Help with custom dispel function

Hi, i’m creating a custom dispel function since the dispel functions of the game doesn’t have what i need. I’m currently stuck when you cast the dispel effect as an AoE and you need to dispel the best effect.

Here is what got:

void EnhancedDispel(object oTarget,int nCasterLevel, int nDispelAll, int nSpellID,effect eVis)
{

    float fDelay = GetRandomDelay(0.1, 0.3);
	
    //--------------------------------------------------------------------------
    // Don't dispel magic on petrified targets
    // this change is in to prevent weird things from happening with 'statue'
    // creatures. Also creature can be scripted to be immune to dispel
    // magic as well.
    //--------------------------------------------------------------------------
    if (GetHasEffect(EFFECT_TYPE_PETRIFY, oTarget) == TRUE || GetLocalInt(oTarget, "X1_L_IMMUNE_TO_DISPEL") == 10)
    {
        return;
    }
	
	if(nDispelAll == TRUE) //Single Target - Dispel All Effects
	{
		int nDC, nCheck,nHighestSpellLvL,nSpellLvL;
		effect eEffects = GetFirstEffect(oTarget);
		while(GetIsEffectValid(eEffects))
		{
			if(GetEffectSubType(eEffects)==SUBTYPE_MAGICAL)
			{
				nCheck = d20()+nCasterLevel;
				int nSpellID = GetEffectSpellId(eEffects);
				object oCreator = GetEffectCreator(eEffects);
				int nCasterLevel = GetHighestCasterLevel(oCreator);
				nDC = 11 + nCasterLevel;
				if(nCasterLevel>=nDC || oCreator == OBJECT_SELF)
				{
					string sSpellName = Get2DAString("spells", "Name", nSpellID);
					SpeakString("Dispelled: "+sSpellName);
					RemoveEffect(oTarget,eEffects);
					
					nSpellLvL = GetSpellLevel(nSpellID);
					if(nHighestSpellLvL<nSpellLvL) nHighestSpellLvL = nSpellLvL;
				}
			}
			eEffects = GetNextEffect(oTarget);
		}
	}
	else //AoE - Dispel Best Effect
	{
		int nDC, nCheck;
		effect eEffects = GetFirstEffect(oTarget);
		while(GetIsEffectValid(eEffects))
		{
			if(GetEffectSubType(eEffects)==SUBTYPE_MAGICAL)
			{
			
			}
			eEffects = GetNextEffect(oTarget);
		}
	
	}

    DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
}

here’s the core of it, a thing i thought up to replace EffectDispelMagicBest()

        int iSpellId; // cycle down from 9th level spells to 0th level spells until one is removed ->

        int iSpellLevelTest = 9;
        while (iSpellLevelTest != -1)
        {
            effect e = GetFirstEffect(oTarget);
            while (GetIsEffectValid(e))
            {
                if (GetEffectSubType(e) == SUBTYPE_MAGICAL
                    && (iSpellId = GetEffectSpellId(e)) != -1
                    && StringToInt(Get2DAString("spells", "Innate", iSpellId)) == iSpellLevelTest)
                {
                    RemoveEffect(oTarget, e);
                    SpeakSpell(oTarget, iSpellId, "aoe"); // debug

                    iSpellLevelTest = 0;
                    break;
                }
                e = GetNextEffect(oTarget);
            }
            --iSpellLevelTest;
        }

and here’s the whole shebang (as i was working it)

#include "nw_i0_spells" // GetRandomDelay()
#include "x0_i0_match"  // GetHasEffect()


// trigger funct
void doEnhancedDispel();

// test funct
int GetCreatorLevel(object oCreator);

// debug funct
void SpeakSpell(object oTarget, int iSpellId, string sType)
{
    AssignCommand(oTarget,
                  SpeakString("Dispelled " + sType + ": " +
                  GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", iSpellId)))));
}

//
void EnhancedDispel(object oTarget, object oCaster, int bDispelAll, effect eImpact)
{
    if (GetHasEffect(EFFECT_TYPE_PETRIFY, oTarget)
        || GetLocalInt(oTarget, "X1_L_IMMUNE_TO_DISPEL") == 10)
    {
        return;
    }


    if (bDispelAll) // single Target - dispel all effects
    {
        int iCasterLevel = GetCasterLevel(oCaster);

        effect e = GetFirstEffect(oTarget);
        while (GetIsEffectValid(e))
        {
            if (GetEffectSubType(e) == SUBTYPE_MAGICAL)
            {
                object oCreator = GetEffectCreator(e);
                if (oCreator == oCaster)
                {
                    RemoveEffect(oTarget, e);
                    SpeakSpell(oTarget, GetEffectSpellId(e), "auto"); // debug
                }
                else
                {
                    int iDc = GetCreatorLevel(oCreator) + 11;
                    if (iCasterLevel + d20() >= iDc)
                    {
                        RemoveEffect(oTarget, e);
                        SpeakSpell(oTarget, GetEffectSpellId(e), ""); // debug
                    }
                }
            }
            e = GetNextEffect(oTarget);
        }
    }
    else // AoE - dispel best effect
    {
        int iSpellId; // cycle down from 9th level spells to 0th level spells until one is removed ->

        int iSpellLevelTest = 9;
        while (iSpellLevelTest != -1)
        {
            effect e = GetFirstEffect(oTarget);
            while (GetIsEffectValid(e))
            {
                if (GetEffectSubType(e) == SUBTYPE_MAGICAL
                    && (iSpellId = GetEffectSpellId(e)) != -1
                    && StringToInt(Get2DAString("spells", "Innate", iSpellId)) == iSpellLevelTest)
                {
                    RemoveEffect(oTarget, e);
                    SpeakSpell(oTarget, iSpellId, "aoe"); // debug

                    iSpellLevelTest = 0;
                    break;
                }
                e = GetNextEffect(oTarget);
            }
            --iSpellLevelTest;
        }
    }

    float fDelay = GetRandomDelay(0.1f, 0.3f);
    DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eImpact, oTarget));
}

//
int GetCreatorLevel(object oCreator)
{
    return GetTotalLevels(oCreator, FALSE);
}


//
void doEnhancedDispel()
{
    SpeakString("doEnhancedDispel()"); // debug

    object oCaster = OBJECT_SELF;
    effect eImpact = EffectVisualEffect(VFX_IMP_DISPEL);

    object oTarget = GetSpellTargetObject();
    if (GetIsObjectValid(oTarget) && GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
    {
        EnhancedDispel(oTarget, oCaster, TRUE, eImpact);
    }
    else
    {
        location lSpell = GetSpellTargetLocation();
        oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lSpell);
        while (GetIsObjectValid(oTarget))
        {
            EnhancedDispel(oTarget, oCaster, FALSE, eImpact);
            oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lSpell);
        }
    }
}

Thank you, the way you did the dispel best effect makes everything more clear to me. I’m going to adapt it to what i want to do.

1 Like