EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development: Custom Code (https://www.eqemulator.org/forums/forumdisplay.php?f=665)
-   -   AoE Resurrection (https://www.eqemulator.org/forums/showthread.php?t=35431)

squevis667 06-18-2012 04:55 PM

AoE Resurrection
 
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
Code:

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
Code:

case ST_AECaster:
                {
                        spell_target = NULL;
                        ae_center = this;
                        CastAction = AECaster;
                        break;
                }

Looking at AECaster
Code:

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
Code:

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.
Code:

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);
                }
        }
}



All times are GMT -4. The time now is 06:55 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.