Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
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;
|
|
}
|
|
//*/
|