123 lines
6.0 KiB
Plaintext
123 lines
6.0 KiB
Plaintext
#include "x2_inc_spellhook"
|
|
//::////////////////////////////////////////////////////:://
|
|
//:: Invizible420's Alternate <span class="highlight">Timestop</span> Spell //:://
|
|
//:: //:://
|
|
//:: By: Invizible420 //:://
|
|
//:: Modified By: Shayan //:://
|
|
//:: (Created 12/20/02 updated 12/08/04 (v 2.0) //:://
|
|
//::////////////////////////////////////////////////////:://
|
|
//:: //:://
|
|
//:: Persistent World Workaround for Bioware's //:://
|
|
//:: Default <span class="highlight">Timestop</span> Spell. This will Decrease //:://
|
|
//:: Attack and Movement Speed, then CutSceneDominate //:://
|
|
//:: creatures within a radius of the caster. //:://
|
|
//:: //:://
|
|
//:: This version now uses the module to dominate the //:://
|
|
//:: the creatures, this stops PC from dominating //:://
|
|
//:: other PC's. Also added a fix to not dominate //:://
|
|
//:: a caster's familiars. //:://
|
|
//:: //:://
|
|
//:: Contact info/Bug Reports: Digiddy777@yahoo.com //:://
|
|
//::////////////////////////////////////////////////////:://
|
|
#include "NW_I0_GENERIC"
|
|
float iInterval = 6.0; //the minimum time gap between casting Tmestops simulataneously.
|
|
// Customize User Defined Variables
|
|
float fDur = IntToFloat(d4(4)); // Duration in seconds //max is 16 seconds
|
|
float fDist = 50.0; // Radius in meters
|
|
int iSlow = 100; // Percentage to decrease movement by
|
|
int iDAttack = 100; // Amount to decrease attack by
|
|
|
|
// Has item in inventory to avoid the effects of a time stop.
|
|
int GetIsTimeStopImmune(object oCreature) {
|
|
return (GetResRef(GetItemInSlot(INVENTORY_SLOT_CLOAK, oCreature)) == "sha_tsimmuneclok");
|
|
}
|
|
|
|
//Sends a message to all PCs and DMs in the area indicating that creature that did not freeze for
|
|
// Timestop is infact immune to it.
|
|
void SendTSImmuneMessageToPCs(object TSImmune)
|
|
{
|
|
object oArea = GetArea(OBJECT_SELF);
|
|
object oObj = GetFirstObjectInShape(SHAPE_SPHERE, fDist, GetSpellTargetLocation(), FALSE, OBJECT_TYPE_CREATURE);
|
|
while(GetIsObjectValid(oObj))
|
|
{
|
|
if(GetIsPC(oObj) || GetIsDM(oObj))
|
|
{
|
|
SendMessageToPC(oObj, GetName(TSImmune) + " is immune to Time Stop.");
|
|
}
|
|
oObj = GetNextObjectInShape(SHAPE_SPHERE, fDist, GetSpellTargetLocation(), FALSE, OBJECT_TYPE_CREATURE);
|
|
}
|
|
}
|
|
// Function to resume creature(s) previous actions wrapped for Delay
|
|
void ResumeLast(object oResumee, object oIntruder)
|
|
{
|
|
// Delay DetermineCombatRound
|
|
DelayCommand(fDur+0.25,AssignCommand(oResumee,DetermineCombatRound(oIntruder)));
|
|
}
|
|
// Function to control <span class="highlight">TimeStop</span> effects
|
|
void TSEffects(object oEffector, object oCaster)
|
|
{
|
|
// Check if stopped creature is a hostile
|
|
if (GetIsReactionTypeHostile(oCaster,oEffector) == TRUE && !GetIsPC(oEffector)) {
|
|
// Start the resume combat round after <span class="highlight">Timestop</span>
|
|
ResumeLast(oEffector, oCaster);
|
|
}
|
|
// Decrease the creature(s) attack
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectAttackDecrease(iDAttack,ATTACK_BONUS_MISC),oEffector,fDur);
|
|
// <span class="highlight">Stop</span> the creature(s) from moving for fDur seconds
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneImmobilize(),oEffector,fDur);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneParalyze(),oEffector,fDur);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,SupernaturalEffect(EffectVisualEffect(VFX_DUR_FREEZE_ANIMATION)),oEffector,fDur);
|
|
|
|
// Make module dominate the creature(s) for fDur seconds
|
|
// AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneDominated(),oEffector,fDur));
|
|
// Clear the creature(s) action que
|
|
AssignCommand(oEffector,ClearAllActions(TRUE));
|
|
// Disable Commandable (actions que)
|
|
SetCommandable(FALSE,oEffector);
|
|
// Enable Commandable after fDur
|
|
DelayCommand(fDur,SetCommandable(TRUE,oEffector));
|
|
}
|
|
// Function to get creature(s) within radius and apply the alternate <span class="highlight">TimeStop</span>
|
|
void TimeStop(object oTarget)
|
|
{
|
|
object oNearestC; // Define nearest creature
|
|
// Begin loop to find all creatures within the fDist meter radius
|
|
oNearestC = GetFirstObjectInShape(SHAPE_SPHERE, fDist, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE);
|
|
while(GetIsObjectValid(oNearestC))
|
|
{
|
|
// To make sure it doesn't <span class="highlight">stop</span> the caster or caster's familiar
|
|
string sNCName = GetName(oNearestC);
|
|
if (oNearestC != oTarget)
|
|
{
|
|
int TSImmune = GetIsTimeStopImmune(oNearestC);
|
|
if((oNearestC != OBJECT_SELF) && !TSImmune)
|
|
{
|
|
// Start the <span class="highlight">TimeStop</span> effects
|
|
DelayCommand(0.75,TSEffects(oNearestC,oTarget));
|
|
}
|
|
else if((oNearestC != OBJECT_SELF) && TSImmune)
|
|
{
|
|
SendTSImmuneMessageToPCs(oNearestC);
|
|
}
|
|
|
|
}
|
|
// Get the next creature in the fDist meter radius and continue loop
|
|
oNearestC = GetNextObjectInShape(SHAPE_SPHERE, fDist, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE);
|
|
}
|
|
}
|
|
// Begin Main Function
|
|
void main()
|
|
{
|
|
//Sorcerer Anti timestop spam code. (referred to in j_inc_generic_ai)
|
|
//Thanks to Valve O' Leen
|
|
if(!GetIsPC(OBJECT_SELF) && !GetIsDM(OBJECT_SELF))
|
|
{
|
|
SetLocalInt(OBJECT_SELF, "SPELL_TS_CAST", TRUE);
|
|
DelayCommand(fDur + iInterval, DeleteLocalInt(OBJECT_SELF, "SPELL_TS_CAST"));
|
|
}
|
|
//Signal event to start the <span class="highlight">TimeStop</span>
|
|
SignalEvent(OBJECT_SELF, EventSpellCastAt(OBJECT_SELF, SPELL_TIME_STOP, FALSE));
|
|
TimeStop(OBJECT_SELF);
|
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_TIME_STOP), GetSpellTargetLocation());
|
|
}
|