DayZ 1.27
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
WeaponFSM.c
См. документацию.
4class WeaponFSM extends HFSMBase<WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase>
5{
6 private static const int MAX_SYNCHRONIZE_ATTEMPTS = 12;
7 private static const int MIN_SYNCHRONIZE_INTERVAL = 3000; // ms
8 private static const int RESET_SYNCHRONIZE_THRESHOLD = 3600000; // ms
11
12 protected int m_NextStateId = 0;
14
15 protected void SetInternalID(WeaponStateBase state)
16 {
17 if (state && state.GetInternalStateID() == -1)
18 {
20
21 //if (LogManager.IsWeaponLogEnable()) { wpnDebugSpam("[wpnfsm] " + Object.GetDebugName(m_weapon) + " unique state=" + state + " has id=" + m_NextStateId); }
22 m_UniqueStates.Insert(state);
24 }
25 }
26
32 {
33 super.AddTransition(t);
34
35 SetInternalID(t.m_srcState);
36 SetInternalID(t.m_dstState);
37 }
38
40 {
41 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] (local) state=" + t.m_srcState.ToString() + "-------- event=" + e.ToString() + "[G=" + t.m_guard.ToString() +"]/A=" + t.m_action.ToString() + " --------|> dst=" + t.m_dstState.ToString());
42
43 if (t.m_action)
44 t.m_action.Action(e); // 2) execute transition action (if any)
45
46 m_State = t.m_dstState; // 3) change state to new
47
48 if (t.m_dstState != NULL)
49 {
50 m_State.OnEntry(e); // 4a) call onEntry on new state
51
52 if (GetOwnerState())
53 GetOwnerState().OnSubMachineChanged(t.m_srcState, t.m_dstState); // 5a) notify owner state about change in submachine
54
55 if (m_State)
56 m_State.OnStateChanged(t.m_srcState, t.m_dstState); // 5b) notify current state about change in machine
57
59 return ProcessEventResult.FSM_OK;
60 }
61 else
62 {
63 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] terminating fsm: state=" + t.m_srcState.ToString() + " event=" + e.ToString());
64
65 if (GetOwnerState())
66 GetOwnerState().OnSubMachineChanged(t.m_srcState, NULL); // 5) notify owner state about change in submachine
68 return ProcessEventResult.FSM_TERMINATED; // 4b) or terminate
69 }
70 }
71
73 {
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());
75
76 if (t.m_action)
77 t.m_action.Action(e); // 2) execute transition action (if any)
78
79 auto tmp = t.m_srcState.GetParentState();
80 if (tmp == t.m_dstState.GetParentState())
81 {
82 m_State = t.m_dstState; // 3) change state to new (or NULL)
83
84 if (t.m_dstState != NULL)
85 {
86 m_State.OnEntry(e); // 4a1) call onEntry on new state (see 4a2) )
88 return ProcessEventResult.FSM_OK;
89 }
90 else
91 {
92 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] abort & terminating fsm: state=" + t.m_srcState.ToString() + " event=" + e.ToString());
93
94 return ProcessEventResult.FSM_TERMINATED; // 4b) or terminate
95 }
96 }
97 else
98 {
99 m_State = NULL;
101 return ProcessEventResult.FSM_ABORTED; // 4c) or signal abort to parent (with appropriate transition)
102 }
103 }
104
106 {
108 {
109 if (GetOwnerState())
110 fsmDebugPrint("[hfsm] SUB! " + GetOwnerState().Type().ToString() + "::ProcessAbortEvent(" + e.Type().ToString() + ")");
111 else
112 fsmDebugPrint("[hfsm] root::ProcessAbortEvent(" + e.Type().ToString() + ")");
113 }
114
115 // 1) look in submachine first (if any)
116 if (m_State && m_State.HasFSM())
117 {
119 ProcessEventResult subfsm_res;
120 WeaponStateBase abort_dst = a.ProcessAbortEvent(e, subfsm_res);
121
122 switch (subfsm_res)
123 {
124 case ProcessEventResult.FSM_OK:
125 {
126 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] event processed by sub machine=" + m_State.ToString());
127
128 result = subfsm_res; // 1.1) submachine accepted event
130 return NULL;
131 }
132 case ProcessEventResult.FSM_ABORTED:
133 {
134 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] aborted sub machine=" + m_State.ToString());
135
136 m_State.OnAbort(e); // 1.2) submachine aborted, abort submachine owner (i.e. this)
137
138 if (GetOwnerState() == abort_dst.GetParentState())
139 {
140 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] aborted sub machine=" + m_State.ToString() + " & abort destination reached.");
141
142 m_State = abort_dst;
143 m_State.OnEntry(e); // 1.3) submachine aborted, call onEntry on new state (cross-hierarchy transition)
144 result = ProcessEventResult.FSM_OK;
146 return NULL;
147 }
148 else
149 {
150 result = ProcessEventResult.FSM_ABORTED; // 1.4) submachine has aborted, look for destination state in parent
152 return NULL;
153 }
154
155 break;
156 }
157 case ProcessEventResult.FSM_TERMINATED:
158 {
159 break; // submachine has finished, look for local transitions from exited submachine
160 }
161 case ProcessEventResult.FSM_NO_TRANSITION:
162 {
163 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] aborted (but no transition) sub machine=" + m_State.ToString());
164
165 break; // submachine has no transition, look for transitions in local machine
166 }
167 }
168 }
169
170 // 2) local transitions
171 int i = FindFirstUnguardedTransition(e);
172 if (i == -1)
173 {
174 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] abort event has no transition: src=" + m_State.ToString() + " e=" + e.Type().ToString());
175
176 result = ProcessEventResult.FSM_NO_TRANSITION;
178 return NULL;
179 }
180
181 m_State.OnAbort(e);
182
183 i = FindFirstUnguardedTransition(e);
184 if (i == -1)
185 {
186 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] abort event has no transition: src=" + m_State.ToString() + " e=" + e.Type().ToString());
187
188 result = ProcessEventResult.FSM_NO_TRANSITION;
190 return NULL;
191 }
192
195 result = res;
196 switch (res)
197 {
198 case ProcessEventResult.FSM_OK:
199 {
200 //if (LogManager.IsWeaponLogEnable()) fsmDebugSpam("[hfsm] abort event processed by machine=" + m_State.ToString());
202 return NULL; // machine accepted event
203 }
204 case ProcessEventResult.FSM_ABORTED:
205 {
206 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] aborted sub machine=" + m_State.ToString() + " will fall-through to dst=" + t.m_dstState);
207
209 return t.m_dstState; // store destination state for parent(s)
210 }
211
212 case ProcessEventResult.FSM_TERMINATED:
213 {
214 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] aborted & terminated sub machine=" + m_State.ToString());
215
216 break; // submachine has finished, look for local transitions from exited submachine
217 }
218 case ProcessEventResult.FSM_NO_TRANSITION:
219 {
220 break; // submachine has no transition, look for transitions in local machine
221 }
222 }
223 return NULL;
224 }
225
227 {
229 {
230 if (GetOwnerState())
231 fsmDebugPrint("[hfsm] SUB!::" + GetOwnerState().Type().ToString() + "::ProcessEvent(" + e.Type().ToString() + ")");
232 else
233 fsmDebugPrint("[hfsm] root::ProcessEvent(" + e.Type().ToString() + " =" + e.DumpToString());
234 }
235
236 // 1) completion transitions have priority (if any)
237 if (m_HasCompletions)
238 ProcessCompletionTransitions();
239
240 // 2) submachine then (if any)
241 if (m_State && m_State.HasFSM())
242 {
243 ProcessEventResult subfsm_res = m_State.ProcessEvent(e);
244
245 switch (subfsm_res)
246 {
247 case ProcessEventResult.FSM_OK:
248 {
249 if (LogManager.IsWeaponLogEnable()) fsmDebugSpam("[hfsm] event processed by sub machine=" + m_State.ToString());
250 return subfsm_res; // submachine accepted event
251 }
252 case ProcessEventResult.FSM_TERMINATED:
253 {
254 break; // submachine has finished, look for local transitions from exited submachine
255 }
256 case ProcessEventResult.FSM_NO_TRANSITION:
257 {
258 break; // submachine has no transition, look for transitions in local machine
259 }
260 }
261 }
262
263 // 3) local transitions
264 int i = FindFirstUnguardedTransition(e);
265 if (i == -1)
266 {
267 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] event has no transition: src=" + m_State.ToString() + " e=" + e.Type().ToString());
268
269 return ProcessEventResult.FSM_NO_TRANSITION;
270 }
271
272 m_State.OnExit(e);
273
274 // 3.5) find correct transition after handled exit
275 i = FindFirstUnguardedTransition(e);
276 if (i == -1)
277 {
278 if (LogManager.IsInventoryHFSMLogEnable()) fsmDebugPrint("[hfsm] event has no transition: src=" + m_State.ToString() + " e=" + e.Type().ToString());
279
280 return ProcessEventResult.FSM_NO_TRANSITION;
281 }
282
285 if (row.m_dstState != NULL)
286 {
287 // this is regular transition
288 if (row.m_srcState.GetParentState() == row.m_dstState.GetParentState())
289 res = LocalTransition(i, e); // transition is within this state machine
290 else
291 Error("cross-hierarchy transition or misconfigured transition detected!");
292 //res = HierarchicTransition(i, e); // transition has to cross hierarchy
293 }
294 else
295 {
296 // this is terminating transition
297 if (row.m_srcState.GetParentState() == GetOwnerState())
298 res = LocalTransition(i, e); // terminating transition is within this state machine
299 else
300 Error("cross-hierarchy transition or misconfigured transition detected!");
301 //res = HierarchicTransition(i, e); // source node crosses hierarchy (terminate lies always within this machine)
302 }
303 return res;
304 }
305
311 {
312 int state_count = m_UniqueStates.Count();
313 for (int idx = 0; idx < state_count; ++idx)
314 {
315 int state_id = m_UniqueStates.Get(idx).GetInternalStateID();
316 if (state_id == id)
317 return m_UniqueStates.Get(idx);
318 }
319 return null;
320 }
321
327 {
328 if (id == 0)
329 return null;
330
331 int count = m_Transitions.Count();
332 for (int i = 0; i < count; ++i)
333 {
334 WeaponTransition trans = m_Transitions.Get(i);
335 WeaponStableState state = WeaponStableState.Cast(trans.m_srcState);
336 if (state && id == state.GetCurrentStateID())
337 return state;
338 }
339 return null;
340 }
341
342 protected bool LoadAndSetCurrentFSMState(ParamsReadContext ctx, int version)
343 {
344 int curr_state_id = -1;
345 if (!ctx.Read(curr_state_id))
346 {
347 Error("[wpnfsm] LoadCurrentFSMState - cannot read current state");
348 return false;
349 }
350
351 WeaponStateBase state = FindStateForInternalID(curr_state_id);
352 if (state)
353 {
354 Terminate();
355 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] synced current state=" + state + " id=" + curr_state_id); }
356 m_State = state;
357 Start(null, true);
358 return true;
359 }
360 else
361 Error("[wpnfsm] LoadCurrentFSMState - cannot find state for id=" + curr_state_id);
362 return false;
363
364 }
365
370 {
371 if (LoadAndSetCurrentFSMState(ctx, version))
372 {
373 bool res = m_State.LoadCurrentFSMState(ctx, version);
374 if (LogManager.IsWeaponLogEnable()) { wpnDebugSpam("[wpnfsm] LoadCurrentFSMState - loaded current state=" + GetCurrentState()); }
375 return res;
376 }
377 return false;
378 }
379
381 {
382 if (LoadAndSetCurrentFSMState(ctx, version))
383 {
384 // read all substates
385 int state_count = m_UniqueStates.Count();
386 for (int idx = 0; idx < state_count; ++idx)
387 {
388 if (LogManager.IsWeaponLogEnable()) { wpnDebugSpam("[wpnfsm] LoadCurrentUnstableFSMState " + idx + "/" + state_count + " id=" + m_UniqueStates.Get(idx).GetInternalStateID() + " state=" + m_UniqueStates.Get(idx)); }
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));
391 }
392 return true;
393 }
394 return false;
395 }
396
401 {
402 WeaponStateBase state = GetCurrentState();
403 int curr_state_id = state.GetInternalStateID();
404 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] SaveCurrentFSMState - saving current state=" + GetCurrentState() + " id=" + curr_state_id); }
405
406 if (!ctx.Write(curr_state_id))
407 {
408 Error("[wpnfsm] SaveCurrentFSMState - cannot save curr_state_id=" + curr_state_id);
409 return false;
410 }
411
412 // write only current state
413 if (!state.SaveCurrentFSMState(ctx))
414 {
415 Error("[wpnfsm] SaveCurrentFSMState - cannot save currrent state=" +state);
416 return false;
417 }
418 return true;
419 }
420
422 {
423 WeaponStateBase state = GetCurrentState();
424 int curr_state_id = state.GetInternalStateID();
425 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] SaveCurrentUnstableFSMState - saving current state=" + GetCurrentState() + " id=" + curr_state_id); }
426
427 if (!ctx.Write(curr_state_id))
428 {
429 Error("[wpnfsm] SaveCurrentFSMState - cannot save curr_state_id=" + curr_state_id);
430 return false;
431 }
432
433 // write all substates
434 int state_count = m_UniqueStates.Count();
435 for (int idx = 0; idx < state_count; ++idx)
436 {
437 int state_id = m_UniqueStates.Get(idx).GetInternalStateID();
438 if (state_id != -1)
439 {
440 if (LogManager.IsWeaponLogEnable()) { wpnDebugSpam("[wpnfsm] SaveCurrentUnstableFSMState " + idx + "/" + state_count + " id=" + state_id + " name=" + m_UniqueStates.Get(idx)); }
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);
443 }
444 else
445 Error("[wpnfsm] SaveCurrentUnstableFSMState state=" + m_UniqueStates.Get(idx) + " with unassigned ID!");
446 }
447 return true;
448 }
449
457
463 {
464 bool repaired = false;
465
466 // Only repair stable states
468 if (state && state.IsRepairEnabled())
469 {
470 Weapon_Base weapon = state.m_weapon;
471 if (weapon)
472 {
473 repaired |= ValidateAndRepairHelper(weapon,
474 "MagazineRepair",
475 state.HasMagazine(), ( weapon.GetMagazine(0) != null ),
476 new WeaponEventAttachMagazine, new WeaponEventDetachMagazine,
477 state);
478
479 repaired |= ValidateAndRepairHelper(weapon,
480 "JammedRepair",
481 state.IsJammed(), weapon.IsJammed(),
482 new WeaponEventTriggerToJam, new WeaponEventUnjam,
483 state);
484
485 if (weapon.IsJammed())
486 return repaired;
487
488 int nMuzzles = weapon.GetMuzzleCount();
489 switch (nMuzzles)
490 {
491 case 1:
492 {
493 repaired |= ValidateAndRepairHelper(weapon,
494 "ChamberFiredRepair",
495 state.IsChamberFiredOut(0), weapon.IsChamberFiredOut(0),
496 new WeaponEventTrigger, new WeaponEventMechanism,
497 state);
498
499 repaired |= ValidateAndRepairHelper(weapon,
500 "ChamberRepair",
501 state.IsChamberFull(0), weapon.IsChamberFullEx(0),
502 new WeaponEventLoad1Bullet, new WeaponEventMechanism,
503 state);
504
505 break;
506 }
507 default:
508 {
509 for (int i = 0; i < nMuzzles; ++i)
510 {
511 repaired |= ValidateAndRepairHelper(weapon,
512 "ChamberFiredRepair",
513 state.IsChamberFiredOut(i), weapon.IsChamberFiredOut(i),
514 null, null, // A bit brute forced, not really any clean way to transition
515 state);
516
517 repaired |= ValidateAndRepairHelper(weapon,
518 "ChamberRepair",
519 state.IsChamberFull(i), weapon.IsChamberFull(i),
520 null, null, // A bit brute forced, not really any clean way to transition
521 state);
522 }
523
524 break;
525 }
526 }
527 }
528 }
529
530 return repaired;
531 }
532
533 protected bool ValidateAndRepairHelper(Weapon_Base weapon, string name, bool stateCondition, bool gunCondition, WeaponEventBase e1, WeaponEventBase e2, out WeaponStableState state)
534 {
535 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + weapon.GetDebugName(weapon) + " ValidateAndRepair - " + name + " - " + m_State + " - state: " + stateCondition + " & weapon: " + gunCondition); }
536
537 if (stateCondition != gunCondition)
538 {
539 WeaponStableState repairedState;
540
541 // Seeing this message is not TOO bad, it just means this system is working
542 // It is simply being listed in the logs to identify how much the FSM state and weapon state still desyncs
543 // Which can be because of a myriad of causes, such as incorrectly set up transitions
544 // Or simply certain timings of certain actions or interrupts lined up perfectly, which can have repro rates such as 1/300
545 Error(string.Format("[wpnfsm] ValidateAndRepair Attempting to repair: %1 - %2 - %3 - state: %4 != weapon: %5",
546 weapon.GetDebugName(weapon), name, m_State, stateCondition, gunCondition));
547
548 if (e1 && e2)
549 repairedState = ValidateAndRepairStateFinder(gunCondition, e1, e2, state);
550
551 if (repairedState)
552 {
553 Terminate();
554 m_State = repairedState;
555 Start(null, true);
556 state = repairedState;
557 weapon.SyncSelectionState(state.HasBullet(), state.HasMagazine());
558 repairedState.SyncAnimState();
559
560 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + weapon.GetDebugName(weapon) + " ValidateAndRepair - " + name + " - Result - " + m_State); }
561 return true;
562 }
563 else
564 {
565 // Last ditch effort
567 {
568 int currentTime = g_Game.GetTime();
569 int timeDiff = currentTime - m_LastSynchronizeTime;
570
571 // Careful with calling synchronize
572 if (timeDiff > MIN_SYNCHRONIZE_INTERVAL)
573 {
574 // If a lot of time passed since last attempt
575 // There is a possibility the weapon was fixed for a period
576 if (timeDiff > RESET_SYNCHRONIZE_THRESHOLD)
578
579 // Only call this on server or in SP
580 // Synchronize will ask the server for its FSM state anyways
581 if (g_Game.IsServer())
582 weapon.RandomizeFSMState();
583
584 weapon.Synchronize();
585
587 m_LastSynchronizeTime = currentTime;
588 }
589 }
590 else
591 {
592 OnFailThresholdBreached(weapon, name, stateCondition, gunCondition);
593 }
594 }
595 }
596
597 return false;
598 }
599
600 protected void OnFailThresholdBreached(Weapon weapon, string name, bool stateCondition, bool gunCondition)
601 {
602 // Now seeing THIS one, after the one above, THIS one CAN be bad
603 // As the state was identified as being desynced with the actual weapon state
604 // But the system was unable to fix it, so the weapon is now working improperly or not at all
605 // There is even the possibility that this weapon is now permanently broken
606 Error(string.Format("[wpnfsm] %1 ValidateAndRepair THRESHOLD BREACH - %2 - %3 - state: %4 != weapon: %5",
607 weapon.GetDebugName(weapon), name, m_State, stateCondition, gunCondition));
608
609 // At this point might even consider just deleting the weapon :c
610 }
611
613 {
614 WeaponStateBase interState;
615 if (condition)
616 interState = FindTransitionState(state, e1);
617 else
618 interState = FindTransitionState(state, e2);
619
620 WeaponEventBase e = new WeaponEventHumanCommandActionFinished;
621 return WeaponStableState.Cast(FindGuardedTransitionState(interState, e));
622 }
623
627 bool OnStoreLoad(ParamsReadContext ctx, int version)
628 {
629 int id = 0;
630 ctx.Read(id);
632 if (state)
633 {
634 Terminate();
635 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] OnStoreLoad - loading current state=" + state + " id=" + id); }
636 m_State = state;
637 Start(null, true);
638 }
639 else
640 {
641 Print("[wpnfsm] Warning! OnStoreLoad - cannot load curent weapon state, id=" + id);
642 }
643
644 return true;
645 }
646
658 {
659 // 1) if current state is stable state then return ID directly
660 WeaponStableState state = WeaponStableState.Cast(GetCurrentState());
661 if (state)
662 return state.GetCurrentStateID();
663
664 // 2) otherwise find closest stable state (by looking on abort event)
665 WeaponStateBase abort_dst = FindAbortDestinationState(new WeaponEventHumanCommandActionAborted(null));
666 WeaponStableState closest_stable_state = WeaponStableState.Cast(abort_dst);
667
668 if (closest_stable_state)
669 {
670 Print("[wpnfsm] Save occured in fsm transition! current state=" + GetCurrentState() + " closes stable state=" + closest_stable_state + " id=" + closest_stable_state.GetCurrentStateID());
671 return closest_stable_state.GetCurrentStateID();
672 }
673
674 Print("[wpnfsm] Warning! Save occured in fsm transition! GetCurrentStateID - cannot find closest weapon stable state.");
675 return 0;
676 }
677
682 {
683 WeaponStateBase curr = GetCurrentState();
684 int id = 0;
685 if (curr)
686 id = curr.GetInternalStateID();
687 return id;
688 }
689
694 {
695 int id = GetCurrentStableStateID();
696 if (LogManager.IsWeaponLogEnable()) { wpnDebugSpamALot("[wpnfsm] OnStoreSave - saving current state=" + GetCurrentState() + " id=" + id); }
697 ctx.Write(id);
698 }
699
703 void RandomizeFSMState(bool hasBullet, bool hasMagazine, bool isJammed)
704 {
705 array<MuzzleState> muzzleStates;
706 if (hasBullet)
707 muzzleStates = { MuzzleState.L };
708 else
709 muzzleStates = { MuzzleState.E };
710
711 RandomizeFSMStateEx(muzzleStates, hasMagazine, isJammed);
712 }
713
719 void RandomizeFSMStateEx(array<MuzzleState> muzzleStates, bool hasMagazine, bool isJammed)
720 {
722 int tc = m_Transitions.Count();
723 foreach (WeaponTransition trans : m_Transitions)
724 {
725 WeaponStableState state = WeaponStableState.Cast(trans.m_srcState);
726
727 if (state && candidates.Find(state) == INDEX_NOT_FOUND && state.HasMagazine() == hasMagazine && state.IsJammed() == isJammed)
728 {
729 if (state.IsSingleState())
730 {
731 // There is only one, insert it and stop
732 candidates.Insert(state);
733 break;
734 }
735
736 int nMuzzles = muzzleStates.Count();
737 int nMuzzlesState = state.GetMuzzleStateCount();
738 if (nMuzzles != nMuzzlesState)
739 {
740 ErrorEx(string.Format("Number of muzzles on the weapon (%1) does not correspond with what state has configured (%2).", nMuzzles, nMuzzlesState));
741 continue;
742 }
743
744 bool equal = true;
745 for (int i = 0; i < nMuzzles; ++i)
746 {
747 if (muzzleStates[i] != state.GetMuzzleState(i))
748 {
749 equal = false;
750 break;
751 }
752 }
753
754 if (equal)
755 candidates.Insert(state);
756 }
757 }
758
759 int cc = candidates.Count();
760 if (cc)
761 {
762 int randomIndex = Math.RandomInt(0, cc);
763 WeaponStableState selected = candidates.Get(randomIndex);
764 Terminate();
765 m_State = selected;
767 Start(null, true);
768 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] RandomizeFSMState - randomized current state=" + m_State + " id=" + selected.GetCurrentStateID()); }
769 selected.SyncAnimState();
770 }
771 else
772 {
773 if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] RandomizeFSMState - warning - cannot randomize, no states available"); }
774 }
775 }
776};
777
void wpnDebugSpamALot(string s)
Определения Debug.c:25
void wpnDebugSpam(string s)
Определения Debug.c:17
void wpnDebugPrint(string s)
Определения Debug.c:9
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
DayZGame g_Game
Определения DayZGame.c:3868
void Start()
Plays all elements this effects consists of.
Определения Effect.c:155
proto string ToString()
ProcessEventResult
Определения FSMBase.c:41
void fsmDebugSpam(string s)
Определения HFSMBase.c:9
void fsmDebugPrint(string s)
Определения HFSMBase.c:1
string Type
Определения JsonDataContaminatedArea.c:11
enum EObjectTemperatureState m_State
enum FSMTransition WeaponTransition
MuzzleState
Определения WeaponStableState.c:15
represents transition src -— event[guard]/action -—|> dst
bool LoadCurrentUnstableFSMState(ParamsWriteContext ctx, int version)
Определения WeaponFSM.c:380
override WeaponStateBase ProcessAbortEvent(WeaponEventBase e, out ProcessEventResult result)
Определения WeaponFSM.c:105
void RandomizeFSMState(bool hasBullet, bool hasMagazine, bool isJammed)
Deprecated, use RandomizeFSMStateEx for better results.
Определения WeaponFSM.c:703
void OnFailThresholdBreached(Weapon weapon, string name, bool stateCondition, bool gunCondition)
Определения WeaponFSM.c:600
bool LoadAndSetCurrentFSMState(ParamsReadContext ctx, int version)
Определения WeaponFSM.c:342
bool SaveCurrentFSMState(ParamsWriteContext ctx)
save current state of fsm
Определения WeaponFSM.c:400
ProcessEventResult ProcessLocalTransition(FSMTransition< WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase > t, WeaponEventBase e)
Определения WeaponFSM.c:39
ProcessEventResult ProcessAbortTransition(FSMTransition< WeaponStateBase, WeaponEventBase, WeaponActionBase, WeaponGuardBase > t, WeaponEventBase e)
Определения WeaponFSM.c:72
bool LoadCurrentFSMState(ParamsReadContext ctx, int version)
load current state of fsm
Определения WeaponFSM.c:369
void SetInternalID(WeaponStateBase state)
unique list of states in this machine (automation of save/load)
Определения WeaponFSM.c:15
bool ValidateAndRepairHelper(Weapon_Base weapon, string name, bool stateCondition, bool gunCondition, WeaponEventBase e1, WeaponEventBase e2, out WeaponStableState state)
Определения WeaponFSM.c:533
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
Определения WeaponFSM.c:31
ref array< WeaponStateBase > m_UniqueStates
counter for InternalID: each state in a fsm is assigned an unique number
Определения WeaponFSM.c:13
WeaponStableState FindStableStateForID(int id)
load from database - reverse lookup for state from saved id
Определения WeaponFSM.c:326
WeaponStateBase FindStateForInternalID(int id)
retrieve base state that matches given internal id
Определения WeaponFSM.c:310
bool Internal_ValidateAndRepair()
validate the state of the gun and repair if mismatch
Определения WeaponFSM.c:462
WeaponStableState ValidateAndRepairStateFinder(bool condition, WeaponEventBase e1, WeaponEventBase e2, WeaponStableState state)
Определения WeaponFSM.c:612
void OnStoreSave(ParamsWriteContext ctx)
save state of fsm
Определения WeaponFSM.c:693
override ProcessEventResult ProcessEvent(WeaponEventBase e)
Определения WeaponFSM.c:226
void ValidateAndRepair()
validate the state of the gun and repair if mismatch
Определения WeaponFSM.c:453
bool OnStoreLoad(ParamsReadContext ctx, int version)
load state of fsm
Определения WeaponFSM.c:627
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...
Определения WeaponFSM.c:719
base class for hierarchic finite state machine
static bool IsWeaponLogEnable()
Определения Debug.c:718
static bool IsInventoryHFSMLogEnable()
Определения Debug.c:668
Определения Debug.c:594
Определения EnMath.c:7
proto bool Write(void value_out)
proto bool Read(void value_in)
shorthand
Определения BoltActionRifle_Base.c:6
string DumpToString()
Определения Events.c:62
signalize mechanism manipulation
Определения Events.c:35
weapon finite state machine
script counterpart to engine's class Weapon
Определения InventoryItem.c:49
override bool IsJammed()
Определения Crossbow.c:33
override int GetCurrentStateID()
Определения Crossbow.c:30
override bool IsRepairEnabled()
Определения Crossbow.c:34
override bool HasMagazine()
Определения Crossbow.c:32
represents weapon's stable state (i.e. the basic states that the weapon will spend the most time in)
Определения Crossbow.c:27
int GetInternalStateID()
Определения WeaponStateBase.c:32
WeaponStateBase GetParentState()
Определения WeaponStateBase.c:26
void SetInternalStateID(int i)
Определения WeaponStateBase.c:31
override bool SaveCurrentFSMState(ParamsWriteContext ctx)
Определения RifleChambering.c:74
represent weapon state base
Определения BulletHide.c:2
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
const int INDEX_NOT_FOUND
Определения gameplay.c:13
Serializer ParamsReadContext
Определения gameplay.c:15
Serializer ParamsWriteContext
Определения gameplay.c:16
void Error(string err)
Messagebox with error message.
Определения EnDebug.c:90
proto void Print(void var)
Prints content of variable to console/log.
enum ShapeType ErrorEx
static proto int RandomInt(int min, int max)
Returns a random int number between and min [inclusive] and max [exclusive].