Updated AMS marker feats. Removed arcane & divine marker feats. Updated Dread Necromancer for epic progression. Updated weapon baseitem models. Updated new weapons for crafting & npc equip. Updated prefix. Updated release archive.
		
			
				
	
	
		
			635 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			635 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| //:: This is the prc_dispel_magic functions declarations.   The functions themselves are at the bottom
 | |
| //:: of the file.       I got tired of circular include statement errors and just decided to make
 | |
| //:: these both be just one file by adding my text to theirs.
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| //:: This function is called from withing PRCApplyEffectToObject().  It's purpose is to
 | |
| //:: clean up the three arrays that hold the caster level and references to all
 | |
| //:: effects on the object having this struct PRCeffect applied to it.
 | |
| //:: It also returns the expected number of entries in the new arrays it will have set up.
 | |
| int ReorderEffects(struct PRCeffect eIn, object oTarget);
 | |
| 
 | |
| //:: This function is called from withing ReorderEffects().  It's purpose is to verify
 | |
| //:: that the struct PRCeffect referred to by an entry in the 3 arrays is still in effect, returning
 | |
| //:: FALSE if it is not.
 | |
| int IsStillRealEffect(struct PRCeffect eEffect, object oTarget);
 | |
| 
 | |
| //:: This is my remake of the spellsDispelMagic found in x0_i0_spells.   It's pretty much
 | |
| //:: identical to the old one except instead of calling the EffectDispelMagicBest() and
 | |
| //:: EffectDispelMagicAll() scripting functions it calls the ones I've specified in this
 | |
| //:: file to replace them.
 | |
| void spellsDispelMagicMod(object oTarget, int nCasterLevel, struct PRCeffect eVis, struct PRCeffect eImpac, int bAll = TRUE, int bBreachSpells = FALSE);
 | |
| 
 | |
| //:: This is my remake of spellsDispelAoE().  It's very different, and very short.   It
 | |
| //:: takes advantage of the way I've reworked AoE's so that it can simply use the caster
 | |
| //:: level stored in the AoE and do a proper dispel check against it.
 | |
| void spellsDispelAoEMod(object oTargetAoE, object oCaster, int nCasterLevel);
 | |
| 
 | |
| //:: This function is to replace EffectDispelMagicBest().   It goes through the references
 | |
| //:: in the three arrays that store the caster levels and references to effects on oTarget,
 | |
| //:: chooses the one with the highest caster level, and attempts to dispel it using the
 | |
| //:: caster level entry in the array that corresponds to the spell itself.
 | |
| void DispelMagicBestMod(object oTarget, int nCasterLevel);
 | |
| 
 | |
| //:: This function is to replace EffectDispelMagicAll().  It goest through all the references
 | |
| //:: in the three arrays that store the caster levels and references to effects on oTarget, and
 | |
| //:: attempts a dispel on each of them.  It only checks to dispel whole spells, not individual
 | |
| //:: separate effects one spell may place on a person.
 | |
| void DispelMagicAllMod(object oTarget, int nCasterLevel);
 | |
| 
 | |
| //:: This function sorts the 3 arrays in descending order of caster level, so entry 0 is the
 | |
| //:: highest, and the last entry is the lowest.  It only gets called from inside DispelMagicBest()
 | |
| void SortAll3Arrays(object oTarget);
 | |
| 
 | |
| //:: This function is just a helper function to include Infestation of Maggots among the list
 | |
| //:: of spells in struct PRCeffect on oTarget, so it can be sorted with the rest. It's only called by
 | |
| //:: DispelMagicBest()
 | |
| void HandleInfestationOfMaggots(object oTarget);
 | |
| 
 | |
| // This sets many things that would have been checked against GetAreaOfEffectCreator()
 | |
| // as local ints making it so the AoE can now function entirely independantly of its caster.
 | |
| // - The only problem is that this will never be called until the AoE does a heartbeat or
 | |
| // something.
 | |
| void SetAllAoEInts(int SpellID, object oAoE, int nBaseSaveDC,int SpecDispel = 0, int nCasterLevel = 0);
 | |
| 
 | |
| // This is only meant to be called withing SetAllAoEInts()  I've heard terrible stories that
 | |
| // say if an object is destroyed, it's local variables may remain in place eating up memory
 | |
| // so I decided I'd better mop up after setting all of these.
 | |
| void DeleteAllAoEInts(object oAoE);
 | |
| 
 | |
| // Returns the AoE's entire caster level, including any from prc's as stored in the local variable
 | |
| int AoECasterLevel(object oAoE = OBJECT_SELF);
 | |
| 
 | |
| float GetRandomDelay(float fMinimumTime = 0.4, float MaximumTime = 1.1);
 | |
| 
 | |
| void PRCApplyEffectToObject(int nDurationType, struct PRCeffect eEffect, object oTarget, float fDuration = 0.0f, 
 | |
|     int bDispellable = TRUE, int nSpellID = -1, int nCasterLevel = -1, object oCaster = OBJECT_SELF);
 | |
