Scriptname MineOreFurnitureScript extends ObjectReference Conditional {script for furniture which the player can use to get resources} objectReference property lastActivateRef auto Hidden {tracks the last triggeringRef} bool property isRegisteredForEvents = false auto hidden {bool to track if this is registered for events} bool property canBeActivated = true auto hidden idle property PickaxeExit auto bool property playerIsLeavingFurniture = false auto hidden Actor Property PlayerREF Auto ;=================================================================== ;;EVENT BLOCK ;=================================================================== Event OnLoad() BlockActivation(true) If !PlayerREF ; Just in case PlayerREF = Game.GetPlayer() EndIf if isFurnitureInUse() goToState("busy") endif endEvent Event OnUnload() ; safety measures If !PlayerREF ; Just in case PlayerREF = Game.GetPlayer() EndIf UnregisterForEvents() lastActivateRef = None playerIsLeavingFurniture = False endEvent Event OnAnimationEvent(ObjectReference akSource, string asEventName) ; debug.trace(self + ": animation event received = " + asEventName) ;if the animation event we've recieved is addToInventory activate our mineOreVein with ;the furniture as the activator to tell it to pay out ore if asEventName == "AddToInventory" ;PlayerREF.AddItem(Resource, ResourceCount) lastActivateRef.activate(self) endif if asEventName == "IdleFurnitureExit" || asEventName == "IdlePickaxeExit" || asEventName == "IdlePickaxeFloorExit" || asEventName == "IdlePickaxeTableExit" UnregisterForEvents(True) endif endEvent ;=================================================================== ;;STATE BLOCK ;=================================================================== auto STATE normal event onBeginState() canBeActivated = true ; debug.Trace(self + " is in state normal") endEvent Event OnActivate(ObjectReference akActionRef) if canBeActivated ; gotoState must be before canBeActivated = False because onBeginState in "busy" resets the flag gotoState("busy") canBeActivated = False ; debug.trace(self + ", normal: OnActivate by " + akActionRef) if akActionRef == PlayerREF && !isFurnitureInUse() ; debug.trace(self + ", normal: was activated by the player in state normal, furniture not in use") RegisterForEvents() Activate(akActionRef, true) elseif akActionRef == PlayerREF ; debug.Trace(self + ", normal: has been activated by the player while in use") ;just activate it ;goToState("busy") Activate(akActionRef, true) ; debug.trace(self + ", normal: NPC activation END") else ;goToState("busy") Activate(akActionRef, true) ; debug.trace(self + ", normal: NPC (other) activation END") endif canBeActivated = true endif endEvent endState STATE busy ; do nothing event onBeginState() canBeActivated = True endEvent event onActivate(objectReference akActionRef) If isFurnitureInUse() If canBeActivated canBeActivated = False ; debug.Trace(self + ", busy: has recieved activation in busy state from " + akActionRef) if isRegisteredForEvents if lastActivateRef && akActionRef == lastActivateRef ; debug.Trace(self + ", busy: is trying to kick player out of furniture") ; PlayerREF.PlayIdle(PickaxeExit) ; Activate(PlayerREF, true) playerIsLeavingFurniture = True goToState("reseting") elseif akActionRef == PlayerREF ; debug.Trace(self + ", busy: player is trying to leave furniture") ; PlayerREF.PlayIdle(PickaxeExit) ; Activate(PlayerREF, true) playerIsLeavingFurniture = True goToState("reseting") endif elseif akActionRef == PlayerREF ; debug.trace(self + ", busy: player is trying to leave furniture, not registered for events") Activate(PlayerREF, true) else ; debug.trace(self + ", busy: player is trying to leave furniture, not registered for events") ;Activate(akActivator, true) endif canBeActivated = true EndIf Else ; not in use If akActionRef == PlayerREF ; debug.trace(self + ", busy: activated by the player, furniture not in use") RegisterForEvents() Activate(akActionRef, true) endif EndIf endEvent endState state reseting event onBeginState() ; debug.Trace(self + ", reseting: onBeginState START") if playerIsLeavingFurniture playerIsLeavingFurniture = false PlayerREF.PlayIdle(PickaxeExit) else UnregisterForEvents(True) endif ;Activate(PlayerREF, true) ;UnregisterForEvents() endEvent event onActivate(objectReference akActionRef) ; UnregisterForEvents() endEvent endState state Depleted event onBeginState() isRegisteredForEvents = True ; Force unregister UnregisterForEvents() endEvent event onActivate(objectReference akActionRef) ; debug.Trace(self + ": has recieved activation in state Depleted from " + akActionRef) endEvent endState ;=================================================================== ;;FUNCTION BLOCK ;=================================================================== function goToDepletedState() goToState("Depleted") endFunction function RegisterForEvents() ; centralize this if !isRegisteredForEvents isRegisteredForEvents = True RegisterForAnimationEvent(PlayerREF, "AddToInventory") RegisterForAnimationEvent(PlayerREF, "IdlePickaxeExit") RegisterForAnimationEvent(PlayerREF, "IdlePickaxeFloorExit") RegisterForAnimationEvent(PlayerREF, "IdlePickaxeTableExit") RegisterForAnimationEvent(PlayerREF, "IdleFurnitureExit") endif endFunction function UnregisterForEvents(Bool bNotifyLastActivateRef = False) ; centralize this ; It is perfectly safe to unregister for events you never registered for, however ; this function is called as part of OnUnload, and if this object isn't persistent ; then it may be deleted by the time OnUnload runs, and these function calls will ; fail. Since RegisterForAnimationEvent persists us, we know it will be safe to ; call Unregister if we've previously Registered, even if called as a part of ; OnUnload ; debug.Trace(self + " is attempting to unregister for anim events") if isRegisteredForEvents isRegisteredForEvents = false UnRegisterForAnimationEvent(PlayerREF, "AddToInventory") UnRegisterForAnimationEvent(PlayerREF, "IdlePickaxeExit") UnRegisterForAnimationEvent(PlayerREF, "IdlePickaxeFloorExit") UnRegisterForAnimationEvent(PlayerREF, "IdlePickaxeTableExit") UnRegisterForAnimationEvent(PlayerREF, "IdleFurnitureExit") If bNotifyLastActivateRef && lastActivateRef (lastActivateRef as MineOreScript).OnFurnitureExit() EndIf ; debug.Trace(self + " should be unregistered for anim events") endif gotoState("normal") canBeActivated = True endFunction