4class WeaponFSM extends HFSMBase<WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase>
6 private static const int MAX_SYNCHRONIZE_ATTEMPTS = 12;
7 private static const int MIN_SYNCHRONIZE_INTERVAL = 3000;
8 private static const int RESET_SYNCHRONIZE_THRESHOLD = 3600000;
12 protected int m_NextStateId = 0;
19 state.SetInternalStateID(m_NextStateId);
22 m_UniqueStates.Insert(
state);
35 SetInternalID(
t.m_srcState);
36 SetInternalID(
t.m_dstState);
48 if (
t.m_dstState !=
NULL)
53 GetOwnerState().OnSubMachineChanged(
t.m_srcState,
t.m_dstState);
56 m_State.OnStateChanged(
t.m_srcState,
t.m_dstState);
66 GetOwnerState().OnSubMachineChanged(
t.m_srcState,
NULL);
74 if (
LogManager.
IsInventoryHFSMLogEnable())
fsmDebugPrint(
"[hfsm] (local abort) state=" +
t.m_srcState.ToString() +
"-------- ABORT event=" +
e.ToString() +
"[G=" +
t.m_guard.ToString() +
"]/A=" +
t.m_action.ToString() +
" --------|> dst=" +
t.m_dstState.ToString());
79 auto tmp =
t.m_srcState.GetParentState();
80 if (
tmp ==
t.m_dstState.GetParentState())
84 if (
t.m_dstState !=
NULL)
112 fsmDebugPrint(
"[hfsm] root::ProcessAbortEvent(" +
e.Type().ToString() +
")");
138 if (GetOwnerState() ==
abort_dst.GetParentState())
171 int i = FindFirstUnguardedTransition(
e);
183 i = FindFirstUnguardedTransition(
e);
233 fsmDebugPrint(
"[hfsm] root::ProcessEvent(" +
e.Type().ToString() +
" =" +
e.DumpToString());
237 if (m_HasCompletions)
238 ProcessCompletionTransitions();
264 int i = FindFirstUnguardedTransition(
e);
275 i = FindFirstUnguardedTransition(
e);
288 if (
row.m_srcState.GetParentState() ==
row.m_dstState.GetParentState())
289 res = LocalTransition(
i,
e);
291 Error(
"cross-hierarchy transition or misconfigured transition detected!");
297 if (
row.m_srcState.GetParentState() == GetOwnerState())
298 res = LocalTransition(
i,
e);
300 Error(
"cross-hierarchy transition or misconfigured transition detected!");
315 int state_id = m_UniqueStates.Get(
idx).GetInternalStateID();
317 return m_UniqueStates.Get(
idx);
331 int count = m_Transitions.Count();
347 Error(
"[wpnfsm] LoadCurrentFSMState - cannot read current state");
371 if (LoadAndSetCurrentFSMState(
ctx, version))
382 if (LoadAndSetCurrentFSMState(
ctx, version))
389 if (!m_UniqueStates.Get(
idx).LoadCurrentFSMState(
ctx, version))
390 Error(
"[wpnfsm] LoadCurrentUnstableFSMState - cannot load unique state " +
idx +
"/" +
state_count +
" with id=" + m_UniqueStates.Get(
idx).GetInternalStateID() +
" state=" + m_UniqueStates.Get(
idx));
413 if (!
state.SaveCurrentFSMState(
ctx))
415 Error(
"[wpnfsm] SaveCurrentFSMState - cannot save currrent state=" +
state);
437 int state_id = m_UniqueStates.Get(
idx).GetInternalStateID();
441 if (!m_UniqueStates.Get(
idx).SaveCurrentFSMState(
ctx))
442 Error(
"SaveCurrentUnstableFSMState - cannot save unique state=" + m_UniqueStates.Get(
idx) +
" idx=" +
idx +
"/" +
state_count +
" with id=" +
state_id);
445 Error(
"[wpnfsm] SaveCurrentUnstableFSMState state=" + m_UniqueStates.Get(
idx) +
" with unassigned ID!");
455 Internal_ValidateAndRepair();
476 new WeaponEventAttachMagazine,
new WeaponEventDetachMagazine,
482 new WeaponEventTriggerToJam,
new WeaponEventUnjam,
494 "ChamberFiredRepair",
495 state.IsChamberFiredOut(0),
weapon.IsChamberFiredOut(0),
496 new WeaponEventTrigger,
new WeaponEventMechanism,
502 new WeaponEventLoad1Bullet,
new WeaponEventMechanism,
512 "ChamberFiredRepair",
545 Error(
string.Format(
"[wpnfsm] ValidateAndRepair Attempting to repair: %1 - %2 - %3 - state: %4 != weapon: %5",
566 if (m_SynchronizeAttempts < MAX_SYNCHRONIZE_ATTEMPTS)
572 if (
timeDiff > MIN_SYNCHRONIZE_INTERVAL)
576 if (
timeDiff > RESET_SYNCHRONIZE_THRESHOLD)
577 m_SynchronizeAttempts = 0;
582 weapon.RandomizeFSMState();
586 ++m_SynchronizeAttempts;
604 Error(
string.Format(
"[wpnfsm] %1 ValidateAndRepair THRESHOLD BREACH - %2 - %3 - state: %4 != weapon: %5",
638 Print(
"[wpnfsm] Warning! OnStoreLoad - cannot load curent weapon state, id=" +
id);
658 return state.GetCurrentStateID();
670 Print(
"[wpnfsm] Warning! Save occured in fsm transition! GetCurrentStateID - cannot find closest weapon stable state.");
682 id =
curr.GetInternalStateID();
691 int id = GetCurrentStableStateID();
718 int tc = m_Transitions.Count();
724 if (
state.IsSingleState())
735 ErrorEx(
string.Format(
"Number of muzzles on the weapon (%1) does not correspond with what state has configured (%2).",
nMuzzles,
nMuzzlesState));
761 if (!Internal_ValidateAndRepair())
void wpnDebugSpamALot(string s)
void wpnDebugSpam(string s)
void wpnDebugPrint(string s)
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
void Start()
Plays all elements this effects consists of.
void fsmDebugSpam(string s)
void fsmDebugPrint(string s)
bool OnStoreLoad(ParamsReadContext ctx, int version)
load state of fsm
bool LoadCurrentUnstableFSMState(ParamsWriteContext ctx, int version)
override WeaponStateBase ProcessAbortEvent(WeaponEventBase e, out ProcessEventResult result)
void OnFailThresholdBreached(Weapon weapon, string name, bool stateCondition, bool gunCondition)
void RandomizeFSMStateEx(array< MuzzleState > muzzleStates, bool hasMagazine, bool isJammed)
With the parameters given, selects a random suitable state for the FSM of the weapon @NOTE: It is bet...
bool LoadAndSetCurrentFSMState(ParamsReadContext ctx, int version)
bool SaveCurrentUnstableFSMState(ParamsWriteContext ctx)
override void AddTransition(FSMTransition< WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase > t)
adds transition into transition table As a side effect registers the state(s) into m_UniqueStates
bool Internal_ValidateAndRepair()
validate the state of the gun and repair if mismatch
void RandomizeFSMState(bool hasBullet, bool hasMagazine, bool isJammed)
Deprecated, use RandomizeFSMStateEx for better results.
ProcessEventResult ProcessLocalTransition(FSMTransition< WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase > t, WeaponEventBase e)
bool SaveCurrentFSMState(ParamsWriteContext ctx)
save current state of fsm
ProcessEventResult ProcessAbortTransition(FSMTransition< WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase > t, WeaponEventBase e)
int m_LastSynchronizeTime
void SetInternalID(WeaponStateBase state)
unique list of states in this machine (automation of save/load)
bool LoadCurrentFSMState(ParamsReadContext ctx, int version)
load current state of fsm
bool ValidateAndRepairHelper(Weapon_Base weapon, string name, bool stateCondition, bool gunCondition, WeaponEventBase e1, WeaponEventBase e2, out WeaponStableState state)
WeaponStableState FindStableStateForID(int id)
load from database - reverse lookup for state from saved id
int m_SynchronizeAttempts
int GetCurrentStableStateID()
WeaponStateBase FindStateForInternalID(int id)
retrieve base state that matches given internal id
void OnStoreSave(ParamsWriteContext ctx)
save state of fsm
WeaponStableState ValidateAndRepairStateFinder(bool condition, WeaponEventBase e1, WeaponEventBase e2, WeaponStableState state)
void ValidateAndRepair()
validate the state of the gun and repair if mismatch
override ProcessEventResult ProcessEvent(WeaponEventBase e)
base class for hierarchic finite state machine
static bool IsWeaponLogEnable()
static bool IsInventoryHFSMLogEnable()
Serialization general interface. Serializer API works with:
signalize mechanism manipulation
weapon finite state machine
script counterpart to engine's class Weapon
represents weapon's stable state (i.e. the basic states that the weapon will spend the most time in)
represent weapon state base
void Error(string err)
Messagebox with error message.
proto void Print(void var)
Prints content of variable to console/log.
static proto int RandomInt(int min, int max)
Returns a random int number between and min [inclusive] and max [exclusive].