| 
 | |
| void PRCApplyEffectAtLocation(int nDurationType, struct PRCeffect eEffect, location lLocation, float fDuration=0.0f);
 | |
| 
 | |
| #include "NW_I0_GENERIC"
 | |
| #include "prc_feat_const"
 | |
| #include "lookup_2da_spell"
 | |
| #include "prcsp_spell_adjs"
 | |
| #include "prc_alterations"
 | |
| #include "prc_inc_effect"
 | |
| 
 | |
| const string X2_EFFECT = "X2_Effects_";
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| //:: Goes through the whole 3 stored lists of caster levels, spell id's, and casters,
 | |
| //:: deletes any that aren't real anymore (refer to an struct PRCeffect no longer present), then
 | |
| //:: builds a new list out of the ones that are still real/current (refer to effects that
 | |
| //:: are still present)
 | |
| 
 | |
| //:: Thus, the list gets cleaned up every time it is added to.
 | |
| //:: It returns the number of effects in the 3 new arrays.
 | |
| 
 | |
| int ReorderEffects(struct PRCeffect eIn, object oTarget)
 | |
| {
 | |
|     int nIndex = GetLocalInt(oTarget, X2_EFFECT+"Index_Number");
 | |
|     struct PRCeffect eEffect;
 | |
|     int nRealIndex = 0;
 | |
|     int nPlace;
 | |
| 
 | |
|     for(nPlace = 0; nPlace <= nIndex; nPlace++)
 | |
|     {
 | |
|         // SendMessageToPC(OBJECT_SELF, "reorder for loop is happening at least once.");
 | |
|         eEffect = GetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nPlace));
 | |
|         DeleteLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nPlace));
 | |
| 
 | |
|         if(IsStillRealEffect(eEffect, oTarget))
 | |
|         {
 | |
|             if(eEffect.nSpellID != eIn.nSpellID 
 | |
|                 || eEffect.oCaster != eIn.oCaster)
 | |
|           // Take it out of the list if it's the spell now being cast, and by the same caster
 | |
|           // This way spells that don't self dispel when they're recast don't flood the list
 | |
|             {
 | |
|                 SetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nRealIndex), eEffect);
 | |
|  //             SendMessageToPC(OBJECT_SELF, "Index is incrementing.");
 | |
|                 nRealIndex++;
 | |
|             }// end of if is the same as the current spell and caster
 | |
|         }// end of if is valid struct PRCeffect statement
 | |
|     }// end of for statement
 | |
|    return nRealIndex; // This is the number of values currently in all 3 arrays -1.
 | |
| }// end of function
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| //:: This tests to make sure the data in my array still refers to an actual effect
 | |
| //:: in case it has been dispelled or run out its duration since the data was put there.
 | |
| int IsStillRealEffect(struct PRCeffect eEffect, object oTarget)
 | |
| {
 | |
|     struct PRCeffect eTest = GetEffectOnObjectFromPRCEffect(eEffect, oTarget);
 | |
|     if(PRCGetIsEffectValid(eTest))
 | |
|         return TRUE;
 | |
|     return FALSE;
 | |
| }
 | |
| 
 | |
| //:: Copy of the original function with 1 minor change: calls DispelMagicAll() and
 | |
| //:: DispelMagicBest() instead of EffectDispelMagicAll() and EffectDispelMagicBest()
 | |
| //:: That is the only change.
 | |
| //------------------------------------------------------------------------------
 | |
| // Attempts a dispel on one target, with all safety checks put in.
 | |
| //------------------------------------------------------------------------------
 | |
| void spellsDispelMagicMod(object oTarget, int nCasterLevel, struct PRCeffect eVis, struct PRCeffect eImpac, int bAll = TRUE, int bBreachSpells = FALSE)
 | |
| {
 | |
|     //--------------------------------------------------------------------------
 | |
|     // 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 (PRCGetHasEffect(EFFECT_TYPE_PETRIFY, oTarget) == TRUE 
 | |
|         || GetLocalInt(oTarget, "X1_L_IMMUNE_TO_DISPEL") == 10)
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     struct PRCeffect eDispel;
 | |
|     float fDelay = GetRandomDelay(0.1, 0.3);
 | |
|     int nId = PRCGetSpellId();
 | |
| 
 | |
|     //--------------------------------------------------------------------------
 | |
|     // Fire hostile event only if the target is hostile...
 | |
|     //--------------------------------------------------------------------------
 | |
|     
 | |
|     if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))    
 | |
|         SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nId));
 | |
|     else
 | |
|         SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nId, FALSE));
 | |
| 
 | |
|     //--------------------------------------------------------------------------
 | |
|     // GZ: Bugfix. Was always dispelling all effects, even if used for AoE
 | |
|     //--------------------------------------------------------------------------
 | |
