#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()); }