diff --git a/scripts/trapswingingwall.pex b/scripts/trapswingingwall.pex new file mode 100644 index 00000000..a4a4fc90 Binary files /dev/null and b/scripts/trapswingingwall.pex differ 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 + + + + +