|     if (bAll == TRUE )
 | |
|     {
 | |
|         //:: This is the first of 2 changes I made.
 | |
|         DispelMagicAllMod(oTarget, nCasterLevel);
 | |
| 
 | |
|         // The way it used to get done.
 | |
|         //eDispel = PRCEffectDispelMagicAll(nCasterLevel);
 | |
| 
 | |
|         //----------------------------------------------------------------------
 | |
|         // GZ: Support for Mord's disjunction
 | |
|         //----------------------------------------------------------------------
 | |
|         if (bBreachSpells)
 | |
|         {
 | |
|             DoSpellBreach(oTarget, 6, 10, nId);
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         //:: This is the second of the 2 changes I made.
 | |
|         //:: There are no other changes.
 | |
|         DispelMagicBestMod(oTarget, nCasterLevel);
 | |
| 
 | |
|         // The way it used to get done
 | |
|         //eDispel = PRCEffectDispelMagicBest(nCasterLevel);
 | |
| 
 | |
|         if (bBreachSpells)
 | |
|         {
 | |
|            DoSpellBreach(oTarget, 2, 10, nId);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     DelayCommand(fDelay,PRCApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
 | |
|     DelayCommand(fDelay,PRCApplyEffectToObject(DURATION_TYPE_INSTANT, eDispel, oTarget));
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////////////////////////////////
 | |
| //::  This one's so small I hope not to lose track of it.
 | |
| 
 | |
| //:: Replaces the normal spellsDispelAoE
 | |
| //:: I reworked all AoE's to store their caster level as a local int on themselves,
 | |
| //:: so it's possible to just do a proper caster level check instead of doing
 | |
| //:: something complicated.
 | |
| 
 | |
| void spellsDispelAoEMod(object oTargetAoE, object oCaster, int nCasterLevel)
 | |
| {
 | |
|    int ModWeave;
 | |
|    int nBuffer = 0;
 | |
|    int nGirding = 0;
 | |
|    string SchoolWeave = lookup_spell_school(GetLocalInt(oTargetAoE, "X2_AoE_SpellID"));
 | |
|    int Weave = GetHasFeat(FEAT_SHADOWWEAVE,oCaster)+ GetLocalInt(oCaster, "X2_AoE_SpecDispel");
 | |
|    if (GetLocalInt(oTargetAoE, " X2_Effect_Weave_ID_") && !Weave) ModWeave = 4;
 | |
|    if (SchoolWeave=="V" ||SchoolWeave=="T"  ) ModWeave = 0;
 | |
|    if (GetLocalInt(oTargetAoE, "DispellingBuffer")) nBuffer = 5;
 | |
|    if (GetHasFeat(FEAT_SPELL_GIRDING, oTargetAoE)) nGirding = 2;
 | |
| 
 | |
|    int iDice = d20(1);
 | |
| //   SendMessageToPC(GetFirstPC(), "Spell :"+ IntToString(PRCGetSpellId())+" T "+GetName(oTargetAoE));
 | |
| //   SendMessageToPC(GetFirstPC(), "Dispell :"+IntToString(iDice + nCasterLevel)+" vs DC :"+IntToString(11 + GetLocalInt(oTargetAoE, "X2_AoE_Caster_Level")+ModWeave)+" Weave :"+IntToString(ModWeave)+" "+SchoolWeave);
 | |
| 
 | |
|    if(iDice + nCasterLevel >= GetLocalInt(oTargetAoE, "X2_AoE_Caster_Level")+ModWeave+nBuffer+nGirding)
 | |
|    {
 | |
|      DestroyObject(oTargetAoE);
 | |
|    }
 | |
| }
 | |
| 
 | |
|  ///////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| 
 | |
| //:: Goes through all the references to effects stored in the 3 variable arrays,
 | |
| //:: picks the one with the highest caster level (breaking ties by just keeping the
 | |
| //:: first one it comes to) and then attempts a dispel check on it.
 | |
| //:: It goes by spell, not spell effect, so a successful check removes all spell
 | |
| //:: affects from that spell itself.
 | |
| 
 | |
| void DispelMagicBestMod(object oTarget, int nCasterLevel)
 | |
| {
 | |
|     /// I *really*  want to rewrite this one so that it simply dispels the most useful effect
 | |
|     /// instead of just the one with the highest caster level.
 | |
|     /// Sure hate to dispel mage armor on somebody who's immune to necromancy.   Difficult Decision, these.
 | |
| 
 | |
|     //:: calls a function to determine whether infestation of maggots is in effect
 | |
|     //:: on the target.   If so, it adds it to the 3 arrays so it can be sorted with them.
 | |
|     HandleInfestationOfMaggots(oTarget);
 | |
| 
 | |
|     //:: calls a function to arrange the values in the 3 arrays in order of highest caster level to lowest
 | |
|     //:: Index 0 will be the highest, and nLastEntry will be the lowest.
 | |
| 
 | |
|     SortAll3Arrays(oTarget);
 | |
| 
 | |
|     int nCurrentEntry;
 | |
|     int nLastEntry = GetLocalInt(oTarget, X2_EFFECT+"Index_Number");
 | |
| 
 | |
|     struct PRCeffect eEffect;
 | |
|     int nBuffer;
 | |
|     if (GetLocalInt(oTarget, "DispellingBuffer")) 
 | |
|         nBuffer = 5; // from psi_pow_displbuf
 | |
| 
 | |
|     string sSelf = "Dispelled: ";
 | |
|     string sCast = "Dispelled on "+GetName(oTarget)+": ";
 | |
|  
 | |
| // SendMessageToPC(GetFirstPC(), "DispelMagicBestMod Weave Caster:"+ IntToString(Weave));
 | |
| 
 | |
|     for(nCurrentEntry = 0; nCurrentEntry <= nLastEntry; nCurrentEntry++)
 | |
|     {
 | |
|         eEffect = GetLocalPRCEffect(oTarget,X2_EFFECT+IntToString(nCurrentEntry));
 | |
|         //:: Make sure the struct PRCeffect it refers to is still in place before making it
 | |
|         //:: number one.
 | |
|         if(IsStillRealEffect(eEffect, oTarget))
 | |
|         {
 | |
|             int nModWeave = 0;
 | |
|             string SchoolWeave = lookup_spell_school(eEffect.nSpellID);
 | |
|             string SpellName = GetStringByStrRef(StringToInt(lookup_spell_name(eEffect.nSpellID)));            
 | |
| 
 | |
|             int nRoll, nDC;
 | |
|             nRoll += d20();
 | |
|             nRoll += nCasterLevel;
 | |
|             nDC += 11; //base
 | |
|             nDC += eEffect.nCasterLevel;
 | |
|             nDC += nBuffer; // from psi_pow_displbuf
 | |
|             if (GetHasFeat(FEAT_TENACIOUSMAGIC, eEffect.oCaster)//effect creator has Tenacious Magic
 | |
|                 && !GetHasFeat(FEAT_SHADOWWEAVE, OBJECT_SELF) //other shadow weave users casting the dispel ignore this
 | |
|                 && SchoolWeave != "V" //evocation & transmutation spells dont benefit from Tenacious Magic
 | |
|                 && SchoolWeave != "T")  
 | |
|                 nDC += 4; //base goes from 11 to 15, +4
 | |
|             if (GetHasFeat(FEAT_SPELL_GIRDING, eEffect.oCaster)) 
 | |
|                 nDC += 2; // from Spell Girding feat
 | |
| //          SendMessageToPC(GetFirstPC(), "Spell :"+ IntToString(nEffectSpellID)+" T "+GetName(oTarget)+" C "+GetName(oEffectCaster));
 | |
| //          SendMessageToPC(GetFirstPC(), "Dispell :"+ IntToString(iDice + nCasterLevel)+" vs DC :"+IntToString(11 + nEffectCastLevel+ModWeave)+" Mod Weave"+IntToString(ModWeave)+" "+SchoolWeave);
 | |
|             if(nRoll >= nDC)
 | |
| 
 | |
|             {
 | |
|                 if(eEffect.nSpellID != SPELL_INFESTATION_OF_MAGGOTS)
 | |
|                 {// If it isn't infestation of maggots we remove it one way, if it is, we remove it another.
 | |
|                     struct PRCeffect eToDispel = PRCGetFirstEffect(oTarget);
 | |
|                     while(PRCGetIsEffectValid(eToDispel))
 | |
|                     {
 | |
|                         if(PRCGetEffectSpellId(eToDispel) == eEffect.nSpellID
 | |
|                             && PRCGetEffectCreator(eToDispel) == eEffect.oCaster)
 | |
|                         {
 | |
|                             PRCRemoveEffect(oTarget, eToDispel);
 | |
|                         }// end if struct PRCeffect comes from this spell
 | |
|                         eToDispel = PRGetNextEffect(oTarget);
 | |
|                     }// end of while loop
 | |
|                 }// end if infestation is not the spell
 | |
|                 else
 | |
|                 {   
 | |
|                     DeleteLocalInt(oTarget, "XP2_L_SPELL_CASTER_LVL_" + IntToString (SPELL_INFESTATION_OF_MAGGOTS));
 | |
|                     // Deleting this variable is what actually ends the spell effect's damage.
 | |
|                     struct PRCeffect eToDispel = PRCGetFirstEffect(oTarget);
 | |
|                     while(PRCGetIsEffectValid(eToDispel))
 | |
|                     {
 | |
|                         //:: We don't worry about who cast it.  A person can only really have one infestation
 | |
|                         //:: going on at a time, I think.
 | |
|                         if(PRCGetEffectSpellId(eToDispel) == eEffect.nSpellID)
 | |
|                         {
 | |
|                             PRCRemoveEffect(oTarget, eToDispel);
 | |
|                         }// end if struct PRCeffect comes from this spell
 | |
|                         eToDispel = PRGetNextEffect(oTarget);
 | |
|                     }// end of while loop
 | |
|                 }// end else
 | |
| 
 | |
|                 //:: Since the struct PRCeffect has been removed, delete the references to it.
 | |
|                 //:: This will help out the sweeping function when it gets called next (not now, though)
 | |
|                 DeleteLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrentEntry));
 | |
| 
 | |
|                 //:: Display a message to all involved.
 | |
|                 SendMessageToPC(OBJECT_SELF, sCast+SpellName);
 | |
|                 if (oTarget != OBJECT_SELF) 
 | |
|                     SendMessageToPC(oTarget, sSelf+SpellName);
 | |
| 
 | |
|                 //:: If the check was successful, then we're done.
 | |
|                 return;
 | |
|             }// end if check is successful.
 | |
|         }// end if is still a valid spell.
 | |
|         else
 | |
|         {
 | |
|             // If it's not a real struct PRCeffect anymore, then delete the variables that refer to it.
 | |
|             DeleteLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrentEntry));
 | |
|         }// end of else statement.
 | |
|     }// end of for loop
 | |
|     // If we got here, the return function above never ran, so nothing got removed:
 | |
|     SendMessageToPC(OBJECT_SELF, sCast+"None");
 | |
|     if (oTarget != OBJECT_SELF) 
 | |
|         SendMessageToPC(oTarget, sSelf+"None");
 | |
| } // End Of Function
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| //:: Goes through and tries to remove each and every spell effect, doing a
 | |
