|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Archive::Development Archive area for Development's posts that were moved here after an inactivity period of 90 days. |
08-24-2004, 09:53 AM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
scorp also has a ton of custom code i believe so it may not work the same with this, however if it does and he feels like sharing that would be great! if not no biggy i'll eventually get it done or someone else will.
|
08-24-2004, 02:45 PM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
updated the code from my last post it seems while testing none of us ever decided to use canni, manastones etc or heal a pet so it was causing some problems we apparently didnt see, sorry ill try to be a lil more carefull testing next time.
anyway uh updated it so self target only spells no longer crit(manastone-canni-etc) and fixed the heal messages a lil but currently group heals dont display a message- also fixed something else i cant think of atm.
|
|
|
|
08-28-2004, 06:49 AM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
dont use old manaburn or lifeburn code, remove them and use the new stuff posted below, this will allow the buff from manaburn to take hold and not allow manaburn groups however the buff stacking system doesnt seem to work with it currently- also this method allows pvp checks and you dont have to modify the spell value.
also updated the previous code for zone/spells.cpp to include a few more things and updated it since i learned a little more of the way spells are handled. case SE_CurrentHP that is.
added code to place a cap on pvp damage of 70% for a single spell like live used to be, if you want it 40% like live is currently youll have to do it yourself.
added cleric fury and fury of magic mastery, im not too sure of the exact values of these AAs so i just guessed that its a little behind the other versions.
also added quick damage, quick evacuation and spell casting deftness. i think theres another spell haste AA but cant think of it currently. will update whenever i do
also swarm pets are still killing exsisting pets and i have yet to find a way around this but im working on it.
zone/spells.cpp right below case SE_CurrentHP youll find
case: SE_CurrentHPOnce- replace exsisting with this-
Code:
case SE_CurrentHPOnce: // used in buffs usually, see Courage
{
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Current Hitpoints Once: %+i", effect_value);
#endif
//Dook- added manaburn, lifeburn
if(spell_id==2751)
{
int r=MakeRandomInt(0,10);
if(r>=9)
{
effect_value+=((caster->GetMana())*2.4)*-1;
caster->SetMana(0);
entity_list.MessageClose(caster,false,75,0,"%s delivers a critical blast! (%d)",caster->GetName(),((effect_value)*(-1)));
caster->Message(0,"You deliver a critical blast! (%d)", ((effect_value)*(-1)));
}
else
{
effect_value+=((caster->GetMana())*1.8)*-1;
caster->SetMana(0);
}
}
if(spell_id==2755)
{
effect_value+=(caster->GetHP())*-1;
caster->SetHP(caster->CalcMaxHP()/4);
}
ChangeHP(caster, effect_value, spell_id, buffslot);
break;
}
then in zone/attack.cpp do a search for "cut all pvp" and alter the exsisting code to be-
Code:
if (amount < 0)
{
// cut all PVP spell damage to 2/3 -solar
if(other && this->IsClient() && other->IsClient() && this != other)
amount = (int) (amount * 0.67f);
//Dook- Added 70% single blow max damage --pvp dmg cap
if(other && this->IsClient() && other->IsClient())
{
int pcmaxdmg=(((this->CalcMaxHP())*0.7)*(-1));
if(amount<pcmaxdmg)
amount=pcmaxdmg;
}
this->Damage(other, abs(amount), spell_id, 231, false, buffslot, iBuffTic);
return true;
}
then in zone/spells.capp again do a search for "we know our" and alter exsisting code to look like this-
Code:
// we know our mana cost now
casting_spell_mana = mana_cost;
//Dook- Casting Haste
if((IsClient)&&(spell_id != 13)&&(slot != 9)&&(slot != 10)&&(cast_time >= 4000))
{
int dur=spells[spell_id].buffduration;
int dmg;
for (int i = 0; i < EFFECT_COUNT; i++)
{
if (spells[spell_id].effectid[i] == SE_CurrentHP)
{
dmg = CalcSpellEffectValue(spell_id, i, GetCasterLevel());
break;
}
}
Client *c=this->CastToClient();
if(IsEffectInSpell(spell_id, SE_Succor)) //Dook- Quick Evac
{
uint8 qe=c->GetAA(42);
if(qe==1){cast_time=(cast_time*0.90);}
if(qe==2){cast_time=(cast_time*0.75);}
if(qe==3){cast_time=(cast_time*0.50);}
}
if((IsEffectInSpell(spell_id,SE_CurrentHPOnce))||
(IsEffectInSpell(spell_id,SE_CurrentHP))&&(dmg<=0))
{
uint8 qd=c->GetAA(44);
if(qd==1){cast_time=(cast_time*0.98);}
if(qd==2){cast_time=(cast_time*0.95);}
if(qd==3){cast_time=(cast_time*0.90);}
}
if(IsBeneficialSpell(spell_id)&&(dur > 0))
{
uint8 deft=c->GetAA(27);
if(deft==1){cast_time=(cast_time*0.95);}
if(deft==2){cast_time=(cast_time*0.85);}
if(deft==3){cast_time=(cast_time*0.75);}
}
else if(cast_time <= 0)
{
cast_time = 0;
}
}
orgcasttime = cast_time;
// cast time is 0, just finish it right now and be done with it
if(cast_time == 0)
thats all for now.
|
|
|
|
|
|
|
09-02-2004, 03:32 AM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
updated my little checklist of whats broken in my first post, you dont need to do anything with that i simply did it in hopes that someone will pick one of the none working one and start hacking at it with me.
also updated the flurry code from an earlier post, the part in client_process.cpp due to the message being displayed at incorrect times such as when the target was out of range and the skill triggered.
updated SE_CurrentHP in spells.cpp from an earlier post due to something allowing a warrior to get an exceptional heal....only happened onces and i dont really know why but i cleaned it up a little and it hasnt happened since.
updated the lifetap code in attack.cpp from an earlier post due to once again something without the skill got the benefit and a necro pet this time had an exceptional heal... anyone see something obviously wrong im missing?
so! ive spent a ton of time with swarm pets and and have yet to get them perfect, so im posting the progress ive made with them currently in hopes that someone will help finish up, the current minor issues are commented in the code for things like incorrect textures/models or details i dont know of them, the only magor issue at the moment is that after the swarm pets despawn if you had a pet already you no longer see the pet in the group window or in the pet information window, however all command line instructions work perfectly still, this one is driving me insane as ive tried just about everything i believe to be possible. also since this isnt exactly finished im not removing my comment or custom pets i threw in for fun.
wake the dead and doppelganger, these both require getting textures from pop+ which ive been unable to do and havent spent much time looking into yet. so doppelganger only trys to reproduce the primary item slot from the caster and i just gave it a kedge robe for the time being.
wake the dead, again with the textures thing, it works out nicely for NPC corpses but its far from perfect with clients.
fading memories and escape, the invisibility effect on these isnt working correctly since i dont yet understand how to make a client use their hide skill by code, and when i just flagged the player invisable the effect doesnt fade thus every mob in the zone cons indifferent after the skill had been used, as a temporary solution i added the spell improved invis to the skills and plan on coming back to this later, also when i know for sure if fading memories uses 900 mana or only checks that the player has 900 mana.
rampage...well it works perfectly, but i added an area message to it just as i did with flurry, just cause well i think its more fun that way~
ae taunt... see rampage
the god swarm pets i havent been able to get much information on, i know the shaman swarm pets from god proc a 640 poison based DD however i havent been able to figure out what spell this is.
swarm of decay, again with the freakin texture thing, their bows are not the correct model, i also had to guess as to their attack animation speed since it seems no one has seen it enough to remember.
anyway i think thats the magority of it and instead of posting the code per skill im just lumping it all together here, also keep in mind this is a work in progress so dont expect perfection with this just yet.
zone\MobAI.cpp search for "Mob::AI_Process" then scroll down a few lines till you see the bit saying "if (CombatRange(target))" then ABOVE THAT LINE add.
Code:
if((GetBodyType()==63)&&(GetClass()==4)
&&(attack_timer->Check())&&(IsAttackAllowed(target)))
{ //Dook- Swarm Pets -Swarm of Decay
if(Dist(*target)<=100)
{
FaceTarget(target);
DoAnim(20, 9);
int dmg=MakeRandomInt(50,200);
target->Damage(this, dmg, 0xffff, 0x07, true);
}
return;
}
if((GetBodyType()==63)&&(GetRace()==89)&&(IsAttackAllowed(target))
&&(attack_timer->Check())&&(Dist(*target)<=100))
{
//Dook- Servant of Ro castin Bolt of Lava
CastSpell(3005,target->GetID(),9,3000,0,0,0);
return;
}
if((GetBodyType()==63)&&(GetRace()==127)&&(IsAttackAllowed(target))
&&(attack_timer->Check())&&(CombatRange(target))&&(GetClass()==90)
&&(MakeRandomInt(0,10)>=9))
{
CastSpell(1638,target->GetID(),9,0,0,0,0);
}
if((GetBodyType()==63)&&(GetRace()==120)&&(IsAttackAllowed(target))
&&(attack_timer->Check())&&(CombatRange(target))&&(GetClass()==91)
&&(MakeRandomInt(0,10)>=9))
{
//Dook- ToDo Add GoD shaman swarm puppy proc here
}
now on to zone\entity.cpp do a search for "EntityList::GetFreeID" then ABOVE THAT LINE add the following.
Code:
Mob* EntityList::GetMobInZoneByRange(Mob *client, int type, int range) //Dook- AA skills
{
if(type==1) //Dook- find a corpse within range
{
LinkedListIterator<Corpse*> iterator(corpse_list);
iterator.Reset();
Mob* corp;
while(iterator.MoreElements())
{
corp = iterator.GetData();
if(corp->Dist(*client)<=range)
{
return iterator.GetData();
}
iterator.Advance();
}
return 0;
}
if(type==2) //Dook- todo add mob by range here
{
return 0;
}
}
void EntityList::WipeHateAll(Mob *client) //Dook- FM, Escape and such
{
LinkedListIterator<Mob*> iterator(mob_list);
Mob *agroed;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
agroed = iterator.GetData();
if(agroed->IsNPC())
{
agroed->RemoveFromHateList(client);
}
}
}
void EntityList::AETaunt(Mob *client) //Dook- AE Taunt of course..
{ //Dook- no horse no players
LinkedListIterator<Mob*> iterator(mob_list);
Mob *taunte;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
taunte = iterator.GetData();
if((taunte->Dist(*client) <= 30)&&(client->IsAttackAllowed(taunte))&&(taunte != client)
&&(taunte->IsNPC())&&(taunte->GetRace() != 216))
{
Mob* hated=taunte->GetHateTop();
int hate=0;
if(hated)
{
hate=taunte->GetHateAmount(hated);
taunte->SetHate(client,(hate+100));
}
else
{
taunte->AddToHateList(client,100);
}
}
}
}
void EntityList::AEAttack(Mob *attacker, float dist) //Dook- Rampage and stuff
{ //Dook- Will need tweaking, currently no pets or players or horses
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curmob = iterator.GetData();
if((curmob->Dist(*attacker) <= dist)&&(attacker->IsAttackAllowed(curmob))&&(curmob != attacker)
&&(curmob->IsNPC())&&(curmob->GetRace() != 216))
attacker->Attack(curmob,13);
}
}
then on to zone\entity.h do a search for "GetMobByNpcTypeID" then above or below it, doesnt really matter add the following.
Code:
Mob* GetMobInZoneByRange(Mob* client, int type, int range);//Dook- For AA skills etc
void WipeHateAll(Mob* client); //Dook- Escape and Fading Memories etc
void AETaunt(Mob* client); //Dook- AE Taunt of course
void AEAttack(Mob *attacker, float dist); //Dook- Rampage and such
then on to zone\mob.cpp and do a search for
"attack_timer_dw = new Timer(2000);" then below this line add the following.
Code:
swarm_timer = new Timer(0); //Dook- swarm pets
swarm_timer->Disable();
then in mob.cpp still search for "safe_delete(spellend_timer);" and on the line below it add.
Code:
safe_delete(swarm_timer); //Dook- swarm pets
then still in moc.cpp do a search for "Mob* Mob::GetOwnerOrSelf" and replace exsisting with this.
Code:
Mob* Mob::GetOwnerOrSelf() {
if (!GetOwnerID())
return this;
Mob* owner = entity_list.GetMob(this->GetOwnerID());
if (!owner) {
SetOwnerID(0);
}
else if (owner->GetPetID() == this->GetID()) {
return owner;
}
else if (owner->GetFamiliarID() == this->GetID()) {
return owner;
}
else if (this->GetBodyType() == 63) { //Dook- swarm pets
return owner;
}
else {
SetOwnerID(0);
}
return this;
}
still in mob.cpp right below the code we just did you should see "Mob* Mob::GetOwner" replace exsisting with this.
Code:
Mob* Mob::GetOwner() {
Mob* owner = entity_list.GetMob(this->GetOwnerID());
if (owner && owner->GetPetID() == this->GetID()) {
return owner;
}
if (owner && owner->GetFamiliarID() == this->GetID())
{
return owner;
}
if(this->GetBodyType() == 63) //Dook- Swarm Pets
{
return owner;
}
this->SetOwnerID(0);
return 0;
}
now move over to zone\mob.h and search for "spellend_timer"
and right below this add.
Code:
Timer* swarm_timer; //Dook- swarm pets
now move to zone\npc.cpp and search for "if (p_depop)" and replace exsisting with.
Code:
if (p_depop)
{
Mob* owner = entity_list.GetMob(this->ownerid);
if((owner != 0)&&(this->GetBodyType() != 63)) //Dook- Swarm Pets
{
owner->SetPetID(0);
this->ownerid = 0;
this->petid = 0;
}
if(this->GetBodyType() ==63) //Dook- Swarm Pets
{
this->ownerid = 0;
this->petid = 0;
}
return false;
}
then move to zone\spdat.h and search for "SE_StackingCommand_Block" and alter that area to look like this.
Code:
#define SE_StackingCommand_Block 148
#define SE_StackingCommand_Overwrite 149
#define SE_DeathSave 150
#define SE_TemporaryPets 152 //Dook- Swarm Pets
#define SE_BalanceHP 153 // Divine Arbitration
#define SE_DispelDetrimental 154
#define SE_IllusionCopy 156 // Deception
#define SE_SpellDamageShield 157 // Petrad's Protection
#define SE_Reflect 158
#define SE_AllStats 159 // Aura of Destruction
#define SE_FadingMemories 194 //Dook- ....
#define SE_Blank 254
#define SE_WakeTheDead 299 //Dook- ....
#define SE_Doppelganger 300 //Dook- ...
then on to zone\spells.cpp and search for "Mob::SpellProcess" and add the bit at the bottom so that it looks like this.
Code:
void Mob::SpellProcess()
{
// check the rapid recast prevention timer
if(delaytimer == true && spellend_timer->Check())
{
spellend_timer->Disable();
delaytimer = false;
return;
}
// a timed spell is finished casting
if (casting_spell_id != 0 && spellend_timer->Check())
{
spellend_timer->Disable();
delaytimer = false;
CastedSpellFinished(casting_spell_id, casting_spell_targetid, casting_spell_slot, casting_spell_mana, casting_spell_inventory_slot);
}
//Dook- swarm pets
if((swarm_timer->Check()) && (GetBodyType() == 63))
{
Depop();
swarm_timer->Disable();
}
}
then still in spells.cpp search for "The basic types of spells" and move 3 or so lines up and alter it so it looks like this.
Code:
if(IsEffectInSpell(spell_id, SE_TemporaryPets)) //Dook- swarm pet
{
target_id = this->GetID();
}
/*
solar: The basic types of spells:
making a second post now as the next bit is huge and i think im nearing the end of this post.
|
|
|
|
|
|
|
09-02-2004, 05:58 AM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
lovely time for the forums to crash.
so anyway still in spells.cpp now do a search for
"case SE_StackingCommand_Block:" and on the line below it and all this.
Code:
case SE_TemporaryPets: //Dook- swarms and wards
{
Mob* c=CastToClient();
Mob* targ=c->GetTarget();
if(!targ)
{
targ=c;
}
int tim=spell.unknown[12];
int time=tim*1000;
NPCType* npc_type = new NPCType;
memset(npc_type, 0, sizeof(NPCType));
strcpy(npc_type->name, CastToClient()->GetName());
strcat(npc_type->name, "'s_pet");
npc_type->level = 59;
npc_type->race = 127;
npc_type->class_ = 1;
npc_type->runspeed = 1.25f;
npc_type->min_dmg = 1;
npc_type->max_dmg = 50;
npc_type->walkspeed = 0.7f;
npc_type->bodytype = 63; //Dook- claimed 63 for swarm pets
npc_type->max_hp = 100;
npc_type->cur_hp = npc_type->max_hp;
npc_type->gender = 2;
switch(spell_id) {
case 2272:
{//listed as wrath of xuzl but i dont
}//think this is in game
break;
case 3265: //3265-67 servant of ro
{
npc_type->level = 61;
npc_type->race = 89;
npc_type->texture = 2;
npc_type->max_dmg = 150;
npc_type->max_hp = 100;
npc_type->walkspeed = 0;
npc_type->runspeed = 0;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
}
break;
case 3266:
{
npc_type->level = 61;
npc_type->race = 89;
npc_type->texture = 2;
npc_type->max_dmg = 150;
npc_type->max_hp = 100;
npc_type->walkspeed = 0;
npc_type->runspeed = 0;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
}
break;
case 3267:
{
npc_type->level = 61;
npc_type->race = 89;
npc_type->texture = 2;
npc_type->max_dmg = 150;
npc_type->max_hp = 100;
npc_type->walkspeed = 0;
npc_type->runspeed = 0;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
}
break;
case 3283: //3283-85 spirit call
{
npc_type->race = 120;
npc_type->texture = 4;
npc_type->max_hp = 2050;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
}
break;
case 3284:
{
npc_type->race = 120;
npc_type->texture = 4;
npc_type->max_hp = 2050;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npcd = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
npcd->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
entity_list.AddNPC(npcd);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
npcd->AddToHateList(targ,1000,1000);
npcd->swarm_timer->Start(time);
}
break;
case 3285:
{
npc_type->race = 120;
npc_type->texture = 4;
npc_type->max_hp = 2050;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npcd = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npce = new NPC(npc_type, 0,
c->GetX()+10, c->GetY()+10,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
npcd->SetOwnerID(c->GetID());
npce->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
entity_list.AddNPC(npcd);
entity_list.AddNPC(npce);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
npcd->AddToHateList(targ,1000,1000);
npcd->swarm_timer->Start(time);
npce->AddToHateList(targ,1000,1000);
npce->swarm_timer->Start(time);
}
break;
case 3286: //3286-88 host of the elements
{
npc_type->race = 75;
npc_type->texture = 0;
npc_type->size = 3;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npcd = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npce = new NPC(npc_type, 0,
c->GetX()+10, c->GetY()+10,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
npcd->SetOwnerID(c->GetID());
npce->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
entity_list.AddNPC(npcd);
entity_list.AddNPC(npce);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
npcd->AddToHateList(targ,1000,1000);
npcd->swarm_timer->Start(time);
npce->AddToHateList(targ,1000,1000);
npce->swarm_timer->Start(time);
}
break;
case 3287:
{
npc_type->race = 75;
npc_type->texture = 0;
npc_type->size = 3;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npcd = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npce = new NPC(npc_type, 0,
c->GetX()+10, c->GetY()+10,
c->GetZ(), c->GetHeading());
NPC* npcf = new NPC(npc_type, 0,
c->GetX()-10, c->GetY()+10,
c->GetZ(), c->GetHeading());
NPC* npcg = new NPC(npc_type, 0,
c->GetX()+10, c->GetY()-10,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
npcd->SetOwnerID(c->GetID());
npce->SetOwnerID(c->GetID());
npcf->SetOwnerID(c->GetID());
npcg->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
entity_list.AddNPC(npcd);
entity_list.AddNPC(npce);
entity_list.AddNPC(npcf);
entity_list.AddNPC(npcg);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
npcd->AddToHateList(targ,1000,1000);
npcd->swarm_timer->Start(time);
npce->AddToHateList(targ,1000,1000);
npce->swarm_timer->Start(time);
npcf->AddToHateList(targ,1000,1000);
npcf->swarm_timer->Start(time);
npcg->AddToHateList(targ,1000,1000);
npcg->swarm_timer->Start(time);
}
break;
case 3288:
{
npc_type->race = 75;
npc_type->texture = 0;
npc_type->size = 3;
if(CastToClient()->GetGM())
{
npc_type->race = 95;
npc_type->size = 3;
npc_type->gender = 2;
npc_type->texture = 0;
npc_type->max_dmg = 200;
}
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npcd = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npce = new NPC(npc_type, 0,
c->GetX()+10, c->GetY()+10,
c->GetZ(), c->GetHeading());
NPC* npcf = new NPC(npc_type, 0,
c->GetX()-10, c->GetY()+10,
c->GetZ(), c->GetHeading());
NPC* npcg = new NPC(npc_type, 0,
c->GetX()+10, c->GetY()-10,
c->GetZ(), c->GetHeading());
NPC* npch = new NPC(npc_type, 0,
c->GetX()-10, c->GetY()-10,
c->GetZ(), c->GetHeading());
NPC* npci = new NPC(npc_type, 0,
c->GetX()+8, c->GetY()+8,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
npcd->SetOwnerID(c->GetID());
npce->SetOwnerID(c->GetID());
npcf->SetOwnerID(c->GetID());
npcg->SetOwnerID(c->GetID());
npch->SetOwnerID(c->GetID());
npci->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
entity_list.AddNPC(npcd);
entity_list.AddNPC(npce);
entity_list.AddNPC(npcf);
entity_list.AddNPC(npcg);
entity_list.AddNPC(npch);
entity_list.AddNPC(npci);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
npcd->AddToHateList(targ,1000,1000);
npcd->swarm_timer->Start(time);
npce->AddToHateList(targ,1000,1000);
npce->swarm_timer->Start(time);
npcf->AddToHateList(targ,1000,1000);
npcf->swarm_timer->Start(time);
npcg->AddToHateList(targ,1000,1000);
npcg->swarm_timer->Start(time);
npch->AddToHateList(targ,1000,1000);
npch->swarm_timer->Start(time);
npci->AddToHateList(targ,1000,1000);
npci->swarm_timer->Start(time);
}
break;
case 3292: //3292-94 call of xuzl
{
npc_type->equipment[7] = 62;
npc_type->gender = 0;
npc_type->texture = 4;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
}
break;
case 3293:
{
npc_type->equipment[7] = 62;
npc_type->gender = 0;
npc_type->texture = 4;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
}
break;
case 3294:
{
npc_type->equipment[7] = 62;
npc_type->gender = 0;
npc_type->texture = 4;
if(CastToClient()->GetGM())
{
npc_type->race = 66;
npc_type->gender = 2;
npc_type->texture = 1;
npc_type->max_dmg = 200;
npc_type->size = 5;
}
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
NPC* npcd = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
npcd->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
entity_list.AddNPC(npcd);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
npcd->AddToHateList(targ,1000,1000);
npcd->swarm_timer->Start(time);
}
break;
case 3495:
{//another that i dont think is in game
}
break;
case 3633: //call of the mistwalker
{//some say invis man with epic, most say wolf /shrug
npc_type->race = 120;
npc_type->texture = 4;
npc_type->max_dmg = 94;
npc_type->gender = 2;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3634: //call of the dark knight
{
npc_type->equipment[7] = 145;
npc_type->max_dmg = 94;
npc_type->gender = 0;
//custom for Mog
if(CastToClient()->GetGM()) //for Mog
{
strcpy(npc_type->name, CastToClient()->GetName());
strcat(npc_type->name, "'s_Minion");
npc_type->race = 367;
npc_type->gender = 2;
npc_type->equipment[7] = 145;
npc_type->equipment[8] = 145;
npc_type->texture = 4;
npc_type->max_dmg = 1500;
npc_type->min_dmg = 500;
}
//custom for Mog
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3635: //call of faith
{ //dunno
npc_type->equipment[7] = 62;
npc_type->gender = 0;
npc_type->max_dmg = 94;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3636: //call of battle
{ //invis war epic
npc_type->equipment[7] = 141;
npc_type->equipment[8] = 142;
npc_type->max_dmg = 94;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3637: //call of the beast
{ //wtf are the bst epic textures =/
npc_type->equipment[7] = 431;
npc_type->equipment[8] = 431;
npc_type->max_dmg = 94;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3638: //call of wu
{ //cant be right, can barely see it
npc_type->equipment[7] = 159;
npc_type->equipment[8] = 159;
npc_type->max_dmg = 94;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3639: //call of rizlona
{
npc_type->equipment[7] = 148;
npc_type->gender = 0;
npc_type->max_dmg = 94;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3640: //call of the assassin
{ //unsure on this one also
npc_type->equipment[7] = 140;
npc_type->gender = 0;
npc_type->max_dmg = 94;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3649: //call of time
{ //again no textures
//needs correct weapon
//someone said sol ro spear?
npc_type->min_dmg = 100;
npc_type->max_dmg = 415;
npc_type->equipment[7] = 431;
npc_type->equipment[8] = 431;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3807: //trickster's calling
{//not a clue what this is
npc_type->max_dmg = 90;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3869: //ancient call
{ //no clue
//needs correct weapon
npc_type->min_dmg = 100;
npc_type->max_dmg = 415;
npc_type->equipment[7] = 431;
npc_type->equipment[8] = 431;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 3870: //call of the tempest
{ //need to make this despawn when disengaged
//and limit one per fight
//without a timer
npc_type->min_dmg = 100;
npc_type->max_dmg = 330;
npc_type->race = 75;
npc_type->texture = 3;
npc_type->gender = 2;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 4460: //anguish of torment
{//again clueless
npc_type->max_dmg = 90;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 4490: //stone animation
{//......
npc_type->max_dmg = 90;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 4564: //4564-66 swarm of fear/swarm of decay
{//cant find the stonewood compound bow texture
npc_type->equipment[7] = 4;
npc_type->gender = 2;
npc_type->race = 367;
npc_type->texture = 1;
npc_type->walkspeed = 0;
npc_type->runspeed = 0;
npc_type->class_ = 4;
npc_type->max_hp = 1025;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
}
break;
case 4565:
{
npc_type->equipment[7] = 4;
npc_type->gender = 2;
npc_type->race = 367;
npc_type->texture = 1;
npc_type->walkspeed = 0;
npc_type->runspeed = 0;
npc_type->class_ = 4;
npc_type->max_hp = 1025;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
}
break;
case 4566:
{
npc_type->equipment[7] = 4;
npc_type->gender = 2;
npc_type->race = 367;
npc_type->texture = 1;
npc_type->walkspeed = 0;
npc_type->runspeed = 0;
npc_type->class_ = 4;
npc_type->max_hp = 1025;
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
}
break;
case 4568: //call of discord
{//no idea what this is
npc_type->max_dmg = 90;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 4569: //call of chaos
{//la la la
npc_type->max_dmg = 90;
npc_type->gender = 0;
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
npc->swarm_timer->Start(time);
}
break;
case 4790: //4790-4794=Exquisite Benediction
break;
case 4791://heard they cast aura of restoration
break;
case 4792:
break;
case 4793:
break;
case 4794:
break;
case 4796: //4796-4800=Nature's Boon
break;
case 4797:
break;
case 4798:
break;
case 4799:
break;
case 4800:
break;
case 4826: //Spirit Call 4
{//should have a 640 poison DD proc
npc_type->race = 120;
npc_type->gender = 2;
npc_type->texture = 1;
npc_type->max_hp = 2050;
npc_type->min_dmg = 80;
npc_type->max_dmg = 140;
npc_type->class_ = 91;
sprintf(npc_type->npc_attacks, "E");
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
}
break;
case 4827: //Sprit Call 5
{//should have a 640 poison DD proc
npc_type->race = 120;
npc_type->gender = 2;
npc_type->texture = 1;
npc_type->max_hp = 2050;
npc_type->min_dmg = 80;
npc_type->max_dmg = 140;
npc_type->class_ = 91;
sprintf(npc_type->npc_attacks, "E");
npc_type->cur_hp = npc_type->max_hp;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
}
break;
case 4828://Call of the Ancient 4828-4832
break;
case 4829:
break;
case 4830:
break;
case 4831:
break;
case 4832:
break;
case 4836://4836-4840 = Flaming ward of Ro
break;
case 4837:
break;
case 4838:
break;
case 4839:
break;
case 4840:
break;
case 5110: //5110-5111 wrth of xuzl
{ //Useing class 90 for their proc
npc_type->equipment[7] = 62;
npc_type->gender = 0;
npc_type->texture = 4;
npc_type->min_dmg = 80;
npc_type->max_dmg = 140;
npc_type->class_ = 90;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
}
break;
case 5111:
{
npc_type->equipment[7] = 62;
npc_type->gender = 0;
npc_type->texture = 4;
npc_type->min_dmg = 80;
npc_type->max_dmg = 140;
npc_type->class_ = 90;
NPC* npca = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcb = new NPC(npc_type, 0,
c->GetX()-5, c->GetY()+5,
c->GetZ(), c->GetHeading());
NPC* npcc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()-5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npca->SetOwnerID(c->GetID());
npcb->SetOwnerID(c->GetID());
npcc->SetOwnerID(c->GetID());
entity_list.AddNPC(npca);
entity_list.AddNPC(npcb);
entity_list.AddNPC(npcc);
npca->AddToHateList(targ,1000,1000);
npca->swarm_timer->Start(time);
npcb->AddToHateList(targ,1000,1000);
npcb->swarm_timer->Start(time);
npcc->AddToHateList(targ,1000,1000);
npcc->swarm_timer->Start(time);
}
break;
case 5156://Call of Nexona..not a clue
break;
default:
{
c->Message(0,"Unknown pet!");
cout<<"Unknown Temporary Pet in Spell "<<spell_id<<endl;
safe_delete(npc_type);
}
}
targ->AddToHateList(c, 1, 0);
}
break;
case SE_Doppelganger:
{
NPCType* npc_type = new NPCType;
memset(npc_type, 0, sizeof(NPCType));
strcpy(npc_type->name, caster->GetName());
strcat(npc_type->name, "'s_image");
npc_type->level = (caster->GetLevel());
npc_type->race = (caster->GetRace());
npc_type->class_ = (caster->GetClass());
npc_type->luclinface = caster->CastToClient()->GetFace();
npc_type->walkspeed = 0.7f;
npc_type->size = (caster->GetSize());
npc_type->runspeed = 1.25f;
npc_type->bodytype = 63;
npc_type->texture = 14;
npc_type->gender = (caster->GetGender());
npc_type->AC = (caster->GetAC());
npc_type->equipment[7] = caster->GetEquipmentMaterial(7);//primary
if(spell_id==4552)
{
npc_type->max_hp = (caster->CalcMaxHP())/2;
npc_type->min_dmg = 1;
npc_type->max_dmg = 1;
}
if(spell_id==4553)
{
npc_type->min_dmg = 1;
npc_type->max_dmg = 150;
npc_type->max_hp = (caster->CalcMaxHP());
}
if(spell_id==4554)
{
npc_type->min_dmg = 1;
npc_type->max_dmg = 150;
npc_type->max_hp = ((caster->CalcMaxHP())*1.3);
npc_type->npc_spells_id = 5;
}
npc_type->cur_hp = npc_type->max_hp;
NPC* npc = new NPC(npc_type, 0,
caster->GetX(), caster->GetY(),
caster->GetZ(), caster->GetHeading());
npc->swarm_timer->Start(600000);
safe_delete(npc_type);
entity_list.AddNPC(npc);
Mob* targ=caster->GetTarget();
if((targ)&&(targ != caster))
{
int hate=hate_list.GetEntHate(caster);
targ->AddToHateList(npc,hate+100);
npc->AddToHateList(targ,1);
}
}
break;
case SE_FadingMemories: //Dook- escape etc
{
entity_list.WipeHateAll(this);
SpellOnTarget(1406,this);
}
break;
case SE_WakeTheDead: //Dook- Wake the Dead
{
Mob* corpse=entity_list.GetMobInZoneByRange(caster, 1, 20);
Mob* c=caster;
Mob* targ=caster->GetTarget();
if(!targ)
{
targ=caster;
}
if(!corpse)
{
caster->Message(0,"Could not find the dead!");
break;
}
else
{
NPCType* npc_type = new NPCType;
memset(npc_type, 0, sizeof(NPCType));
strcpy(npc_type->name, c->GetName());
strcat(npc_type->name, "'s_pet");
npc_type->level = corpse->GetLevel();
npc_type->race = corpse->GetRace();
npc_type->class_ = corpse->GetClass();
npc_type->runspeed = 1.25f;
npc_type->min_dmg = 50;
npc_type->max_dmg = 300;
npc_type->walkspeed = 0.7f;
npc_type->bodytype = 63;//Dook- useing swarm timer for this
npc_type->max_hp = 5000;
npc_type->cur_hp = npc_type->max_hp;
npc_type->gender = corpse->GetGender();
npc_type->texture = corpse->GetTexture();
npc_type->helmtexture = corpse->GetHelmTexture();
npc_type->equipment[7] = corpse->GetEquipmentMaterial(7);
npc_type->equipment[8] = corpse->GetEquipmentMaterial(8);
NPC* npc = new NPC(npc_type, 0,
c->GetX()+5, c->GetY()+5,
c->GetZ(), c->GetHeading());
safe_delete(npc_type);
npc->SetOwnerID(c->GetID());
entity_list.AddNPC(npc);
npc->AddToHateList(targ,1000,1000);
if(spell_id==3268)
npc->swarm_timer->Start(60000);
if(spell_id==3269)
npc->swarm_timer->Start(75000);
if(spell_id==3270)
npc->swarm_timer->Start(90000);
}
}
break;
well i think thats all of it but not too sure, if i find ive left anything out ill update. anyway i could really use some help finishing this up so if you see anything wrong with it please post, also i do understand theres other ways that might have been nicer or better than this but this is the current state im at, help is always appreciated and if you simply want to fill me in on some of the details im missing can do so here or on my server which ive left up basicly 24/7.
|
|
|
|
|
|
|
09-02-2004, 10:56 AM
|
Hill Giant
|
|
Join Date: May 2004
Posts: 238
|
|
I havent checked your post in awhile, and so breifly skimming over it i didnt notice if you had figured out how to get aa_timers to work.
I've been working on some code to get that working right but in all my testing I cannot find any type of logic behind the aa_timer table in my db. It randomly changes when you click an aa and has nothing to do with timeing. It also does not change when a button or something is pressed. I'm still investigateing if i can find out whats going on i can let you know how i fixed the problem nearly all the code is fixed cept about one line of logic i think.
Hopefully i will find out soon i'm hopeing lay hands or harm touch will give me some clue. Even though they're not aa's theres a way that they go about triggering off. (Not really sure if that works either hehe) anyways back to codeing. Also after i get this tackled i'll start helping you with the aa's since people on my server want em working.
|
|
|
|
|
|
|
09-02-2004, 11:30 AM
|
Hill Giant
|
|
Join Date: May 2004
Posts: 238
|
|
Ok after some further investigation heres what i've found. Its still not working just like i want but i'm getting closer.
The way that aa_timers is working atm is:
When the effect first goes off it sets begin < end
If you click it again it sets begin = end
it rotates in this cycle and does not go down in time.
The way i have this working now it will go off every other time
So i was looking in database::UpdateTimersClientConnected(int32 charid)
and heres what i found
Code:
if (!RunQuery(query, MakeAnyLenString(&query, "update aa_timers set end=(UNIX_TIMESTAMP(now())+(end-begin)),begin=UNIX_TIMESTAMP(now()) where charid=%i",charid), errbuf))
correct me if i'm wrong but the way they have it increases both end and begin and not only begin so no matter what they will have the same difference. Cant think of a way to fix it because i've got to go do some homework. Almost there though if u can think of a fix before i get back post it.
|
|
|
|
09-02-2004, 11:52 AM
|
Hill Giant
|
|
Join Date: Jul 2004
Location: In my basement
Posts: 131
|
|
I had AA timers workin perfect, but I lost all the code :(
|
09-03-2004, 03:35 AM
|
Developer
|
|
Join Date: Jul 2004
Posts: 773
|
|
just to let you guys know.
I have been working with cofruben on a persistent timer which he needs for adventure stuff. The result is something which can easily be used for AAs.
Right now it automatically takes care of all the database stuff, you just use it like the current timer class, basically, and it is preserved across zones. I dont know/care how the aa_timers stuff worked, because it was kinda klumsy if you ask me.
When cofruben gets done testing it, I will hook you up with a patch that should apply to 7-31 CVS... these timers are currently in 5.8, so they will be around for sure.
|
09-03-2004, 08:07 AM
|
Hill Giant
|
|
Join Date: May 2004
Posts: 238
|
|
Yeah it was set up really wird but i've figured it all out now once i do a little more work today it will be working. Got it down now where the only problem i'm having is the values it sets in aa_timers wont increase over time like it should but thats easy enough to fix i should have my source posted here by the end of today i would think.
**EDIT**
Its working now all timers for aa's should be working i will release the source when i get home from work in like 3 hours. Dont have time to do it atm.
|
|
|
|
09-03-2004, 12:18 PM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
oh sweet im excited to see what you guys came up with, i kinda gave up on the current timers also since the more i looked into it the more it seems to be a simple rapid recast prevention thing than an actual timer, one of you two please say yalls system allows reenabling the button server side. currently the client does timers on its own to reenable the buttons which id like to have adjustable by the server op if possible. also monalin from what ive seen the timers in the DB arent meant to change constantly their simply there to check if current time hasnt passed the time when the timer was supposed to expire however the current system also only checks during zone changes. and fathernitwit would you mind filling me in on how much of this is broken in 5.8? im rather curious and just want a simple answer like "little different" or "omg start over" although i dont see how much of it can be broken other than actually recognizing an AA activation request, anyway thats just something ive been wondering about and one of the reasons i asked about the jr dev thing. anyway thanks again for work with the timers! guess ill spend the night playing with the monk AE attack skill as that one sounds kinda challenging.
also either of you happen to have a link to a decent code optimization tutorial or anything as i think i know enough to start working on good habbits and i still get nervous about tampering with the constantly run processes.
|
|
|
|
|
|
|
09-03-2004, 12:42 PM
|
Hill Giant
|
|
Join Date: May 2004
Posts: 238
|
|
Ok finnaly heres the source code.
client_process.cpp line 5251
before // try to send all packets that weren't send before
add
Code:
database.UpdateTimersClientConnected(CharacterID());
database.h line 124
add
Code:
bool AATimerTest(int32 charid, int32 ability);
database.cpp line 2213
after #ifdef ZONE
add
Code:
bool Database::AATimerTest(int32 charid, int32 ability){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT begin-end from aa_timers WHERE charid=%i AND ability=%i", charid, ability), errbuf, &result)) {
while( ( row = mysql_fetch_row(result) ) ){
LogFile->write(EQEMuLog::Error, "Database::AATimerTest begin-end=%i for ability: %i and charid: %i",atoi(row[0]),ability,charid);
if(atoi(row[0]) >= 0){
LogFile->write(EQEMuLog::Error, "Database::AATimerTest begin <= end");
return false;
}
else{
return true;
LogFile->write(EQEMuLog::Error, "Database::AATimerTest begin >= end");
}
}
mysql_free_result(result);
}
else
LogFile->write(EQEMuLog::Error, "Database::AATimerTest query '%s' %s", query, errbuf);
safe_delete_array(query);
}
and right before that function
where it has
void Database::UpdateTimersClientConnected(int32 charid)
change that function to
Code:
void Database::UpdateTimersClientConnected(int32 charid){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "update aa_timers set begin=UNIX_TIMESTAMP(now()) where charid=%i",charid), errbuf)) {
LogFile->write(EQEMuLog::Error, "UpdateAATimers query '%s' %s", query, errbuf);
}
safe_delete_array(query);
}
client.cpp line 3271
after int targ;
add
Code:
if(database.AATimerTest(CastToClient()->character_id,activate) == 0){
client.cpp line 4955 (about)
after safe_delete(outapp);
add
Code:
}
else
CastToClient()->Message(0,"You cannot cast this spell at this time.");
And i think thats about it i might have forgotten something i dont think i did let me know if it works for you guys too i've tested it on my server and it works so if it doesnt work on yours.
if(code != "works)"{
Message(1,"I probly forgot something.");
}
else if (code == "works"){
Message(1,"enjoy ");
}
and branks
Quote:
also either of you happen to have a link to a decent code optimization tutorial or anything as i think i know enough to start working on good habbits and i still get nervous about tampering with the constantly run processes.
|
I dont know, i'm 17 and i taught myself everything i know. I believe you might be able to edit the aa timers in game by just messing with the db a little i'm not sure how it works i can look into it i hadent really thought of changing it much but i dont think it would be impossible.
**EDIT** dont emptry your aa_timers table it bugs you, also the errors you get in zone.exe mean nothign they're for me to debugg.
**EDIT** UPDATE THIS PLEASE
new AATimerTest function should be
Code:
bool Database::AATimerTest(int32 charid, int32 ability){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT begin-end from aa_timers WHERE charid=%i AND ability=%i", charid, ability), errbuf, &result)) {
while( ( row = mysql_fetch_row(result) ) ){
LogFile->write(EQEMuLog::Error, "Database::AATimerTest begin-end=%i for ability: %i and charid: %i",atoi(row[0]),ability,charid);
if(atoi(row[0]) >= 0){
LogFile->write(EQEMuLog::Error, "Database::AATimerTest begin <= end");
return false;
}
else if(row[0] == "NULL"){
time_t timestamp=time(NULL);
UpdateAATimers(charid,timestamp,timestamp,ability);
return true;
}
else{
LogFile->write(EQEMuLog::Error, "Database::AATimerTest begin >= end");
}
}
mysql_free_result(result);
}
else{
LogFile->write(EQEMuLog::Error, "Database::AATimerTest query '%s' %s", query, errbuf);
}
safe_delete_array(query);
}
it was found to be not adding new timers under certian conditions, with the help of Branks we came up with this it solved his problem he created when he emptied his aa_timer table.
|
|
|
|
|
|
|
09-03-2004, 02:10 PM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
worked out great! but... i was getting one of the errors from it although it was working fine so i decided maybe it didnt like the current numbers that were in the DB so i emptied my aa_timers table and then nothing worked, so it needs a function to handle if there is no table currntly there. working on this now and still trying to track down how to reenable the button when the timer expires.
edit: monalin just noticed the last part, the timers are easily changed they are set in client.cpp above and below the code you added, its the timermod which is in each case, their in seconds. and im self taught also and slowly getting better. also what i meant about the reuse thing was that id like to trackdown whatever it is thats sent to the client to let the client know the skill is avaliable, instead of the button appearing gray while its actually useable, this happens during zoneing currently but not without so its in here somewhere...
|
|
|
|
|
|
|
09-03-2004, 02:15 PM
|
Hill Giant
|
|
Join Date: May 2004
Posts: 238
|
|
Oh, explain please i'm confused that shouldnt be causing problems since i just created a new character and when i did that it added the values to db just as if it had been blank. It shouldnt be causing any problems. Maybe i forgot to add something in there, did u just empty it or did u delete it, and what errors are you getting.
Oh and the errors are just in there because, u can remove them really i had that in there when i was trying to find out what the hell was going on with the aa_timers table. Those Errors really mean nothing just lets me know what was commingo ut of hte function when i would call it.
Quote:
also what i meant about the reuse thing was that id like to trackdown whatever it is thats sent to the client to let the client know the skill is avaliable, instead of the button appearing gray while its actually useable, this happens during zoneing currently but not without so its in here somewhere...
|
They had it updateing the database only when it zoned they put the UpdateTimersClientConnected(charid) in wrong place it was only getting called on login or zone.
|
|
|
|
09-03-2004, 02:20 PM
|
Sarnak
|
|
Join Date: May 2004
Posts: 58
|
|
uh it kept saying begin <= end in the zone window which i assumed it shouldnt have been so i emptied the aa_timers table and rebooted the server.
and since then it wont work im playing with it now though, it may have been some of my other code that caused this as i have a lot thats not posted im playing with.
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 06:21 PM.
|
|
|
|
|
|
|
|
|
|
|
|
|