diff --git a/scripts/critter.pex b/scripts/critter.pex index 9606e155..4c64affc 100644 Binary files a/scripts/critter.pex and b/scripts/critter.pex differ diff --git a/source/scripts/critter.psc b/source/scripts/critter.psc index 340ac3f9..b6e10efa 100644 --- a/source/scripts/critter.psc +++ b/source/scripts/critter.psc @@ -77,6 +77,7 @@ objectReference property hunter auto hidden {if being hunted, by whom?} bool bKilled = false ; if been killed once, don't do Die() a second time +bool bAttached = false ;---------------------------------------------- ; Properties set by the spawner @@ -229,9 +230,18 @@ Event OnUpdateGameTime() DisableAndDelete(false) endEvent +Event OnLoad() + bAttached = true +endEvent + +Event OnUnload() + bAttached = false +endEvent + ;/ Match OnCellDetach() for all critters, to clean up old critters [USKP 2.0.1] /; EVENT OnCellAttach() + bAttached = true ;~ Trace(self + "OnCellAttach() had failed to kill self OnCellDetach", 2) ; kick the OnUpdate in hopes it will clean up. RegisterForSingleUpdate(0.70711); [USKP 2.0.3] @@ -249,6 +259,7 @@ endEVENT ; duplicate code from various critters moved here. [USKP 2.0.3] /; EVENT OnCellDetach() + bAttached = false ;~ Trace(self + "OnCellDetach() Killing self", 2) ;! DisableAndDelete() ; Parentcell usually removed by the time this event triggers, @@ -273,6 +284,7 @@ endEVENT Event OnInit() ; We know default properties are good bDefaultPropertiesInitialized = true + bAttached = true ; If everything else is also good, start doing stuff CheckStateAndStart() endEvent @@ -307,7 +319,7 @@ Function SetSpawnerProperties() fSpawnerX = Spawner.X fSpawnerY = Spawner.Y fSpawnerZ = Spawner.Z - PlayerRef = Game.GetPlayer() + PlayerRef = Game.GetForm(0x14) as Actor endFunction Function SetPositionVariance(float xVar, float yVar, float minZVar, float maxZVar) @@ -387,6 +399,14 @@ endFunction ; This should be called when a critter is too far from the player to be seen for instance Function DisableAndDelete(bool abFadeOut = true) bKilled = true ; BUGFIX BY STEVE40+USKP + + ; vanilla code doesn't have this variable. Use it to detect + ; earlier partially disabled/deleted critters, and also as the + ; StopNowWeReallyMeanIt flag! The advantage over isDisabled() is + ; non-interruptible idempotent run-time testing. + PlayerRef = None + + UnregisterForUpdate() if bCalculating && abFadeOut ; interlock [UKSP 2.0.3] @@ -395,6 +415,8 @@ Function DisableAndDelete(bool abFadeOut = true) return endif + UnregisterForUpdateGameTime() + if bDeleting ; interlock [UKSP 2.0.1] ;~ TraceStack(self + " bDeleting true") @@ -414,11 +436,6 @@ Function DisableAndDelete(bool abFadeOut = true) DisableNoWait() endIf - ; vanilla code doesn't have this variable. Use it to detect - ; earlier partially disabled/deleted critters, and also as the - ; StopNowWeReallyMeanIt flag! The advantage over isDisabled() is - ; non-interruptible idempotent run-time testing. - PlayerRef = None ; Stop Any movement CurrentMovementState = "Idle" @@ -471,12 +488,6 @@ Function DisableAndDelete(bool abFadeOut = true) ; STEVE40+USKP fix persistent reference to deleted object dummyMarker = none - ; StopTranslation must be called before UnregisterForUpdate, - ; because OnCritterGoalFailed() can now RegisterForSingleUpdate() - ; Unregister for any kind of update - UnregisterForUpdate() - UnregisterForUpdateGameTime() - ; And delete ourselves ;~ Debug.Trace("Critter " + self + " will kill itself.") ; Delete must be called, is not dependent on parent cell [USKP 1.3.3] @@ -1030,7 +1041,9 @@ endEvent Event OnTranslationFailed() ; Trigger event ; Debug.Trace("Critter " + self + " Translation Failed", 1) - OnCritterGoalFailed() + if bAttached && ! bKilled + OnCritterGoalFailed() + endif endEvent ; Debugging @@ -1116,7 +1129,7 @@ endFunction /; Bool Function CheckCellAttached(ObjectReference AnyItemRef) - if ! AnyItemRef + if ! bAttached || ! AnyItemRef return false endif