| //:: separate caster level check for each spell.   It goes by spell, not spell
 | |
| //:: effect, so a successful check removes all spell affects from that spell
 | |
| //:: itself.
 | |
| 
 | |
| void DispelMagicAllMod(object oTarget, int nCasterLevel)
 | |
| {
 | |
| 
 | |
|   int nIndex = 0;
 | |
|   int nEffectSpellID;
 | |
|   int nEffectCasterLevel;
 | |
|   object oEffectCaster;
 | |
|   int ModWeave;
 | |
|   int nBuffer;
 | |
|   int nGirding = 0;
 | |
| 
 | |
|   int nLastEntry = GetLocalInt(oTarget, X2_EFFECT+"Index_Number");
 | |
|   struct PRCeffect eToDispel;
 | |
|   
 | |
|   string sList, SpellName;
 | |
|   string sSelf = "Dispelled: ";
 | |
|   string sCast = "Dispelled on "+GetName(oTarget)+": ";  
 | |
| 
 | |
|   int Weave = GetHasFeat(FEAT_SHADOWWEAVE,OBJECT_SELF)+ GetLocalInt(OBJECT_SELF, "X2_AoE_SpecDispel");
 | |
| //  SendMessageToPC(GetFirstPC(), "DispelMagicAllMod Weave Caster:"+ IntToString(Weave));
 | |
|   if (GetLocalInt(oTarget, "DispellingBuffer")) nBuffer = 5;
 | |
| 
 | |
|   //:: Do the dispel check for each and every spell in struct PRCeffect on oTarget.
 | |
|   for(nIndex; nIndex <= nLastEntry; nIndex++)
 | |
|   {
 | |
|     nEffectSpellID = GetLocalInt(oTarget, " X2_Effect_Spell_ID_" + IntToString(nIndex));
 | |
|     if(GetHasSpellEffect(nEffectSpellID, oTarget))
 | |
|     {
 | |
|       ModWeave = 0;
 | |
|       string SchoolWeave = lookup_spell_school(nEffectSpellID);
 | |
|       SpellName = GetStringByStrRef(StringToInt(lookup_spell_name(nEffectSpellID)));
 | |
|       nEffectCasterLevel = GetLocalInt(oTarget, " X2_Effect_Cast_Level_" + IntToString(nIndex));
 | |
|       if (GetLocalInt(oTarget, " X2_Effect_Weave_ID_"+ IntToString(nIndex)) && !Weave) ModWeave = 4;
 | |
|       if (SchoolWeave=="V" ||SchoolWeave=="T"  ) ModWeave = 0;
 | |
|       if (GetHasFeat(FEAT_SPELL_GIRDING, oTarget)) nGirding = 2;
 | |
|       
 | |
|       int iDice = d20(1);
 | |
|  //     SendMessageToPC(GetFirstPC(), "Spell :"+ IntToString(nEffectSpellID)+" T "+GetName(oTarget)+" C "+GetName(GetLocalObject(oTarget, " X2_Effect_Caster_" + IntToString(nIndex))));
 | |
|  //     SendMessageToPC(GetFirstPC(), "Dispell :"+IntToString(iDice + nCasterLevel)+" vs DC :"+IntToString(11 + nEffectCasterLevel+ModWeave)+" Weave :"+IntToString(ModWeave)+" "+SchoolWeave);
 | |
| 
 | |
|       if(iDice + nCasterLevel >= 11 + nEffectCasterLevel+ModWeave+nBuffer+nGirding)
 | |
|       {
 | |
|         sList += SpellName+", ";
 | |
|         oEffectCaster = GetLocalObject(oTarget, " X2_Effect_Caster_" + IntToString(nIndex));
 | |
| 
 | |
|         //:: Was going to use this function but upon reading it it became apparent it might not remove
 | |
|         //:: all of the given spells effects, but just one instead.
 | |
| 
 | |
|         //PRCRemoveSpellEffects(nEffectSpellID, oEffectCaster, oTarget);
 | |
| 
 | |
|         //:: If the check is successful, go through and remove all effects originating
 | |
|         //:: from that particular spell.
 | |
|         struct PRCeffect eToDispel = PRCGetFirstEffect(oTarget);
 | |
|         while(PRCGetIsEffectValid(eToDispel))
 | |
|         {
 | |
|           if(PRCGetEffectSpellId(eToDispel) == nEffectSpellID)
 | |
|           {
 | |
|             if(PRCGetEffectCreator(eToDispel) == oEffectCaster)
 | |
|             {
 | |
|               PRCRemoveEffect(oTarget, eToDispel);
 | |
|             }// end if struct PRCeffect comes from this caster
 | |
|           }// end if struct PRCeffect comes from this spell
 | |
|           eToDispel = PRGetNextEffect(oTarget);
 | |
|         }// end of while loop
 | |
| 
 | |
| 
 | |
| 
 | |
|         // Delete the saved references to the spell's effects.
 | |
|         // This will save some time when reordering things a bit.
 | |
|         DeleteLocalInt(oTarget, " X2_Effect_Spell_ID_" + IntToString(nIndex));
 | |
|         DeleteLocalInt(oTarget, " X2_Effect_Cast_Level_" + IntToString(nIndex));
 | |
|         DeleteLocalObject(oTarget, " X2_Effect_Caster_" + IntToString(nIndex));
 | |
|         DeleteLocalInt(oTarget, " X2_Effect_Weave_ID_" + IntToString(nIndex));
 | |
| 
 | |
|       }// end of if caster check is sucessful
 | |
|     }// end of if oTarget has effects from this spell
 | |
|   }// end of for statement
 | |
| 
 | |
| 
 | |
|   // Additional Code to dispel any infestation of maggots effects.
 | |
| 
 | |
|   // If check to take care of infestation of maggots is in effect.
 | |
|   // with the highest caster level on it right now.
 | |
|   // If it is, we remove it instead of the other effect.
 | |
|   int bHasInfestationEffects = GetLocalInt(oTarget,"XP2_L_SPELL_CASTER_LVL_" + IntToString (SPELL_INFESTATION_OF_MAGGOTS));
 | |
| 
 | |
|   if(bHasInfestationEffects)
 | |
|   {
 | |
|     ModWeave =0;
 | |
|     if (GetLocalInt(oTarget, " XP2_L_SPELL_WEAVE" +IntToString (SPELL_INFESTATION_OF_MAGGOTS)) && !Weave) ModWeave = 4;
 | |
|     
 | |
|     if(d20(1) + nCasterLevel >= bHasInfestationEffects + 11+ModWeave+nBuffer+nGirding)
 | |
|     {
 | |
|       DeleteLocalInt(oTarget,"XP2_L_SPELL_SAVE_DC_" + IntToString (SPELL_INFESTATION_OF_MAGGOTS));
 | |
|       DeleteLocalInt(oTarget,"XP2_L_SPELL_CASTER_LVL_" + IntToString (SPELL_INFESTATION_OF_MAGGOTS));
 | |
|       struct PRCeffect eToDispel = PRCGetFirstEffect(oTarget);
 | |
|       nEffectSpellID = SPELL_INFESTATION_OF_MAGGOTS;
 | |
| 
 | |
|       SpellName = GetStringByStrRef(StringToInt(lookup_spell_name(nEffectSpellID)));
 | |
|       sList += SpellName+", ";
 | |
| 
 | |
|       while(PRCGetIsEffectValid(eToDispel))
 | |
|       {
 | |
|         if(PRCGetEffectSpellId(eToDispel) == nEffectSpellID)
 | |
|         {
 | |
|           PRCRemoveEffect(oTarget, eToDispel);
 | |
|         }// end if struct PRCeffect comes from this spell
 | |
|         eToDispel = PRGetNextEffect(oTarget);
 | |
|       }// end of while loop
 | |
|     }// end if caster level check was a success.
 | |
|   }// end if infestation of maggots is in struct PRCeffect on oTarget/
 | |
| 
 | |
|   // If the loop to rid the target of the effects of infestation of maggots
 | |
|   // runs at all, this next loop won't because eToDispel has to be invalid for this
 | |
|   // loop to terminate and the other to begin - but it won't begin if eToDispel is
 | |
|   // already invalid :)
 | |
| 
 | |
|   if (sList == "") sList = "None  ";
 | |
|   sList = GetStringLeft(sList, GetStringLength(sList) - 2); // truncate the last ", "
 | |
|   
 | |
|   SendMessageToPC(OBJECT_SELF, sCast+sList);
 | |
|   if (oTarget != OBJECT_SELF) SendMessageToPC(oTarget, sSelf+sList);
 | |
| 
 | |
| }// End of function.
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////
 | |
