Page 1 of 1

Banishment and code trouble

Posted: Thu Mar 02, 2006 5:28 pm
by Fredegar
Ok, I am trying to modify a few spells to banish a player/monsters to a demiplane if they are effected by it. Here is my code, modified from the psionic code.

Code: Select all

        //----------------------------------
        case SPELL_WORD_OF_FAITH:
        {
        //Declare major variables
        effect eLink = EffectVisualEffect(VFX_FNF_WORD);
        effect eVis = EffectVisualEffect(VFX_IMP_DEATH);
        float fDelay;
        int nDuration=iLevel/2;
        object oBanArea=GetObjectByTag("Banishment");
        int nDC=17+GetAbilityModifier(ABILITY_WISDOM, oCaster);

        //Apply the FNF VFX impact to the target location
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eLink, GetSpellTargetLocation());
        //Get the first target in the spell area
        oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget);
        while (GetIsObjectValid(oTarget))
        {
            //Make a faction check
            if(GetIsEnemy(oTarget))
            {
                fDelay = GetRandomDelay(0.5, 2.0);
                //Fire cast spell at event for the specified target
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_WORD_OF_FAITH));
                //Make SR check
                if(!MyResistSpell(OBJECT_SELF, oTarget, fDelay))
                {
                    eLink = EffectVisualEffect(VFX_IMP_SONIC);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget);
                    if(!WillSave(oTarget, nDC, SAVING_THROW_TYPE_NONE))
                    {
                        int nBanIndex=GetLocalInt(oBanArea, "BanIndex")+1;
                        if (nBanIndex>=37) nBanIndex=1;
                        location lDest=GetLocation(GetWaypointByTag("Banish_WP_"+IntToString(nBanIndex)));
                        location lHere=GetLocation(oTarget);
                        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lHere);
                        AssignCommand(oTarget, ClearAllActions(TRUE));
                        AssignCommand(oTarget, JumpToLocation(lDest));
                        SetLocalInt(oBanArea, "BanIndex", nBanIndex);
                        //Wait one round before escape attempt
                        DelayCommand(6.0, Escape(oTarget, lHere, nDuration, nDC));
                    }
                }
            }
            //Get the next target in the spell area
            oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget);
        }

        SetModuleOverrideSpellScriptFinished();
        break;
        }

Code: Select all

void Escape(object oBanished, location lReturnSpot, int nDuration, int nDC);

void Escape(object oBanished, location lReturnSpot, int nDuration, int nDC)
{
    if (nDuration <= 0 || WillSave(oBanished, nDC, SAVING_THROW_TYPE_NONE))
    {
        effect eVis2=EffectVisualEffect(VFX_IMP_GOOD_HELP);
        eVis2=EffectLinkEffects(eVis2,EffectVisualEffect(VFX_IMP_DISPEL));

        AssignCommand(oBanished, ClearAllActions());
        DelayCommand(0.3, AssignCommand(oBanished, JumpToLocation(lReturnSpot)));
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis2, lReturnSpot);
        if (!GetIsPC(oBanished))
            DelayCommand(1.0, AssignCommand(oBanished,
                DetermineCombatRound(GetNearestPerceivedEnemy(oBanished))));
    }
    else DelayCommand(6.0, Escape(oBanished, lReturnSpot, nDuration-1, nDC));
}
My trouble is coming from this.. When cast against a single creature (pc or npc) it will banish the creature to the demiplane. If the spell is cast against a group of pc's(hostile or attacking) they will all be banished to the demiplane and each in their seperate 'cage'. If the spell is cast on a group of NPC's(hostile but not attacking) then they will all be banished to the demiplane.

The problem comes here:

If the spell is cast against a group of NPC's(hostile but attacking) then none of them will be banished, not even those that fail the save. If the spell is cast against a group of NPC's with PC's (both hostile and attacking), the PC's will all be banished, but if the NPC count is over 1, then none of the NPC's are banished.

Any ideas?

Posted: Thu Mar 02, 2006 6:11 pm
by slave.of.emotions
only thing that seems weird to me right now is that i can not find anywhere lTarget defined...

like

location lTarget = GetSpellTargetLocation();

or GetSpellTargetLocation() used in the function istead of lTarget itself.

is that perhaps somewhere earlier ?

Posted: Thu Mar 02, 2006 10:58 pm
by Fredegar
lTarget = GetSpellTargetLocation();

That is defined before the case switch that spellhooking utilizes.

Posted: Fri Mar 03, 2006 5:10 am
by slave.of.emotions
Since NPCs that fail save dont get jumped i would try the following if i could; Replace "AssignCommand(oTarget, ActionJumpToLocation(lDest));" with some sort of a visual effect, effect,or some NPC count that applies instead of it on oTarget. Then use it on a group of NPC and see if they all get this effect, if yes then it would be sure that ActionJumpToLocation(lDest) is having troubles with NPCs.
And anther time comment out the delay command out... from your description it must be something after the willsave making troubles.

Posted: Tue Mar 07, 2006 4:10 am
by Sindol
If it's still not working I'd try making a little delay between the two assigncommands. They sometimes fuck up in a chronological sense.

Code: Select all

AssignCommand(oTarget, ClearAllActions(TRUE)); 
DelayCommand(0.2, AssignCommand(oTarget, JumpToLocation(lDest))); 
Note that I'm not sure this will bring the solution, but at first glace I found nothing else that could go awry.

Posted: Tue Mar 07, 2006 1:14 pm
by Bruno Knotslinger
Sindol wrote:If it's still not working I'd try making a little delay between the two assigncommands. They sometimes fuck up in a chronological sense.

Code: Select all

AssignCommand(oTarget, ClearAllActions(TRUE)); 
DelayCommand(0.2, AssignCommand(oTarget, JumpToLocation(lDest))); 
Note that I'm not sure this will bring the solution, but at first glace I found nothing else that could go awry.
Since AssignCommands are executed after the script finishes, I believe they are added to a stack while the calling script is executing and then are pulled off the stack after execution and the commands added to the action queue. So first in, last out. Just a conjecture though. Same thing happens with DelayCommands called in a function that have the same delay.