918 lines
34 KiB
Plaintext
918 lines
34 KiB
Plaintext
/*:://////////////////////////////////////////////
|
||
//:: Name Dispel Include
|
||
//:: FileName SMP_INC_DISPEL
|
||
//:://////////////////////////////////////////////
|
||
All dispel magic things.
|
||
//:://////////////////////////////////////////////
|
||
//:: Created By: Jasperre
|
||
//::////////////////////////////////////////////*/
|
||
|
||
#include "SMP_INC_AOE"
|
||
#include "SMP_INC_REMOVE"
|
||
|
||
const string SMP_IMMUNNITY_TO_DISPEL = "SMP_IMMUNNITY_TO_DISPEL";
|
||
|
||
// SMP_INC_DISPEL. This will dispel magic (All, IE targeted) on oTarget.
|
||
// * Checks spell effects for special things when ended.
|
||
// * No special reaction checks.
|
||
// * Put in eDispel, all effect.
|
||
// * Removes all friendly-spell effects off oTarget, by oCaster if "good" spells.
|
||
// * Will check items equipped by oTarget, and dispel ALL possible ones.
|
||
void SMP_DispelMagicAll(object oTarget, effect eDispel, effect eVis, object oCaster = OBJECT_SELF);
|
||
|
||
// SMP_INC_DISPEL. This will dispel magic (All, IE targeted) on oTarget.
|
||
// * Checks spell effects for special things when ended.
|
||
// * No special reaction checks.
|
||
// * Put in eDispel, best effect.
|
||
// * Removes all friendly-spell effects off oTarget, by oCaster if "good" spells.
|
||
// * Will check items equipped by oTarget, and dispel ONE possible effect.
|
||
void SMP_DispelMagicBest(object oTarget, effect eDispel, effect eVis, object oCaster = OBJECT_SELF);
|
||
|
||
// SMP_INC_DISPEL. Dispels all magic on oItem.
|
||
// * TRUE if we dispel anything.
|
||
int SMP_DispelMagicAllOnItem(object oItem);
|
||
// SMP_INC_DISPEL. Dispels one spell on oItem.
|
||
// * TRUE if we dispel anything.
|
||
int SMP_DispelMagicBestOnItem(object oItem);
|
||
|
||
// SMP_INC_DISPEL. This will disjoin magical effects on oTarget (Mage's Disjuction).
|
||
// - Checks spell effects for special things when ended.
|
||
// - No special reaction checks.
|
||
// - It will remove all SUBTYPE_MAGICAL effects which have
|
||
// GetEffectSpellId() != SPELL_INVALID
|
||
// * Note it can remove some effects Dispel Magic cannot. And does so here.
|
||
void SMP_DisjoinMagic(object oTarget, int nVFX = VFX_IMP_DISPEL, object oCaster = OBJECT_SELF);
|
||
|
||
|
||
// SMP_INC_DISPEL.
|
||
// This will dispel magic - on an area of effect. Each one will need a seperate
|
||
// caster check to destroy and must be from a spell, of course.
|
||
void SMP_DispelMagicAreaOfEffect(object oAOE, int nCasterLevel);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// By putting in nMPH, it will see if it can remove oAOE, if it is a fog-based AOE.
|
||
void SMP_DispelWindAreaOfEffect(object oAOE, int nMPH);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// This will remove all "friendly" effects from oTarget which are from spells.
|
||
// - Only do this if oTarget is an enemy.
|
||
void SMP_DispelAllFriendlySpells(object oTarget, object oCaster = OBJECT_SELF);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells which are of
|
||
// nEffectType, using nCasterLevel.
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllEffectsOfType(object oTarget, int nCasterLevel, int nEffectType);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells which are
|
||
// nSpellId, using nCasterLevel. Once one is tested, all are removed.
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellsOfId(object oTarget, int nCasterLevel, int nSpellId);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Good/Evil Alignment nAlignment. Goes from Best to Worse, using nCasterLevel.
|
||
// * Also the list will try any GoodEvil spells of nAlignment
|
||
// * Returns TRUE if any are removed, and 2 if any are found. (for VFX's)
|
||
int SMP_DispelBestSpellFromGoodEvilAlignment(object oTarget, int nCasterLevel, int nAlignment);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Good/Evil Alignment nAlignment.
|
||
// * Also the list will try any GoodEvil spells of nAlignment
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellFromGoodEvilAlignment(object oTarget, int nCasterLevel, int nAlignment);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Law/Chaos Alignment nAlignment. Goes from Best to Worse, using nCasterLevel.
|
||
// * Also the list will try any LawChaos spells of nAlignment
|
||
// * Returns TRUE if any are removed, and 2 if any are found. (for VFX's)
|
||
int SMP_DispelBestSpellFromLawChaosAlignment(object oTarget, int nCasterLevel, int nAlignment);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Law/Chaos Alignment nAlignment.
|
||
// * Also the list will try any LawChaos spells of nAlignment
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellFromLawChaosAlignment(object oTarget, int nCasterLevel, int nAlignment);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Get the caster level of nSpellId from oCaster. This will get the last caster level
|
||
// of the spell cast by oCaster of nSpellId.
|
||
// * Used in dispel functions.
|
||
// * If oCaster is invalid, it will use the Spell Level (Innate) + 1 / 2 to get the
|
||
// minimum caster level for at least a half-decent DC
|
||
int SMP_DispelGetCasterLevelOfSpell(int nSpellId, object oCaster);
|
||
// SMP_INC_DISPEL. Get the level of the spell, nSpellId, last cast by oCreator.
|
||
// * Use the innate level if the caster is invalid.
|
||
int SMP_DispelGetLevelOfSpell(int nSpellId, object oCaster);
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells which are of
|
||
// the spell school nSpellSchool.
|
||
// * If nLevelIfSpecial is over 0, and the effect is supernatural or extraodinary,
|
||
// it will dispel it still if the spell's level is <= nLevelIfSpecial
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellsFromSpellSchool(object oTarget, int nCasterLevel, int nSpellSchool, int nLevelIfSpecial = 0);
|
||
|
||
// SMP_INC_DISPEL. Returns an integer value of all the valid effects on oTarget.
|
||
// Used in "Best" dispel function.
|
||
int SMP_DispelCountEffectsOnTarget(object oTarget);
|
||
|
||
// Start functions
|
||
|
||
// SMP_INC_DISPEL. This will dispel magic (All, IE targeted) on oTarget.
|
||
// * Checks spell effects for special things when ended.
|
||
// * No special reaction checks.
|
||
// * Put in eDispel, all effect.
|
||
// * Removes all friendly-spell effects off oTarget, by oCaster if "good" spells.
|
||
// * Will check items equipped by oTarget, and dispel ALL possible ones.
|
||
void SMP_DispelMagicAll(object oTarget, effect eDispel, effect eVis, object oCaster = OBJECT_SELF)
|
||
{
|
||
// If they are specifically immune to dispel, do not dispel!
|
||
if(GetLocalInt(oTarget, SMP_IMMUNNITY_TO_DISPEL)) return;
|
||
|
||
// We remove all friendly spell effects cast by oCaster if they are not
|
||
// a friend/faction equal
|
||
if(!GetIsFriend(oTarget, oCaster) && !GetFactionEqual(oTarget, oCaster))
|
||
{
|
||
// Remove them
|
||
SMP_DispelAllFriendlySpells(oTarget, oCaster);
|
||
}
|
||
|
||
// Apply dispel
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDispel, oTarget);
|
||
|
||
// We can also dispel all magical spells from thier items
|
||
int nCnt;
|
||
for(nCnt = 0; nCnt <= NUM_INVENTORY_SLOTS; nCnt++)
|
||
{
|
||
// Dispel the magic from that slot.
|
||
SMP_DispelMagicAllOnItem(GetItemInSlot(nCnt, oTarget));
|
||
}
|
||
}
|
||
|
||
|
||
// SMP_INC_DISPEL. This will dispel magic (All, IE targeted) on oTarget.
|
||
// * Checks spell effects for special things when ended.
|
||
// * No special reaction checks.
|
||
// * Put in eDispel, best effect.
|
||
// * Removes all friendly-spell effects off oTarget, by oCaster if "good" spells.
|
||
// * Will check items equipped by oTarget, and dispel ONE possible effect.
|
||
void SMP_DispelMagicBest(object oTarget, effect eDispel, effect eVis, object oCaster = OBJECT_SELF)
|
||
{
|
||
// If they are specifically immune to dispel, do not dispel!
|
||
if(GetLocalInt(oTarget, SMP_IMMUNNITY_TO_DISPEL)) return;
|
||
|
||
// We remove all friendly spell effects cast by oCaster if they are not
|
||
// a friend/faction equal
|
||
if(!GetIsFriend(oTarget, oCaster) && !GetFactionEqual(oTarget, oCaster))
|
||
{
|
||
// Remove them
|
||
SMP_DispelAllFriendlySpells(oTarget, oCaster);
|
||
}
|
||
|
||
// Count up the effects on oTarget before applying eDispel
|
||
int nBefore = SMP_DispelCountEffectsOnTarget(oTarget);
|
||
|
||
// Apply dispel
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDispel, oTarget);
|
||
|
||
// Count up the effects on oTarget after applying eDispel
|
||
int nAfter = SMP_DispelCountEffectsOnTarget(oTarget);
|
||
|
||
// If we have removed at least 1 effect from oTarget, we do not dispel
|
||
// item properties.
|
||
if(nBefore > nAfter)
|
||
{
|
||
// We can also dispel the best magical spells from thier items if we have
|
||
// not removed anything from eDispel.
|
||
int nCnt, bDone;
|
||
for(nCnt = 0; (bDone != TRUE && nCnt <= NUM_INVENTORY_SLOTS); nCnt++)
|
||
{
|
||
// Dispel the best magic from that slot.
|
||
bDone = SMP_DispelMagicBestOnItem(GetItemInSlot(nCnt, oTarget));
|
||
}
|
||
}
|
||
}
|
||
|
||
// SMP_INC_DISPEL. Dispels all magic on oItem.
|
||
// * TRUE if we dispel anything.
|
||
int SMP_DispelMagicAllOnItem(object oItem)
|
||
{
|
||
// Return value
|
||
int bReturn, bGotSpell;
|
||
|
||
// We need to check a local variable - is there any valid spells on the
|
||
// item, or cast on it?
|
||
if(GetLocalInt(oItem, "SMP_ITEM_SPELLCASTON") == TRUE)
|
||
{
|
||
// We loop the item properties on oItem.
|
||
itemproperty ipCheck = GetFirstItemProperty(oItem);
|
||
int nPropType;
|
||
while(GetIsItemPropertyValid(ipCheck))
|
||
{
|
||
// Check duration
|
||
if(GetItemPropertyDurationType(ipCheck) == DURATION_TYPE_TEMPORARY)
|
||
{
|
||
// We check nPropType
|
||
nPropType = GetItemPropertyType(ipCheck);
|
||
|
||
// Each spell will set, on the item, a valid integer for the caster
|
||
// level of the temp item property.
|
||
|
||
// TO DO
|
||
|
||
// Set bGotSpell to TRUE
|
||
bGotSpell = TRUE;
|
||
}
|
||
}
|
||
|
||
// Note: Here, if we didn't find any tempoary item properties from spells, we
|
||
// will set the local to FALSE again, by deleting it.
|
||
if(bGotSpell == FALSE)
|
||
{
|
||
DeleteLocalInt(oItem, "SMP_ITEM_SPELLCASTON");
|
||
}
|
||
}
|
||
return bReturn;
|
||
}
|
||
// SMP_INC_DISPEL. Dispels one spell on oItem.
|
||
// * TRUE if we dispel anything.
|
||
int SMP_DispelMagicBestOnItem(object oItem)
|
||
{
|
||
// Return value
|
||
int bReturn, bGotSpell;
|
||
|
||
// We need to check a local variable - is there any valid spells on the
|
||
// item, or cast on it?
|
||
if(GetLocalInt(oItem, "SMP_ITEM_SPELLCASTON") == TRUE)
|
||
{
|
||
// We loop the item properties on oItem.
|
||
itemproperty ipCheck = GetFirstItemProperty(oItem);
|
||
int nPropType;
|
||
while(GetIsItemPropertyValid(ipCheck))
|
||
{
|
||
// Check duration
|
||
if(GetItemPropertyDurationType(ipCheck) == DURATION_TYPE_TEMPORARY)
|
||
{
|
||
// We check nPropType
|
||
nPropType = GetItemPropertyType(ipCheck);
|
||
|
||
// Each spell will set, on the item, a valid integer for the caster
|
||
// level of the temp item property.
|
||
|
||
// TO DO
|
||
|
||
// Set bGotSpell to TRUE
|
||
bGotSpell = TRUE;
|
||
}
|
||
}
|
||
|
||
// Note: Here, if we didn't find any tempoary item properties from spells, we
|
||
// will set the local to FALSE again, by deleting it.
|
||
if(bGotSpell == FALSE)
|
||
{
|
||
DeleteLocalInt(oItem, "SMP_ITEM_SPELLCASTON");
|
||
}
|
||
}
|
||
|
||
return bReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// This will dispel magic - on an area of effect. Each one will need a seperate
|
||
// caster check to destroy and must be from a spell, of course.
|
||
void SMP_DispelMagicAreaOfEffect(object oAOE, int nCasterLevel)
|
||
{
|
||
// Can't be a plotted AOE - as it will not be destroyed anyway!
|
||
if(GetPlotFlag(oAOE)) return;
|
||
|
||
// Dispel the AOE
|
||
int nEnemyCasterLevel = SMP_GetAOECasterLevel(oAOE);
|
||
|
||
// Forbiddance:
|
||
// Dispel magic does not dispel a forbiddance effect unless the dispeller<65>s
|
||
// level is at least as high as your caster level.
|
||
if(GetTag(oAOE) == SMP_AOE_TAG_PER_FORBIDDANCE)
|
||
{
|
||
if(nEnemyCasterLevel >= nCasterLevel)
|
||
{
|
||
// Cannot dispel!
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Get the level of the AOE
|
||
int nDC = 11 + nEnemyCasterLevel;
|
||
|
||
// Do the roll
|
||
int nCasterRoll = d20() + nCasterLevel;
|
||
|
||
// If sucessful, destroy the target.
|
||
if(nCasterRoll >= nDC)
|
||
{
|
||
DestroyObject(oAOE);
|
||
}
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// By putting in nMPH, it will see if it can remove oAOE, if it is a fog-based AOE.
|
||
void SMP_DispelWindAreaOfEffect(object oAOE, int nMPH)
|
||
{
|
||
// Can't be a plotted AOE - as it will not be destroyed anyway!
|
||
if(GetPlotFlag(oAOE)) return;
|
||
|
||
// Spells used in: Gust of Wind (50MPH)
|
||
|
||
// We check the tag of oAOE
|
||
string sTag = GetTag(oAOE);
|
||
// We get the DC of the MPH needed. It will be slightly randomised.
|
||
// - Note that it is the "is removed in 1 round" MPH needed. This is an instant
|
||
// gust of wind.
|
||
int nDC;
|
||
|
||
// Will finish later.
|
||
if(sTag == SMP_AOE_TAG_PER_ACID_FOG)
|
||
{
|
||
nDC = 40 + Random(11);
|
||
}
|
||
|
||
// If sucessful, destroy the target.
|
||
if(nMPH >= nDC)
|
||
{
|
||
DestroyObject(oAOE);
|
||
}
|
||
}
|
||
|
||
// SMP_INC_DISPEL. This will disjoin magical effects on oTarget (Mage's Disjuction).
|
||
// - Checks spell effects for special things when ended.
|
||
// - No special reaction checks.
|
||
// - It will remove all SUBTYPE_MAGICAL effects which have
|
||
// GetEffectSpellId() != SPELL_INVALID
|
||
// * Note it can remove some effects Dispel Magic cannot. And does so here.
|
||
void SMP_DisjoinMagic(object oTarget, int nVFX = VFX_IMP_DISPEL, object oCaster = OBJECT_SELF)
|
||
{
|
||
// If they are specifically immune to dispel, do not dispel!
|
||
if(GetLocalInt(oTarget, SMP_IMMUNNITY_TO_DISPEL)) return;
|
||
|
||
// We do not affect ourselves:
|
||
// All magical effects from spells and magic items within the radius of the
|
||
// spell, |||except for those that you carry or touch|||, are disjoined.
|
||
if(oTarget == oCaster) return;
|
||
|
||
// Declare effects
|
||
effect eVis = EffectVisualEffect(nVFX);
|
||
int nSpellId;
|
||
|
||
// Set if the target has any spell effects that have effects applied
|
||
// when ended.
|
||
|
||
// - Stuff
|
||
|
||
// Apply dispel
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
// Remove all magical spell applied effects
|
||
if(nSpellId != SPELL_INVALID &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL)
|
||
{
|
||
RemoveEffect(oTarget, eCheck);
|
||
}
|
||
// * Seal magic is also disjoined
|
||
else if(nSpellId == SMP_SPELL_SEAL_MAGIC)
|
||
{
|
||
RemoveEffect(oTarget, eCheck);
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||
|
||
// And apply the effects of spells removed.
|
||
|
||
// - Stuff
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// This will remove all "friendly" effects from oTarget which are from spells.
|
||
// - Only do this if oTarget is an enemy.
|
||
void SMP_DispelAllFriendlySpells(object oTarget, object oCaster = OBJECT_SELF)
|
||
{
|
||
// Get first effect from oTarget
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
int nSpellId = -1;
|
||
// Remove all from oCaster, which have a valid spell ID and friendly status.
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
if(GetEffectCreator(eCheck) == oCaster)
|
||
{
|
||
//If the effect was created by the spell then remove it
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
if(nSpellId >= 0)
|
||
{
|
||
// Check if not-hostile.
|
||
if(SMP_ArrayGetIsHostile(nSpellId) == FALSE)
|
||
{
|
||
RemoveEffect(oTarget, eCheck);
|
||
}
|
||
}
|
||
}
|
||
//Get next effect on the target
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells which are of
|
||
// nEffectType, using nCasterLevel.
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllEffectsOfType(object oTarget, int nCasterLevel, int nEffectType)
|
||
{
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellId, nDC;
|
||
// Loop effects and try and dispel each one!
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
// Magical subtype and must be from a spell, and nEffectType must match!
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
if(nSpellId >= 0 && GetEffectType(eCheck) == nEffectType &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL)
|
||
{
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, GetEffectCreator(eCheck));
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove the effect!
|
||
RemoveEffect(oTarget, eCheck);
|
||
bReturn = TRUE;
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
|
||
return bReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells which are
|
||
// nSpellId, using nCasterLevel. Once one is tested, all are removed.
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellsOfId(object oTarget, int nCasterLevel, int nSpellId)
|
||
{
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellId, nDC;
|
||
// Loop effects and try and dispel each one!
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
// Magical subtype and must be from nSpellId.
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
if(nSpellId == nSpellId &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL)
|
||
{
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, GetEffectCreator(eCheck));
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove the effect!
|
||
RemoveEffect(oTarget, eCheck);
|
||
bReturn = TRUE;
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
|
||
return bReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Good/Evil Alignment nAlignment. Goes from Best to Worse, using nCasterLevel.
|
||
// * Also the list will try any GoodEvil spells of nAlignment
|
||
// * Returns TRUE if any are removed, and 2 if any are found. (for VFX's)
|
||
int SMP_DispelBestSpellFromGoodEvilAlignment(object oTarget, int nCasterLevel, int nAlignment)
|
||
{
|
||
// BEST VERSION. This will only dispel the best evil spell on the target.
|
||
// Decided:
|
||
// - Going to just dispel the FIST evil spell on the target...
|
||
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellId, nDC;
|
||
object oCreator;
|
||
// Loop effects to get the best to worst spells.
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck) && bReturn != TRUE)
|
||
{
|
||
// Magical subtype and must be from nSpellId.
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
oCreator = GetEffectCreator(eCheck);
|
||
if(nSpellId >= 0 &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL)
|
||
{
|
||
// Check alignment GOOD/EVIL
|
||
if(SMP_ArrayGetSpellGoodEvilAlignment(nSpellId) == nAlignment ||
|
||
// Note: Returns -1 if invalid, so this is good to use easily.
|
||
GetAlignmentGoodEvil(oCreator) == nAlignment)
|
||
{
|
||
// Dispel found
|
||
bReturn = 2;
|
||
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, oCreator);
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove all effects from the spell by oCreator
|
||
SMP_PRCRemoveSpellEffects(nSpellId, oCreator, oTarget, 0.1);
|
||
bReturn = TRUE;
|
||
}
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
return bReturn;
|
||
}
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Good/Evil Alignment nAlignment.
|
||
// * Also the list will try any GoodEvil spells of nAlignment
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellFromGoodEvilAlignment(object oTarget, int nCasterLevel, int nAlignment)
|
||
{
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellId, nDC;
|
||
object oCreator;
|
||
string sId;
|
||
// Loop effects and try and dispel each one!
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
// Magical subtype and must be from nSpellId.
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
sId = "SMP_ALIGNMENTDISPEL" + IntToString(nSpellId);
|
||
oCreator = GetEffectCreator(eCheck);
|
||
// We check if we have dispelled this spells' effect already
|
||
// * Local will be either an alignment (>= 1), -1 for invalid alignment
|
||
// or -2 for "never dispel this effect". -2 will never match.
|
||
if(GetAlignmentGoodEvil(oCreator) == GetLocalInt(OBJECT_SELF, sId))
|
||
{
|
||
// Remove
|
||
// * Note to self: could make it more complexe and, say, check the
|
||
// effect creator. Would need more complexe integers, however.
|
||
// * We do, though, check the alignment of the spellcaster against
|
||
// the local, this is a partial check.
|
||
RemoveEffect(oTarget, eCheck);
|
||
}
|
||
else if(nSpellId >= 0 &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL &&
|
||
GetLocalInt(OBJECT_SELF, sId) != -2)
|
||
{
|
||
|
||
// Check alignment GOOD/EVIL
|
||
if(SMP_ArrayGetSpellGoodEvilAlignment(nSpellId) == nAlignment ||
|
||
// Note: Returns -1 if invalid, so this is good to use easily.
|
||
GetAlignmentGoodEvil(oCreator) == nAlignment)
|
||
{
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, oCreator);
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove the effect!
|
||
RemoveEffect(oTarget, eCheck);
|
||
// NOTE:
|
||
// - Because we have dispelled this spell - other effects
|
||
// from this spell (like visuals) might still be present.
|
||
// This isn't the case when we check specific effects, but
|
||
// it is when we dispel all spells of nSpellId, from oTarget.
|
||
|
||
// This means I'll set a local variable to the caster (OBJECT_SELF)
|
||
// so it'll remove futher effects from nSpellId.
|
||
|
||
// GetAlignmentGoodEvil() is DISPEL ALL OTHERS
|
||
SetLocalInt(OBJECT_SELF, sId, GetAlignmentGoodEvil(oCreator));
|
||
DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, sId));
|
||
|
||
bReturn = TRUE;
|
||
}
|
||
else
|
||
{
|
||
// See above, but the dispel failed, so we set to NEVER
|
||
// remove futher effects from nSpellId.
|
||
|
||
// -2 is IGNORE ALL OTHERS
|
||
SetLocalInt(OBJECT_SELF, sId, -2);
|
||
DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, sId));
|
||
}
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
return bReturn;
|
||
}
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Law/Chaos Alignment nAlignment. Goes from Best to Worse, using nCasterLevel.
|
||
// * Also the list will try any LawChaos spells of nAlignment
|
||
// * Returns TRUE if any are removed, and 2 if any are found. (for VFX's)
|
||
int SMP_DispelBestSpellFromLawChaosAlignment(object oTarget, int nCasterLevel, int nAlignment)
|
||
{
|
||
// BEST VERSION. This will only dispel the best evil spell on the target.
|
||
// Decided:
|
||
// - Going to just dispel the FIST evil spell on the target...
|
||
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellId, nDC;
|
||
object oCreator;
|
||
// Loop effects to get the best to worst spells.
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck) && bReturn != TRUE)
|
||
{
|
||
// Magical subtype and must be from nSpellId.
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
oCreator = GetEffectCreator(eCheck);
|
||
if(nSpellId >= 0 &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL)
|
||
{
|
||
// Check alignment LAW/CHAOS
|
||
if(SMP_ArrayGetSpellLawChaosAlignment(nSpellId) == nAlignment ||
|
||
// Note: Returns -1 if invalid, so this is good to use easily.
|
||
GetAlignmentLawChaos(oCreator) == nAlignment)
|
||
{
|
||
// Dispel found
|
||
bReturn = 2;
|
||
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, oCreator);
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove all effects from the spell by oCreator
|
||
SMP_PRCRemoveSpellEffects(nSpellId, oCreator, oTarget, 0.1);
|
||
bReturn = TRUE;
|
||
}
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
return bReturn;
|
||
}
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells cast by
|
||
// Law/Chaos Alignment nAlignment.
|
||
// * Also the list will try any LawChaos spells of nAlignment
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellFromLawChaosAlignment(object oTarget, int nCasterLevel, int nAlignment)
|
||
{
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellId, nDC;
|
||
object oCreator;
|
||
string sId;
|
||
// Loop effects and try and dispel each one!
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
// Magical subtype and must be from nSpellId.
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
sId = "SMP_ALIGNMENTDISPEL" + IntToString(nSpellId);
|
||
oCreator = GetEffectCreator(eCheck);
|
||
// We check if we have dispelled this spells' effect already
|
||
// * Local will be either an alignment (>= 1), -1 for invalid alignment
|
||
// or -2 for "never dispel this effect". -2 will never match.
|
||
if(GetAlignmentLawChaos(oCreator) == GetLocalInt(OBJECT_SELF, sId))
|
||
{
|
||
// Remove
|
||
// * Note to self: could make it more complexe and, say, check the
|
||
// effect creator. Would need more complexe integers, however.
|
||
// * We do, though, check the alignment of the spellcaster against
|
||
// the local, this is a partial check.
|
||
RemoveEffect(oTarget, eCheck);
|
||
}
|
||
else if(nSpellId >= 0 &&
|
||
GetEffectSubType(eCheck) == SUBTYPE_MAGICAL &&
|
||
GetLocalInt(OBJECT_SELF, sId) != -2)
|
||
{
|
||
|
||
// Check alignment LAW/CHAOS
|
||
if(SMP_ArrayGetSpellLawChaosAlignment(nSpellId) == nAlignment ||
|
||
// Note: Returns -1 if invalid, so this is good to use easily.
|
||
GetAlignmentLawChaos(oCreator) == nAlignment)
|
||
{
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, oCreator);
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove the effect!
|
||
RemoveEffect(oTarget, eCheck);
|
||
// NOTE:
|
||
// - Because we have dispelled this spell - other effects
|
||
// from this spell (like visuals) might still be present.
|
||
// This isn't the case when we check specific effects, but
|
||
// it is when we dispel all spells of nSpellId, from oTarget.
|
||
|
||
// This means I'll set a local variable to the caster (OBJECT_SELF)
|
||
// so it'll remove futher effects from nSpellId.
|
||
|
||
// GetAlignmentGoodEvil() is DISPEL ALL OTHERS
|
||
SetLocalInt(OBJECT_SELF, sId, GetAlignmentLawChaos(oCreator));
|
||
DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, sId));
|
||
|
||
bReturn = TRUE;
|
||
}
|
||
else
|
||
{
|
||
// See above, but the dispel failed, so we set to NEVER
|
||
// remove futher effects from nSpellId.
|
||
|
||
// -2 is IGNORE ALL OTHERS
|
||
SetLocalInt(OBJECT_SELF, sId, -2);
|
||
DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, sId));
|
||
}
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
return bReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Get the caster level of nSpellId from oCaster. This will get the last caster level
|
||
// of the spell cast by oCaster of nSpellId.
|
||
// * Used in dispel functions.
|
||
// * If oCaster is invalid, it will use the Spell Level (Innate) + 1 / 2 to get the
|
||
// minimum caster level for at least a half-decent DC
|
||
int SMP_DispelGetCasterLevelOfSpell(int nSpellId, object oCaster)
|
||
{
|
||
int nReturn;
|
||
if(GetIsObjectValid(oCaster))
|
||
{
|
||
// Get value stored SMP_inc_spellhook
|
||
nReturn = GetLocalInt(oCaster, "SMP_SPELL_CAST_BY_LEVEL_" + IntToString(nSpellId));
|
||
}
|
||
else
|
||
{
|
||
// If oCaster is invalid, it will use the Spell Level (Innate) + 1 / 2 to
|
||
// get the minimum caster level for at least a half-decent DC
|
||
nReturn = (SMP_ArrayGetInteger(SMP_2DA_NAME_SPELLS, SMP_2DA_COLUMN_SPELLS_INNATE, nSpellId) + 1) / 2;
|
||
}
|
||
return nReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL. Get the level of the spell, nSpellId, last cast by oCreator.
|
||
// * Use the innate level if the caster is invalid.
|
||
int SMP_DispelGetLevelOfSpell(int nSpellId, object oCaster)
|
||
{
|
||
int nReturn;
|
||
if(GetIsObjectValid(oCaster))
|
||
{
|
||
// Get value stored SMP_inc_spellhook
|
||
nReturn = GetLocalInt(oCaster, "SMP_SPELL_CAST_SPELL_LEVEL" + IntToString(nSpellId));
|
||
}
|
||
else
|
||
{
|
||
// If oCaster is invalid, it will use the Spell Level (Innate)
|
||
nReturn = SMP_ArrayGetInteger(SMP_2DA_NAME_SPELLS, SMP_2DA_COLUMN_SPELLS_INNATE, nSpellId);
|
||
}
|
||
return nReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL.
|
||
// Does a dispel check against oTarget for all effects from spells which are of
|
||
// the spell school nSpellSchool.
|
||
// * If nLevelIfSpecial is over 0, and the effect is supernatural or extraodinary,
|
||
// it will dispel it still if the spell's level is <= nLevelIfSpecial
|
||
// * Returns TRUE if any are removed (for VFX's)
|
||
int SMP_DispelAllSpellsFromSpellSchool(object oTarget, int nCasterLevel, int nSpellSchool, int nLevelIfSpecial = 0)
|
||
{
|
||
int bReturn = FALSE;
|
||
int nEffectCasterLevel, nSpellLevel, nSpellId, nDC;
|
||
object oCreator;
|
||
string sId;
|
||
// Loop effects and try and dispel each one!
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
// Magical subtype and must be from nSpellId.
|
||
nSpellId = GetEffectSpellId(eCheck);
|
||
sId = "SMP_SPELLSCHOOLDISPEL" + IntToString(nSpellId);
|
||
oCreator = GetEffectCreator(eCheck);
|
||
// We check if we have dispelled this spells' effect already
|
||
// * Local will be either be 1, for dispel all spells of this spell ID,
|
||
// or -2 for "never dispel this effect". -2 will never match.
|
||
if(GetLocalInt(OBJECT_SELF, sId) == TRUE)
|
||
{
|
||
// Remove
|
||
// * Note to self: could make it more complexe and, say, check the
|
||
// effect creator. Would need more complexe integers, however.
|
||
// * In this case (against the alignment thing) we don't check
|
||
// alignment.
|
||
RemoveEffect(oTarget, eCheck);
|
||
}
|
||
else if(nSpellId >= 0 &&
|
||
// Check spell school
|
||
SMP_ArrayGetSpellSchool(nSpellId) == nSpellSchool &&
|
||
// Special: If it isn't a magical subtype, we may still dispel
|
||
// if the spells level is <= nLevelIfSpecial.
|
||
(GetEffectSubType(eCheck) == SUBTYPE_MAGICAL ||
|
||
// * NOTE: Using special function, will at least return innate column
|
||
// or the value, if present, set in the spell hook.
|
||
SMP_DispelGetLevelOfSpell(nSpellId, oCreator) <= nLevelIfSpecial) &&
|
||
GetLocalInt(OBJECT_SELF, sId) != -2)
|
||
{
|
||
// We try and dispel the spells effects
|
||
nEffectCasterLevel = SMP_DispelGetCasterLevelOfSpell(nSpellId, oCreator);
|
||
|
||
// DC is always 11 + nEffectCasterLevel
|
||
nDC = 11 + nEffectCasterLevel;
|
||
|
||
// Dispel!
|
||
if(nCasterLevel + d20() >= nDC)
|
||
{
|
||
// Remove the effect!
|
||
RemoveEffect(oTarget, eCheck);
|
||
// NOTE:
|
||
// - Because we have dispelled this spell - other effects
|
||
// from this spell (like visuals) might still be present.
|
||
// This isn't the case when we check specific effects, but
|
||
// it is when we dispel all spells of nSpellId, from oTarget.
|
||
|
||
// This means I'll set a local variable to the caster (OBJECT_SELF)
|
||
// so it'll remove futher effects from nSpellId.
|
||
|
||
// We use a mear TRUE value for this for now.
|
||
SetLocalInt(OBJECT_SELF, sId, TRUE);
|
||
DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, sId));
|
||
|
||
bReturn = TRUE;
|
||
}
|
||
else
|
||
{
|
||
// -2 is IGNORE ALL OTHERS
|
||
SetLocalInt(OBJECT_SELF, sId, -2);
|
||
DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, sId));
|
||
}
|
||
}
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
return bReturn;
|
||
}
|
||
|
||
// SMP_INC_DISPEL. Returns an integer value of all the valid effects on oTarget.
|
||
// Used in "Best" dispel function.
|
||
int SMP_DispelCountEffectsOnTarget(object oTarget)
|
||
{
|
||
int nReturn = 0;
|
||
effect eCheck = GetFirstEffect(oTarget);
|
||
while(GetIsEffectValid(eCheck))
|
||
{
|
||
// Add one to effects found
|
||
nReturn++;
|
||
eCheck = GetNextEffect(oTarget);
|
||
}
|
||
// Return the amount
|
||
return nReturn;
|
||
}
|
||
|
||
|
||
// End of file Debug lines. Uncomment below "/*" with "//" and compile.
|
||
/*
|
||
void main()
|
||
{
|
||
return;
|
||
}
|
||
//*/
|