| //:: Sorts the 3 arrays in order of highest at index 0 on up to lowest at index nLastEntry
 | |
| //////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| void SortAll3Arrays(object oTarget)
 | |
| {
 | |
| 
 | |
|     int nLastEntry = GetLocalInt(oTarget, X2_EFFECT+"Index_Number");
 | |
|     int nCurrEntry, nCurrEntry2, nCasterLvl, nCasterLvl2, nHighCastLvl, nHighestEntry;
 | |
|     struct PRCeffect eTest;
 | |
|     struct PRCeffect eTest2;
 | |
|     struct PRCeffect eHigh;
 | |
| 
 | |
|     for(nCurrEntry = 0; nCurrEntry <= nLastEntry; nCurrEntry++)
 | |
|     {
 | |
|         eTest = GetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrEntry));
 | |
|         nCasterLvl = eTest.nCasterLevel;
 | |
|         nHighCastLvl = nCasterLvl;
 | |
| 
 | |
|         for(nCurrEntry2 = nCurrEntry + 1; nCurrEntry2 <= nLastEntry; nCurrEntry2++)
 | |
|         {
 | |
|             eTest2 = GetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrEntry));
 | |
|             nCasterLvl2 = eTest.nCasterLevel;
 | |
|             if(nCasterLvl2 >= nHighCastLvl)
 | |
