PDA

View Full Version : AoE Resurrection


squevis667
06-18-2012, 04:55 PM
I am trying to put together a custom AoE Rez Spell.
I copied the resurrection spell and changed target type to 4:PBAE and left spell category as 27: Resurrection.

I added a Boolean to allow the server to know the spell is an AoE Rez
bool IsAERezSpell(int16 spell_id)
{
switch (spell_id)
{
case 9801:
return true;
}
return false;
}

From spells.cpp the the targeting data for the spell should be
case ST_AECaster:
{
spell_target = NULL;
ae_center = this;
CastAction = AECaster;
break;
}

Looking at AECaster
case AECaster:
case AETarget:
{
#ifdef BOTS
if(IsBot()) {
bool StopLogic = false;
if(!this->CastToBot()->DoFinishedSpellAETarget(spell_id, spell_target, slot, StopLogic))
return false;
if(StopLogic)
break;
}
#endif //BOTS

// we can't cast an AE spell without something to center it on
assert(ae_center != NULL);

if(ae_center->IsBeacon()) {
// special ae duration spell
ae_center->CastToBeacon()->AELocationSpell(this, spell_id, resist_adjust);
} else {
// regular PB AE or targeted AE spell - spell_target is null if PB
if(spell_target) // this must be an AETarget spell
{
// affect the target too
SpellOnTarget(spell_id, spell_target, false, true, resist_adjust);
}
if(ae_center && ae_center == this && IsBeneficialSpell(spell_id))
SpellOnTarget(spell_id, this);

bool affect_caster = !IsNPC(); //NPC AE spells do not affect the NPC caster
entity_list.AESpell(this, ae_center, spell_id, affect_caster, resist_adjust);
}
break;
}
So I go to entity_list.AESpell and add a few lines to have it cast the spell on corpses instead of regular mobs
void EntityList::AESpell(Mob *caster, Mob *center, int16 spell_id, bool affect_caster, sint16 resist_adjust)
{
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;

float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;

bool bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC();
const int MAX_TARGETS_ALLOWED = 4;
int iCounter = 0;

if(!IsAERezSpell(spell_id))
{
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curmob = iterator.GetData();
if(curmob == center) //do not affect center
continue;
if(curmob == caster && !affect_caster) //watch for caster too
continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
if(isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if(bad) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if( ! (caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
continue;
} else {
//only affect mobs we would assist.
if( ! (f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if(bad) {
if(!caster->IsAttackAllowed(curmob, true))
continue;
if(!center->CheckLosFN(curmob))
continue;
}

//if we get here... cast the spell.
if(IsTargetableAESpell(spell_id) && bad)
{
if(iCounter < MAX_TARGETS_ALLOWED)
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
}
else
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}

if(!isnpc) //npcs are not target limited...
iCounter++;
}
}
else
{
for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{

curmob = iterator.GetData();
bool isCorpse = curmob->IsPlayerCorpse();
if(!isCorpse)
continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
caster->SpellOnTarget(spell_id, curmob);
}
}
}
Anyone have any input for why this may not be working or any pointers on how to get it to work?

lerxst2112
06-18-2012, 07:54 PM
Have you tried to debug it at all? Does your new code get called? If so, does it find any corpses to try and cast on?

squevis667
06-18-2012, 08:16 PM
I was trying to discern the best way to debug. I cannot discern the proper format for EntityList::Message but I have not looked too hard (int, int, message). The first int is the channel I think but did not see an example of it so I am unsure. I considered using mlog, but again, some of the arguments elude me, but I have found some examples. Any idea where mlog outputs to? I must apologize, I am mainly a C# guy and I would normally just have it pop a messagebox to tell me it has fired. What would you suggest for this environment?

Caryatis
06-18-2012, 08:25 PM
Just use, caster->Message(0, "put your shit here or use %s for string var and %i for integer variables", thisISaSTRINGvar, thisISanINTvar)

squevis667
06-19-2012, 09:23 AM
Th issue was what list was being iterated over. As a side note, if you want to rez corpses, you have to iterate the corpse_list and not the mob_list. Code below for EntityList::AESpell fixed it.
void EntityList::AESpell(Mob *caster, Mob *center, int16 spell_id, bool affect_caster, sint16 resist_adjust)
{
if(!IsAERezSpell(spell_id))
{
LinkedListIterator<Mob*> iterator(mob_list);
Mob *curmob;

float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;

bool bad = IsDetrimentalSpell(spell_id);
bool isnpc = caster->IsNPC();
const int MAX_TARGETS_ALLOWED = 4;
int iCounter = 0;

for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curmob = iterator.GetData();
if(curmob == center) //do not affect center
continue;
if(curmob == caster && !affect_caster) //watch for caster too
continue;
if(center->DistNoRoot(*curmob) > dist2) //make sure they are in range
continue;
if(isnpc && curmob->IsNPC()) { //check npc->npc casting
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
if(bad) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if( ! (caster->CheckAggro(curmob) || f == FACTION_THREATENLY || f == FACTION_SCOWLS) )
continue;
} else {
//only affect mobs we would assist.
if( ! (f <= FACTION_AMIABLE))
continue;
}
}
//finally, make sure they are within range
if(bad) {
if(!caster->IsAttackAllowed(curmob, true))
continue;
if(!center->CheckLosFN(curmob))
continue;
}

//if we get here... cast the spell.
if(IsTargetableAESpell(spell_id) && bad)
{
if(iCounter < MAX_TARGETS_ALLOWED)
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
}
else
{
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}

if(!isnpc) //npcs are not target limited...
iCounter++;
}
}
else
{
LinkedListIterator<Corpse*> iterator(corpse_list);
Corpse *curcorpse;

float dist = caster->GetAOERange(spell_id);
float dist2 = dist * dist;

for(iterator.Reset(); iterator.MoreElements(); iterator.Advance())
{
curcorpse = iterator.GetData();
if(!curcorpse->IsPlayerCorpse())
continue;
if(center->DistNoRoot(*curcorpse) > dist2) //make sure they are in range
continue;

caster->SpellOnTarget(spell_id, curcorpse);
}
}
}