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.
		
			
				
	
	
		
			243 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
/*:://////////////////////////////////////////////
 | 
						|
//:: Name Concentration Include
 | 
						|
//:: FileName SMP_INC_CONCENTR
 | 
						|
//:://////////////////////////////////////////////
 | 
						|
    This holds the functions needed to recursivly call a spell script and not
 | 
						|
    do the effects.
 | 
						|
 | 
						|
    Each spell like this needs:
 | 
						|
 | 
						|
    - A seperate AOE entry
 | 
						|
    - A heartbeat for the AOE
 | 
						|
    - These two checks in the spell script
 | 
						|
    - All targets the effects are applied to, to be added to a special array
 | 
						|
      (SMP_CONCENTRATE_123_654_ARRAY_123456)
 | 
						|
 | 
						|
    Use this instead of SMP_INC_SPELLS, it has it in it.
 | 
						|
//:://////////////////////////////////////////////
 | 
						|
//:: Created By: Jasperre
 | 
						|
//:: Created On: 23 may
 | 
						|
//::////////////////////////////////////////////*/
 | 
						|
 | 
						|
#include "SMP_INC_SPELLS"
 | 
						|
 | 
						|
// SMP_INC_CONCENTR. Start concentrating
 | 
						|
// Call this in a spell which concentrates. The AOE can be used to remove effects
 | 
						|
// from targets in the Heartbeat event it uses. The AOE's location matters, and
 | 
						|
// is created here. Only use if using SMP_ConcentatingContinueCheck() before it.
 | 
						|
// ---
 | 
						|
// Remember to set the objects affected to an array of SMP_CONCENTRATING + spell ID +
 | 
						|
// times cast + array. RETURNS APPROPRATE ARRAY STRING (using TIMES CAST)
 | 
						|
// ---
 | 
						|
// * nSpellId - used for variables
 | 
						|
// * nRoundLimit - We force a limit of rounds? If so, we use this local to enforce it
 | 
						|
// * lTarget - Need to retarget at the same location for it to be a valid re-concentate
 | 
						|
// * nAOEId - The AOE to create at lTarget FOR HEARTBEAT, IMPORTANT.
 | 
						|
// * fExtraTime - How many rounds (minimum 1 second) after the effects stays
 | 
						|
// * oCaster - Creator of the spell/effect
 | 
						|
// It should create an AOE of the correct ID.
 | 
						|
// RETURNS APPROPRATE ARRAY STRING (using TIMES CAST)
 | 
						|
string SMP_ConcentatingStart(int nSpellId, int nRoundLimit, location lTarget, int nAOEId, float fExtraTime = 1.0, object oCaster = OBJECT_SELF);
 | 
						|
 | 
						|
// SMP_INC_CONCENTR. Continue concentrating - or not as the case may be.
 | 
						|
// Call this in a spell which concentrates. It should be used to check if the
 | 
						|
// spell just cast was just to concentrate some more, or not.
 | 
						|
// This will delete the local used so the AOE will go and remove everything.
 | 
						|
// ---
 | 
						|
// We will get the times cast and limits from locals
 | 
						|
// ---
 | 
						|
// * nSpellId - used for variables
 | 
						|
// * lTarget - Need to retarget at the same location for it to be a valid re-concentate
 | 
						|
// * sAOETag - Tag of the AOE.
 | 
						|
// * fExtraTime - How many rounds (minimum 1 second) after the effects stays
 | 
						|
// * oCaster - Creator of the spell/effect
 | 
						|
// TRUE if it IS a correct check and they are JUST concentrating. FALSE, and
 | 
						|
// it is a new spell.
 | 
						|
int SMP_ConcentatingContinueCheck(int nSpellId, location lTarget, string sAOETag, float fExtraTime = 1.0, object oCaster = OBJECT_SELF);
 | 
						|
 | 
						|
// SMP_INC_CONCENTR. Use in the AOE's heartbeat script.
 | 
						|
// This will:
 | 
						|
// 1 If the creator isn't valid, it will remove all effects from the spell
 | 
						|
//   created by invalid creators and then delete itself.
 | 
						|
// 2 If the variable doesn't exsist, then it will first delete all the people
 | 
						|
//   in the array and then remove itself, as well as remove the spell effects from the people
 | 
						|
void SMP_ConcentrationAOEHeartbeat(object oSelf, object oCaster, int nSpell);
 | 
						|
 | 
						|
// Start concentrating
 | 
						|