|             {
 | |
|                 nHighestEntry = nCurrEntry2;
 | |
|                 nHighCastLvl = nCasterLvl2;
 | |
|             }
 | |
|         }// End of second for statement.
 | |
|         
 | |
|         if(nHighCastLvl != nCasterLvl)
 | |
|         // If the entry we're currently looking at already is the highest caster level left,
 | |
|         // we leave it there.  Otherwise we swap the highest level entry with this one.
 | |
|         // nHighCastLvl will still be equal to nCasterLvl unless a higher level struct PRCeffect was found.
 | |
|         {
 | |
|             eTest = GetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrEntry));
 | |
|             eHigh = GetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nHighestEntry));
 | |
|             DeleteLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrEntry));
 | |
|             DeleteLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nHighestEntry));
 | |
|             SetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nCurrEntry), eHigh);
 | |
|             SetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nHighestEntry), eTest);
 | |
|         }  // End if the caster levels of the 2 entries are actually different.
 | |
|     }// End of first for statement.
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////////////////////
 | |
| //:: Finished sorting.
 | |
| /////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| 
 | |
| 
 | |
| /////////////////////////////////////////////////////////////////////////////////
 | |
| //:: Infestation of maggots is a special case because it won't end until a local
 | |
| //:: int is deleted.   It must be handled specially.
 | |
