Scriptname WeaponRackTriggerSCRIPT extends ObjectReference Hidden ;Modifications by Sclerocephalus - debug version 3.4 (10/21/2013) ;modified by taleden - rev 4 (2013-11-01) ;Modifications by DayDreamer - version 5.0 (2014 Mar 15) import game import debug import utility ;------------------------------------------- Keyword Property WRackActivator Auto ;The activator we must disable if there is already something in this trigger ObjectReference Property ActivatorRef Auto Hidden ;/// ;Reference that is currently in the trigger ObjectReference Property RefCurrentlyInTrig Auto Hidden ;1 = if something is in this trigger, 0 = empty Bool Property HasBeenTriggered Auto Hidden Int Property numInTrig Auto Hidden ///; Bool Property AlreadyInit Auto Hidden Bool Property IgnoreArmor = FALSE Auto ;------------------------------------------- ;*** USKP Properties *** Keyword Property ArmorShield Auto ;------------------------------------------- ;*** USKP Variables *** WeaponRackActivateScript ActivatorScript = None ;/------------------------------------------ Handle mis-configured triggers. Returns False for success. /; Bool Function CheckConfiguration(String CallingEvent) GoToState("ActivatorBusy") If WRackActivator == None ; script was deleted, properties missing ;~ Trace(Self + CallingEvent + "() CHECK: WRackActivator == None; 'ActivatorBusy' state.") Return True EndIf ActivatorRef = GetLinkedRef(WRackActivator) If ActivatorRef == Self ; hand fixed, don't disable ;~ Trace(Self + CallingEvent + "() CHECK: WRackActivator == Self; 'ActivatorBusy' state.") ActivatorRef = None Return True EndIf If ActivatorRef == None Trace(Self + CallingEvent + "() ERROR: missing WRackActivator; 'ActivatorBusy' state.") Return True EndIf ActivatorScript = ActivatorRef As WeaponRackActivateScript If ActivatorScript == None Trace(Self + CallingEvent + "() ERROR: missing WeaponRackActivateScript; 'ActivatorBusy' state.") ActivatorRef = None Return True EndIf If isDisabled() GoToState("TriggerDisabled") ActivatorRef.DisableNoWait() ;~ Trace(Self + CallingEvent + "() CHECK: is disabled; set 'TriggerDisabled' state; " + ActivatorRef + " disabled too.") ActivatorRef = NONE ActivatorScript = NONE Return True EndIf Return False EndFunction ;------------------------------------------- EVENT OnCellDetach(); replace OnReset() AlreadyInit = FALSE endEVENT ;/------------------------------------------ This event must be present to catch extant USKP 2.0.0 racks, or otherwise without known state. This is present solely for backward compatibility. /; EVENT OnCellAttach(); replace OnCellLoad() TriggerSetup("Trigger:OnCellAttach") endEVENT ;/------------------------------------------ This state must be present to catch extant USKP 1.3.3 racks. (1) The activator is known to be missing, but can be resuscitated. (2) The activator status is currently being tested. Suppress redundant OnLoad() and trigger events. (3) The activator is either enabled (and the rack empty, so the trigger won't be needed anyway) or running a placement procedure. OnTriggerLeave() events during placement are from adjacent racks ("cross-activation") or from a temporary loss of the item's 3D during a MoveToNode command. Skip them to prevent the items from being mis-interpreted as having been grabbed from the rack. /; STATE ActivatorBusy EVENT OnCellAttach() endEVENT EVENT OnLoad() endEVENT EVENT OnTriggerLeave(ObjectReference ItemRef) ;~ Trace(Self + "ActivatorBusy:OnTriggerLeave() " + ItemRef + "; Base = " + ItemRef.GetBaseObject()) endEVENT endSTATE ;/------------------------------------------ This state must be present to catch extant USKP 2.0.1 racks. The activator has been detected by OnCellAttach(), this trigger is currently disabled. Allows OnLoad() to setup. /; STATE TriggerDisabled EVENT OnCellAttach() endEVENT ;/ Catch newly enabled racks with player present. Starting items must be done upon constructing the rack at a workbench in a player home. OnCellAttach() does not fire. /; EVENT OnLoad() If Self == None Trace(Self + "OnLoad() ERROR!") return EndIf Cell parentCell = GetParentCell() If parentCell == None Trace(Self + "OnLoad() ERROR: GetParentCell == None") return EndIf If !parentCell.IsAttached() Trace(Self + "OnLoad() ERROR: parentCell=" + parentCell + " !IsAttached()") return EndIf TriggerSetup("TriggerDisabled:OnLoad") endEVENT EVENT OnTriggerLeave(ObjectReference ItemRef) ;~ Trace(Self + "TriggerDisabled:OnTriggerLeave() " + ItemRef + "; Base = " + ItemRef.GetBaseObject()) endEVENT endSTATE ;/------------------------------------------ This is a vanilla state and must be present to catch extant vanilla racks. However, the contents have been significantly revised. /; auto STATE WaitingForReference ;/ Catch newly enabled racks without player present. Previously placed items must be renewed on every cell attach, re-adjusting to current game mesh defined nodes. /; EVENT OnCellAttach() TriggerSetup("WFR:OnCellAttach") endEVENT EVENT OnLoad() endEVENT ;/ It would be nice if we could filter out spurious events fired by bouncing clutter etc, but we can't call any native methods on triggerRef such as GetBaseObject() -- if the retrieved item was scripted, then by the time this runs it may already be in the player's inventory and our pointer will be broken. So we'll have to make do with just comparing the pointer itself to our other stored pointers. --taleden /; EVENT OnTriggerLeave(objectReference triggerRef) If CheckConfiguration("WFR:OnTriggerLeave") return EndIf ; state ActivatorBusy If !ActivatorRef.IsDisabled() ;~ Trace(Self + "OnTriggerLeave() CHECK: activator was enabled; 'ActivatorBusy' state.") ActivatorRef = NONE ActivatorScript = NONE return EndIf If ActivatorScript.RackWasTriggered(triggerRef, GetTriggerObjectCount()) GoToState("WaitingForReference") ;~ Trace(Self + "OnTriggerLeave() retain 'WaitingForReference' state.") EndIf ActivatorRef = NONE ActivatorScript = NONE endEVENT endSTATE ;/------------------------------------------ TriggerSetup() CheckConfiguration() immediately changes state, suppressing OnLoad() and trigger events. Called from OnLoad() and OnCellAttach() both here and there. /; Function TriggerSetup(String CallingEvent) Bool wasHandled = AlreadyInit AlreadyInit = True If wasHandled ;~ Trace(Self + CallingEvent + "() TriggerSetup() was handled.") Return EndIf If CheckConfiguration(CallingEvent) Return EndIf ; state ActivatorBusy ;~ Trace(Self + CallingEvent + "() " + ActivatorRef + " update setup.") ActivatorScript.ActivatorSetup(CallingEvent) ActivatorRef = NONE ActivatorScript = NONE EndFunction