string SMP_ConcentatingStart(int nSpellId, int nRoundLimit, location lTarget, int nAOEId, float fExtraTime = 1.0, object oCaster = OBJECT_SELF)
 | 
						|
{
 | 
						|
    // Starting at 1 concentating round.
 | 
						|
    string sLocal = "SMP_CONCENTATING_" + IntToString(nSpellId);
 | 
						|
    int nConcentratingRounds = 1;
 | 
						|
    // Set round limit to override any previous
 | 
						|
    SetLocalInt(oCaster, sLocal + "LIMIT", nRoundLimit);
 | 
						|
    // Get times cast
 | 
						|
    int nReturnTimesCast = SMP_IncreaseStoredInteger(oCaster, "SMP_TIMES_CAST" + IntToString(nSpellId));
 | 
						|
 | 
						|
    // Based on Times cast
 | 
						|
    string sConcetrateLocal = sLocal + "_" + IntToString(nReturnTimesCast);
 | 
						|
 | 
						|
    // Set for this times cast it is valid to concentrate - starting rounds at 1
 | 
						|
    // Start concentation at round 1.
 | 
						|
    // - EG: SMP_CONCENTRATING_100_4, for spell 100, times cast, 4
 | 
						|
    SetLocalInt(oCaster, sConcetrateLocal, 1);
 | 
						|
 | 
						|
    // Delete it after 6.0 + fExtraTime seconds so the AOE used stop
 | 
						|
    DelayCommand(6.0 + fExtraTime, SMP_DeleteIntInTime(sLocal, oCaster, nConcentratingRounds));
 | 
						|
 | 
						|
    // Create the AOE
 | 
						|
    effect eAOE = EffectAreaOfEffect(nAOEId);
 | 
						|
    ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, eAOE, lTarget);
 | 
						|
 | 
						|
    // Do concentrating thing, another spell
 | 
						|
    ClearAllActions();
 | 
						|
    ActionCastSpellAtLocation(nSpellId, lTarget, METAMAGIC_NONE, TRUE);
 | 
						|
 | 
						|
    // End this script
 | 
						|
    // Return the ARRAY STRING to use, IE:
 | 
						|
    // sConcetrateLocal + "_ARRAY"
 | 
						|
    // so:
 | 
						|
    // "SMP_CONCENTATING_" + ID + "_" + TimesCast + "_ARRAY"
 | 
						|
    // "SMP_CONCENTATING_100_5_ARRAY"
 | 
						|
    return sConcetrateLocal + "_ARRAY";
 | 
						|
}
 | 
						|
 | 
						|
// Continue concentrating - or not as the case may be.
 | 
						|
// TRUE if it IS a correct check and they are JUST concentrating. FALSE, and
 | 
						|
// it is a new spell.
 | 
						|