| /////////////////////////////////////////////////////////////////////////////////
 | |
| void HandleInfestationOfMaggots(object oTarget)
 | |
| {
 | |
|     //:: Special to trap an infestation of maggots effect.
 | |
|     int nHasInfestationEffect = GetLocalInt(oTarget, "XP2_L_SPELL_CASTER_LVL_" + IntToString (SPELL_INFESTATION_OF_MAGGOTS));
 | |
| 
 | |
|     int nLastEntry = GetLocalInt(oTarget, "X2_Effects_Index_Number");
 | |
|     if(nHasInfestationEffect)
 | |
|     {  
 | |
|         // If they have infestation of maggots on them, then add it to the end of the list.
 | |
|         // I would add it during the spell script itself but it might get swept up before the spell has
 | |
|         // really ended, I fear.
 | |
|         nLastEntry++;
 | |
|         DeleteLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nLastEntry));
 | |
| 
 | |
|         SetLocalInt(oTarget, " X2_Effect_Spell_ID_" + IntToString(nLastEntry), SPELL_INFESTATION_OF_MAGGOTS);
 | |
|         SetLocalInt(oTarget, " X2_Effect_Cast_Level_" + IntToString(nLastEntry), nHasInfestationEffect);
 | |
|         SetLocalInt(oTarget, " X2_Effect_Weave_ID_" + IntToString(nLastEntry), GetLocalInt(oTarget, " XP2_L_SPELL_WEAVE" +IntToString (SPELL_INFESTATION_OF_MAGGOTS)));
 | |
|         //:: Won't bother with this one. I think a creature can only have one infestation at a time.
 | |
