Added Subhuman0100's fix for TrapSwingingWall, preventing infinite loop in background

This commit is contained in:
Eddoursul 2021-12-20 01:13:21 +01:00
parent 2edfd9c09c
commit b5ef32f9a3
2 changed files with 233 additions and 0 deletions

Binary file not shown.

View File

@ -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