int SMP_ConcentatingContinueCheck(int nSpellId, location lTarget, string sAOETag, float fExtraTime = 1.0, object oCaster = OBJECT_SELF)
 | 
						|
{
 | 
						|
    // Check they are even aiming it at the right place first
 | 
						|
    object oAOE = SMP_GetNearestObjectByTagToLocation(OBJECT_TYPE_AREA_OF_EFFECT, sAOETag, lTarget);
 | 
						|
    // Get times this spell has currently been cast
 | 
						|
    int nTimesCast = GetLocalInt(oCaster, "SMP_TIMES_CAST" + IntToString(nSpellId));
 | 
						|
    // Local used
 | 
						|
    string sLocal = "SMP_CONCENTATING" + IntToString(nSpellId);
 | 
						|
    string sConcetrateLocal = sLocal + "_" + IntToString(nTimesCast);
 | 
						|
 | 
						|
    // If the location matches the AOE there, and the AOE is by us, all is OK
 | 
						|
    if(GetDistanceBetween(oAOE, oCaster) < 0.1 &&
 | 
						|
       GetAreaOfEffectCreator(oAOE) == oCaster)
 | 
						|
    {
 | 
						|
        // ALL IS OK, we carry on as normal
 | 
						|
 | 
						|
        // We need to make sure that we have not reached the limits of the
 | 
						|
        // rounds we can concentrate for.
 | 
						|
 | 
						|
        // Get limit of times to concentrating
 | 
						|
        int nLimit = GetLocalInt(oCaster, sLocal + "LIMIT");
 | 
						|
 | 
						|
        // Increase times concentrating by 1 for this spell, for nTimesCast
 | 
						|
        // * we rely upon the fact that nTimesCast is valid.
 | 
						|
        int nConcentratingRounds = GetLocalInt(oCaster, sConcetrateLocal) + 1;
 | 
						|
 | 
						|
        // Reached the limit?
 | 
						|
        if(nConcentratingRounds < nLimit)
 | 
						|
        {
 | 
						|
            // NO, we carry on casting
 | 
						|
 | 
						|
            // Set new concentrating local for the time
 | 
						|
            SetLocalInt(oCaster, sConcetrateLocal, nConcentratingRounds);
 | 
						|
            // Delete it after 6.0 + fExtraTime seconds so the AOE used stop
 | 
						|
            DelayCommand(6.0 + fExtraTime, SMP_DeleteIntInTime(sConcetrateLocal, oCaster, nConcentratingRounds));
 | 
						|
 | 
						|
            // Do the spell cheat-casting again.
 | 
						|
            ClearAllActions();
 | 
						|
            ActionCastSpellAtLocation(nSpellId, lTarget, METAMAGIC_NONE, TRUE);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            // YES, we stop
 | 
						|
            SendMessageToPC(oCaster, "You cannot concetate anymore on this spell");
 | 
						|
            // We make sure that nConcentratingRounds for nSpellId under nTimesCast
 | 
						|
            // is invalid so the AOE works out the rest
 | 
						|
            DeleteLocalInt(oCaster, sConcetrateLocal);
 | 
						|
        }
 | 
						|
        // Return TRUE, we have either ended the concentating, or carrying on,
 | 
						|
        // but it was a valid call of it.
 | 
						|
        return TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        // We make sure that nConcentratingRounds for nSpellId under nTimesCast
 | 
						|
        // is invalid so the AOE works out the rest
 | 
						|
        DeleteLocalInt(oCaster, sConcetrateLocal);
 | 
						|
    }
 | 
						|
    // FALSE - we have a new spell on our hands. The local should mean the AOE
 | 
						|
    // that used it will delete itself.
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
// Use in the AOE's heartbeat script.
 | 
						|
// This will:
 | 
						|
// 1 If the creator isn't valid, it will remove all effects from the spell
 | 
						|
//   created by invalid creators and then delete itself.
 | 
						|
// 2 If the variable doesn't exsist, then it will first delete all the people
 | 
						|
//   in the array and then remove itself, as well as remove the spell effects from the people
 | 
						|
void SMP_ConcentrationAOEHeartbeat(object oSelf, object oCaster, int nSpell)
 | 
						|
{
 | 
						|
    // The first time this fires, we need to set nTimesCast to ourselves
 | 
						|
    int nTimesCast = GetLocalInt(oSelf, "TIMES_CAST");
 | 
						|
    if(nTimesCast == 0)
 | 
						|
    {
 | 
						|
        // Also set us to plot until WE want to go
 | 
						|
        SetPlotFlag(oSelf, TRUE);
 | 
						|
        nTimesCast = GetLocalInt(oCaster, "SMP_TIMES_CAST" + IntToString(nSpell));
 | 
						|
        SetLocalInt(oSelf, "TIMES_CAST", nTimesCast);
 | 
						|
    }
 | 
						|
 | 
						|
    // We need to get the right local - in this case, calm emotions
 | 
						|
    string sLocal = "SMP_CONCENTATING" + IntToString(nSpell);
 | 
						|
    string sConcentrationLocal = sLocal + "_" + IntToString(nTimesCast);
 | 
						|
 | 
						|
 | 
						|
    // If the creator isn't valid, it will remove all effects from the spell
 | 
						|
    // created by invalid creators and then delete itself.
 | 
						|
    if(!GetIsObjectValid(oCaster))
 | 
						|
    {
 | 
						|
        // Loop all creatures in the area and remove the spell from them
 | 
						|
        // - OBJECT_INVALID for oCreator will be fine.
 | 
						|
        SMP_RemoveAllSpellsFromCreator(nSpell, oCaster);
 | 
						|
 | 
						|
        // Destroy ourselves
 | 
						|
        SetPlotFlag(oSelf, FALSE);
 | 
						|
        DestroyObject(oSelf);
 | 
						|
    }
 | 
						|
    // If the variable doesn't exsist, then it will first delete all the people
 | 
						|
    // in the array and then remove itself.
 | 
						|
    else if(GetLocalInt(oCaster, sConcentrationLocal) == FALSE)
 | 
						|
    {
 | 
						|
        // Ok, its ended, or they cast it again, or an error - we thusly
 | 
						|
        // remove the effects from everyone in the array.
 | 
						|
        string sArray = sConcentrationLocal + "_ARRAY";
 | 
						|
        // Get max (only integer of sArray value on oCaster) and remove.
 | 
						|
        int nMax = GetLocalInt(oCaster, sArray);
 | 
						|
        DeleteLocalInt(oCaster, sArray);
 | 
						|
        int nCnt = 1;
 | 
						|
        // Make sure nMax is valid!
 | 
						|
        if(nMax > 0)
 | 
						|
        {
 | 
						|
            // Loop in the array until nMax
 | 
						|
            object oRemoveFrom = GetLocalObject(oCaster, sArray + IntToString(nCnt));
 | 
						|
            while(nCnt <= nMax)
 | 
						|
            {
 | 
						|
                // Remove it
 | 
						|
                SMP_PRCRemoveSpellEffects(nSpell, oCaster, oRemoveFrom);
 | 
						|
                // Delete from array
 | 
						|
                DeleteLocalObject(oCaster, sArray + IntToString(nCnt));
 | 
						|
                // Next one
 | 
						|
                nCnt++;
 | 
						|
                oRemoveFrom = GetLocalObject(oCaster, sArray + IntToString(nCnt));
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// End of file Debug lines. Uncomment below "/*" with "//" and compile.
 | 
						|
/*
 | 
						|
void main()
 | 
						|
{
 | 
						|
    return;
 | 
						|
}
 | 
						|
//*/
 |