|         //SetLocalObject(oTarget, " X2_Effect_Caster_" + IntToString(nLastEntry));
 | |
|         SetLocalInt(oTarget, "X2_Effects_Index_Number", nLastEntry);
 | |
|     }
 | |
| }
 | |
| //////////////////////////////////////////////////////////////////////////////////////////////
 | |
| //:: End of section to trap infestation of maggots.
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| void PRCApplyEffectToObject(int nDurationType, struct PRCeffect eEffect, object oTarget, float fDuration = 0.0f, 
 | |
|     int bDispellable = TRUE, int nSpellID = -1, int nCasterLevel = -1, object oCaster = OBJECT_SELF)
 | |
| {
 | |
|     //this should be passed in, for testing its set here
 | |
|     struct PRCeffect prceEffect;
 | |
| 
 | |
|     // Extraordinary/Supernatural effects are not supposed to be dispellable.
 | |
|     if (PRCGetEffectSubType(eEffect) == SUBTYPE_EXTRAORDINARY 
 | |
|         || PRCGetEffectSubType(eEffect) == SUBTYPE_SUPERNATURAL)
 | |
|     {
 | |
|         bDispellable = FALSE;
 | |
|     }
 | |
| 
 | |
|     // Instant duration effects can use BioWare code, the PRC code doesn't care about those
 | |
|     if (DURATION_TYPE_INSTANT == nDurationType)
 | |
|     {
 | |
|        ApplyEffectToObject(nDurationType, prceEffect.eEffect, oTarget, fDuration);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 
 | |
|         // Invoke the PRC apply function passing the extra data.
 | |
|        int nIndex = ReorderEffects(prceEffect, oTarget);
 | |
|        // Add this new struct PRCeffect to the slot after the last struct PRCeffect already on the character.
 | |
|        ApplyEffectToObject(nDurationType, prceEffect.eEffect, oTarget, fDuration);
 | |
|        // may have code travers the lists right here and not add the new effect
 | |
|        // if an identical one already appears in the list somewhere
 | |
|        SetLocalPRCEffect(oTarget, X2_EFFECT+IntToString(nIndex), prceEffect);
 | |
| 
 | |
|        //nIndex++;
 | |
|        /// Set new index number to the character.
 | |
|        SetLocalInt(oTarget, X2_EFFECT+"Index_Number", nIndex);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void PRCApplyEffectAtLocation(int nDurationType, struct PRCeffect eEffect, location lLocation, float fDuration=0.0f)
 | |
| {
 | |
|     ApplyEffectAtLocation(nDurationType, eEffect.eEffect, lLocation, fDuration);
 | |
| }
 | |
| 
 | |
| // Sets up all of the AoE's int values, but only if they aren't already set.
 | |
| // When called in a function nMetamagic should be GetMetamagicFeat(), and nBaseSaveDC should be PRCGetSaveDC()
 | |
| void SetAllAoEInts(int SpellID, object oAoE, int nBaseSaveDC ,int SpecDispel = 0 , int nCasterLevel = 0)
 | |
| {
 | |
|     if(GetLocalInt(oAoE, "X2_AoE_Is_Modified") != 1)
 | |
|     {
 | |
| 
 | |
|        // I keep making calls to GetAreaOfEffectCreator()
 | |
|        // I'm not sure if it would be better to just set it one time as an object variable
 | |
|        // It would certainly be better in terms of number of operations, but I'm not sure
 | |
|        // if it's as accurate.
 | |
|        // It's a total of 7 calls, so I figure it doesn't matter that much.  Still, 1 would be better than 7.
 | |
|        // Also: the 7 calls only happen once per casting of the AoE.
 | |
|        if ( !nCasterLevel) nCasterLevel = PRCGetCasterLevel(GetAreaOfEffectCreator());
 | |
| 
 | |
|        ActionDoCommand(SetLocalInt(oAoE, "X2_AoE_Caster_Level", nCasterLevel));
 | |
|        ActionDoCommand(SetLocalInt(oAoE, "X2_AoE_SpellID", SpellID));
 | |
|        ActionDoCommand(SetLocalInt(oAoE, "X2_AoE_Weave", GetHasFeat(FEAT_SHADOWWEAVE,GetAreaOfEffectCreator())));
 | |
|        if (SpecDispel) ActionDoCommand(SetLocalInt(oAoE, "X2_AoE_SpecDispel", SpecDispel));
 | |
|        ActionDoCommand(SetLocalInt(oAoE, "X2_AoE_Is_Modified", 1));
 | |
|     }
 | |
|  
 | |
| }
 | |
| 
 | |
| // Just returns the stored value.
 | |
| int AoECasterLevel(object oAoE = OBJECT_SELF)
 | |
| {
 | |
|    int toReturn = GetLocalInt(oAoE, "X2_AoE_Caster_Level");
 | |
|    return toReturn;
 | |
| } |