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