From b5ef32f9a32eb6b1240ccd09677b827b0a572fc7 Mon Sep 17 00:00:00 2001 From: Eddoursul Date: Mon, 20 Dec 2021 01:13:21 +0100 Subject: [PATCH] Added Subhuman0100's fix for TrapSwingingWall, preventing infinite loop in background --- scripts/trapswingingwall.pex | Bin 0 -> 4732 bytes source/scripts/trapswingingwall.psc | 233 ++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 scripts/trapswingingwall.pex create mode 100644 source/scripts/trapswingingwall.psc diff --git a/scripts/trapswingingwall.pex b/scripts/trapswingingwall.pex new file mode 100644 index 0000000000000000000000000000000000000000..a4a4fc90431685139271e8dfac9270c6a2cb72c4 GIT binary patch literal 4732 zcmai1S#KNH75;`IMTxc+OR{9kaXgM&$8j8ol2?r_C*JK=u~Ny7(lr^ASK>sY8FpqU zn%&|gbzRq60whI?7AOkzwM9{&2->FteJZ-48@fE?p?%ID$cy{kdwFLl#Z7rE@|<(e z`rUKyj6YcT)q7nzSm5X7_xoPN$mPhb&o{kbiT@T{-``)4D=5T`tF;D-bBCTfaJXE? zn;1-J7q{)2v}1st^CFo~+(e-Fe3*oq?GJ;?k+-xYqO(CFB4qN6a90I3&IYH2@1IN( zw^BpTq8ABS0yfTxSR^yviYL8F^CG!YKN)x{F^XZJ*07-x230Td!oc;>UGu6{5uo&3 zxXRL1j3LMI0vfpf8R5IFmsZ^fg>!!BCfMRQmz&|dSQSCiI>)3kwle6RPa+0D_vDfC zxiG?jHmG96m|SrE#dNWIsw`zZ+FA8Og2lzzvFLhb~iQR!KbE3s23 zDhbOXy@4JBJ4$M^H2URr8~6V)99VZ1U@YCHb^F(^EzMcz7@<^Ek`tqE8uYInSL~E) zx*pk}TD4uDTUaIB^0vfKHalr|!&tPowm zz`AQ48#|vN$X^P1`xhN25i9jWhB=IZ@aij~lFW%k5ea$Yv`vm+gWTMjmt1vYJ{fuM zGQbOb67k%6@l5DeMO8l|V!RcnJ$a~&S zYHmUdy`)kTF(pp2E=e_76Lwq|6>rhw!6g!WNcRMyIj^`<81VAcJj>S1#xOV~_!gk0 z$JgeGMAC=?nMT-^M#PSpTg7U(ebn?ng&vL7L^ROT66EW=&9KRF7QCR^sLzLuK*LsSB%bdjE##Xn?fA@JB6T-mq}OJ zBp14YA$%TRAiYFdR8)f|56kdL0ZAGcfrD5@lXQ*rDz1}W!|S9sNH_3J(k;@Pcq^s1 z@iyKeeH-5;eGlKq4@f`6j}-kFKfzD&^OWAjyZ8luNsv*j!-gHfX6EKcBRqyJQXr&Tjm0>&8TJuIY=?LhJ39UB)NiM;cnrG?`!Rex zUEgh#k7JKvpTJ(jK8byXeG2wgX}Ot&$Fex6i^f$F93moyS#%te^_Pv%AElA)3_+R>{Iu3-%~~2G3lMBym zSKTHuJ3Od zEqu+wtH#tqzXpTF>@Q$I1-@ReOz1A^Un^Lt4fk9ppJoQukQhU`Gn8va9;8{5F)24? z?h@r|y5?(Y!&utus->0`a~Aek82(TrZ>Y?&im?K?`t{7kvT#gQt*gte>n#6_%xa;< z!JyeRxsk314<5YFifS@tAGOOWsIEhm#X1}dN7)ShWHYL|t|8UTX6XjK)=bwvl=nI~ zV9fME+M?PehCX58ux`=JKKJT|1{e8kbS!*>1Czr|^$Z(DfjMtd$(%P8cK(wyL|js&;L?SrYkJyT{=7`8Ud`yJumCLYKkrNv4}^aUv%8!wuQV zpJNub^5?jPZ7SXX-R`&D?RHSP^>n!9*0~L8x82%pyLQ{9tEXTW Gtp5VydHj|D literal 0 HcmV?d00001 diff --git a/source/scripts/trapswingingwall.psc b/source/scripts/trapswingingwall.psc new file mode 100644 index 00000000..55862875 --- /dev/null +++ b/source/scripts/trapswingingwall.psc @@ -0,0 +1,233 @@ +scriptName TrapSwingingWall extends MovingTrap +; +; +;This is the script for the blade trap +;Activating the trap causes it to toggle on and off +;If activated while in the process of stopping, it should be able to handle that. +;================================================================ + +import debug +import utility + +;If Loop is true, it swings until activated again. +;If Loop is false, it swings once when activated. +bool restartLooping = false +bool finishedPlaying = false +bool hasPlayedAttackAnimOnce = FALSE +float property initialDelay = 0.25 auto + +string property fireAnim = "90For" auto hidden +{firing animation, should not need to change} +string property fireEvent = "Done" auto hidden +{firing animation event, should not need to change} +string property resetAnim = "90Back" auto hidden +{reset animation, should not need to change} +string property resetEvent = "TransStop" auto hidden +{reset animation event, should not need to change} +string property startSwungAnim = "90End" auto hidden +{anim event to start already swung} +string property rearmAnim = "Rearm" Auto hidden + +string property rearmEvent = "TransStart" Auto hidden + +string property HalfAnim = "90Half" auto hidden +string property HalfAnimEvent = "TransHalf" Auto hidden + +string property NinetyFireAnim = "90For" auto hidden +string property NinetyResetAnim = "90Back" auto hidden +string property NinetyStartSwungAnim = "90End" auto hidden +string property NinetyHalfAnim = "90Half" auto hidden + +string property OneEightyFireAnim = "180For" auto hidden +string property OneEightyResetAnim = "180Back" auto hidden +string property OneEightyStartSwungAnim = "180End" auto hidden +string property OneEightyHalfAnim = "180Half" auto hidden + +string property TwoSeventyFireAnim = "270For" auto hidden +string property TwoSeventyResetAnim = "270Back" auto hidden +string property TwoSeventyStartSwungAnim = "270End" auto hidden +string property TwoSeventyHalfAnim = "270Half" auto hidden + + +bool property startSwung = false auto +{set to true to start swung} +bool property animsSetUp = false auto hidden + +int property actorsInTrigger = 0 auto hidden +int property rotation = 0 Auto +{This property sets how far to rotate + 0 == 90 degrees + 1 == 180 degrees + 2 == 270 degrees +Anything else will fail and trap will default to 90 degrees} + + +;----------------------------------- + +;This block tracks entering objects to prevent the player +;or other live actor from being trapped behind the wall +Event onTriggerEnter(objectReference TriggerRef) +; debug.Trace(self + " has been entered by " + TriggerRef) + if TriggerRef as Actor ;&& !(TriggerRef as actor).isDead() + actorsInTrigger += 1 + endif +; debug.Trace(self + ":actorsInTrigger = " + actorsInTrigger) +endEvent + +Event onTriggerLeave(objectReference TriggerRef) +; debug.Trace(self + " has been entered by " + TriggerRef) +;/ subhuman - you know what the problem with removing the IsDead() check is, Bethesda? A corpse can turn the + trap on, but it never gets turned off because corpse cleanup isn't an OnTriggerLeave event! /; + if TriggerRef as Actor ;&& !(TriggerRef as actor).isDead() +; actorsInTrigger -= 1 +; subhuman - sanity check to prevent negative values + if actorsInTrigger > 0 + actorsInTrigger -= 1 + endif + endif +; debug.Trace(self + ":actorsInTrigger = " + actorsInTrigger) +endEvent + +;Load block used for handing state when going from cell to cell +EVENT OnCellAttach() + isLoaded = TRUE + if !AnimsSetUp + SetUpAnims() + endif +;/ subhuman - WTF? Dead code commented out. If AnimsSetUp was false, then SetUpAnims() was called TWO LINES + ABOVE THIS! Before SetUpAnims() finishes and lets this function resume executing, it set AnimsSetUp to + true.... /; +;/ while !AnimsSetUp + endWhile/; + hitBase = (self as objectReference) as TrapHitBase + + if isFiring || startSwung + if startSwung + ;isFiring == True + loop = True + goToState("On") + endif + fireTrap() + endif +endEVENT + +Function fireTrap() + + ;Basic wind up and fire once checking + ;TRACE("fireTrap called") + isFiring = True + if !AnimsSetUp + SetUpAnims() + endif +;/ subhuman - WTF? Dead code commented out. If AnimsSetUp was false, then SetUpAnims() was called TWO LINES + ABOVE THIS! Before SetUpAnims() finishes and lets this function resume executing, it set AnimsSetUp to + true.... /; +;/ while !AnimsSetUp + endWhile/; + ResolveLeveledDamage() + if !startSwung + hitBase.goToState("CanHit") + WindupSound.play( self as ObjectReference) ;play windup sound + wait( initialDelay ) ;wait for windup + endif + hasPlayedAttackAnimOnce = FALSE + ;TRACE("Initial Delay complete") + + if (fireOnlyOnce == True) ;If this can be fired only once then disarm + trapDisarmed = True + endif + + ;TRACE("Looping =") + ;TRACE(Loop) + + ;Trap Guts + finishedPlaying = False + while !finishedPlaying && isLoaded + ;trace(self + "Firing trap: playanimation(" + fireAnim + ")") + ;trace(self + "Firing trap: waiting for event(" + fireEvent + ")") + if !hasPlayedAttackAnimOnce + if !startSwung + PlayAnimationAndWait(fireAnim, fireEvent) +; ;debug.Trace(self + "has finished anim once") +; hasPlayedAttackAnimOnce = TRUE + hitBase.goToState("CannotHit") + else + startSwung = False + playAnimation(startSwungAnim) +; hasPlayedAttackAnimOnce = TRUE + endif + hasPlayedAttackAnimOnce = TRUE + Else + wait(0.5) + endif +; subhuman - ok, this was just asinine. A function call for what should be setting a simple bool... + finishedPlaying = !loop +;/ finishedPlaying = True + + if loop ;Reset Limiter +; ;debug.Trace(self + "is looping because loop = " + loop) + resetLimiter() + endif /; + endWhile + + if isLoaded + isFiring = false + ;debug.Trace(self + " is playing " + resetAnim + " & waiting for " + resetEvent) + PlayAnimationAndWait(resetAnim, resetEvent) + ;debug.Trace(self + " has recieved anim event " + resetEvent) +;/ subhuman - added isLoaded check to while loop so it will stop when the OnUnload() event + sets isLoaded to false. Encountered at least one case where the PC left the dungeon, and + this was still looping days later. /; + while isLoaded && (actorsInTrigger > 0) + ;debug.Trace(self + ":actorsInTrigger = " + actorsInTrigger) + utility.wait(1.0) + EndWhile + PlayAnimationAndWait(rearmAnim, rearmEvent) + goToState("Reset") + endif + ;trace(self + "Reset trap: playanimation(" + resetAnim + ")") + ;trace(self + "Reset trap: waiting for event(" + resetEvent + ")") + + +endFunction + +Function ResetLimiter() + finishedPlaying = False + ;TrapHitBase hitBase = (self as objectReference) as TrapHitBase + ;hitBase.goToState("CanHit") +EndFunction + +Function SetUpAnims() + if rotation == 0 + ;set anims to 90 degree variants + fireAnim = NinetyFireAnim + resetAnim = NinetyResetAnim + startSwungAnim = NinetyStartSwungAnim + halfAnim = NinetyHalfAnim + ElseIf rotation == 1 + ;set anims to 180 degree variants + fireAnim = OneEightyFireAnim + resetAnim = OneEightyResetAnim + startSwungAnim = OneEightyStartSwungAnim + halfAnim = OneEightyHalfAnim + ElseIf rotation == 2 + ;set anims to 270 degree variants + fireAnim = TwoSeventyFireAnim + resetAnim = TwoSeventyResetAnim + startSwungAnim = TwoSeventyStartSwungAnim + halfAnim = TwoSeventyHalfAnim +; Else +; debug.Trace(self + " has been set to an incorrect rotation value of " + rotation) + endif + animsSetUp = True +endFunction + +Event onReset() + self.reset() + goToState("Idle") +endEvent + + + + +