humaninventorywithfsm.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * @class HumanInventoryWithFSM
  3. * @brief HumanInventory... with FSM (synchronous, no anims)
  4. **/
  5. class HumanInventoryWithFSM : HumanInventory
  6. {
  7. protected ref HandFSM m_FSM; /// hand slot state machine
  8. protected ref HandStateBase m_Empty;
  9. protected ref HandStateBase m_Equipped;
  10. void HumanInventoryWithFSM ()
  11. {
  12. m_FSM = new HandFSM();
  13. }
  14. void CreateStableStates ()
  15. {
  16. // stable states are created only if they do not exist already (for example created by derived class like DayZPlayerInventory)
  17. // @NOTE: this cannot be done in constructor, as there is NO owner set yet. GetManOwner() will therefore return NULL.
  18. if (!m_Empty)
  19. m_Empty = new HandStateEmpty(GetManOwner());
  20. if (!m_Equipped)
  21. m_Equipped = new HandStateEquipped(GetManOwner());
  22. }
  23. override void Init ()
  24. {
  25. // setup state machine
  26. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[hndfsm] Initializing Human Inventory FSM");
  27. // basic states
  28. CreateStableStates();
  29. // events
  30. HandEventBase __T__ = new HandEventTake;
  31. HandEventBase __D__ = new HandEventDrop;
  32. HandEventBase __Tw_ = new HandEventThrow;
  33. HandEventBase __M__ = new HandEventMoveTo;
  34. HandEventBase __W__ = new HandEventSwap;
  35. HandEventBase __F__ = new HandEventForceSwap;
  36. HandEventBase __X__ = new HandEventDestroy;
  37. HandEventBase __Xd_ = new HandEventDestroyed;
  38. HandEventBase __R__ = new HandEventDestroyAndReplaceWithNew;
  39. HandEventBase __Re_ = new HandEventDestroyAndReplaceWithNewElsewhere;
  40. HandEventBase __Rh_ = new HandEventDestroyElsewhereAndReplaceWithNewInHands;
  41. HandEventBase __Rd_ = new HandEventReplaced;
  42. HandEventBase __Cd_ = new HandEventCreated;
  43. HandEventBase _fin_ = new HandEventHumanCommandActionFinished;
  44. HandEventBase _abt_ = new HandEventHumanCommandActionAborted;
  45. HandReplacingItemInHands replacing = new HandReplacingItemInHands(GetManOwner());
  46. HandReplacingItemInHands replacingElsewhere = new HandReplacingItemInHands(GetManOwner());
  47. HandReplacingItemElsewhereWithNewInHands replacingElsewhere3 = new HandReplacingItemElsewhereWithNewInHands(GetManOwner());
  48. // setup transitions
  49. m_FSM.AddTransition(new HandTransition( m_Empty , __T__, m_Equipped, new HandActionTake, new HandGuardHasItemInEvent(GetManOwner())));
  50. m_FSM.AddTransition(new HandTransition( m_Empty , __Cd_, m_Equipped, new HandActionCreated, new HandGuardHasItemInEvent(GetManOwner())));
  51. m_FSM.AddTransition(new HandTransition(m_Equipped, __D__, m_Empty, new HandActionDrop, null));
  52. m_FSM.AddTransition(new HandTransition(m_Equipped, __Tw_, m_Empty, new HandActionThrow, null));
  53. m_FSM.AddTransition(new HandTransition(m_Equipped, __M__, m_Empty, new HandActionMoveTo, new HandGuardAnd(new HandGuardHasItemInHands(GetManOwner()), new HandGuardCanMove(GetManOwner()))));
  54. m_FSM.AddTransition(new HandTransition(m_Equipped, __X__, m_Empty, new HandActionDestroy, new HandGuardHasItemInHands(GetManOwner())));
  55. m_FSM.AddTransition(new HandTransition(m_Equipped, __Xd_, m_Empty, new HandActionDestroyed, new HandGuardHasDestroyedItemInHands(GetManOwner())));
  56. m_FSM.AddTransition(new HandTransition(m_Equipped, __Xd_, m_Equipped, new HandActionDestroyed, new HandGuardNot(new HandGuardHasDestroyedItemInHands(GetManOwner()))));
  57. m_FSM.AddTransition(new HandTransition(m_Equipped, __R__, replacing));
  58. m_FSM.AddTransition(new HandTransition(replacing, _fin_, m_Equipped));
  59. replacing.AddTransition(new HandTransition(replacing.m_Replacing, _abt_, m_Equipped));
  60. m_FSM.AddTransition(new HandTransition(m_Equipped, __Re_, replacingElsewhere));
  61. m_FSM.AddTransition(new HandTransition(replacingElsewhere, _fin_, m_Empty));
  62. replacingElsewhere.AddTransition(new HandTransition(replacingElsewhere.m_Replacing, _abt_, m_Equipped));
  63. m_FSM.AddTransition(new HandTransition(m_Empty, __Rh_, replacingElsewhere3));
  64. m_FSM.AddTransition(new HandTransition(replacingElsewhere3, _fin_, m_Equipped));
  65. replacingElsewhere3.AddTransition(new HandTransition(replacingElsewhere3.m_Replacing, _abt_, m_Empty));
  66. m_FSM.AddTransition(new HandTransition(m_Equipped, __Rd_, m_Equipped, new HandActionReplaced, null));
  67. m_FSM.AddTransition(new HandTransition(m_Equipped, __W__, m_Equipped, new HandActionSwap, new HandGuardAnd(new HandGuardHasItemInHands(GetManOwner()), new HandGuardCanSwap(GetManOwner()))));
  68. m_FSM.AddTransition(new HandTransition(m_Equipped, __F__, m_Equipped, new HandActionForceSwap, new HandGuardAnd(new HandGuardHasItemInHands(GetManOwner()), new HandGuardCanForceSwap(GetManOwner()))));
  69. // start FSM
  70. m_FSM.SetInitialState(m_Empty);
  71. m_FSM.Start();
  72. super.Init();
  73. }
  74. bool CanProcessHandEvents () { return m_FSM && m_FSM.IsRunning(); }
  75. /**@fn ProcessHandEvent
  76. * @brief hand's fsm handling of events
  77. * @NOTE: warning: ProcessHandEvent can be called only within DayZPlayer::HandleInventory (or ::CommandHandler)
  78. **/
  79. override bool ProcessHandEvent (HandEventBase e)
  80. {
  81. //SyncRemote(e);
  82. if (m_FSM.ProcessEvent(e) == ProcessEventResult.FSM_OK)
  83. {
  84. #ifdef ENABLE_LOGGING
  85. if ( LogManager.IsInventoryHFSMLogEnable() )
  86. {
  87. Debug.InventoryHFSMLog("STS = " + GetManOwner().GetSimulationTimeStamp() , e.ToString(), "ProcessHandEvent", e.m_Player.ToString() );
  88. }
  89. #endif
  90. return true;
  91. }
  92. else
  93. {
  94. //if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("FSM refused to process event (no transition): src=" + GetCurrentState().ToString() + " event=" + e.ToString());
  95. return false;
  96. }
  97. }
  98. bool ProcessHandAbortEvent (HandEventBase e)
  99. {
  100. //SyncRemote(e);
  101. ProcessEventResult aa;
  102. m_FSM.ProcessAbortEvent(e, aa);
  103. if (aa == ProcessEventResult.FSM_OK)
  104. {
  105. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugSpam("[hndfsm] STS = " + GetManOwner().GetSimulationTimeStamp() + " Processed event e=" + e.ToString());
  106. return true;
  107. }
  108. else
  109. {
  110. //if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("FSM refused to process event (no transition): src=" + GetCurrentState().ToString() + " event=" + e.ToString());
  111. return false;
  112. }
  113. }
  114. void CheckFSMState()
  115. {
  116. if (GetEntityInHands())
  117. {
  118. if (!m_FSM.IsRunning() || GetCurrentStateID() == HandStateID.Empty) //forcing when not running or in stable state only
  119. m_FSM.SetCurrentState(m_Equipped);
  120. }
  121. else
  122. {
  123. if (!m_FSM.IsRunning() || GetCurrentStateID() == HandStateID.Equipped) //forcing when not running or in stable state only
  124. m_FSM.SetCurrentState(m_Empty);
  125. }
  126. }
  127. override bool OnStoreLoad (ParamsReadContext ctx, int version)
  128. {
  129. if ( !super.OnStoreLoad(ctx, version) )
  130. return false;
  131. //@TODO
  132. //m_FSM.OnStoreLoad(ctx, version);
  133. return true;
  134. }
  135. override void OnStoreSave (ParamsWriteContext ctx)
  136. {
  137. super.OnStoreSave(ctx);
  138. //@TODO
  139. //m_FSM.OnStoreSave(ctx, version);
  140. }
  141. /**@fn GetCurrentStateID
  142. * @return identifier of current stable state
  143. **/
  144. int GetCurrentStateID () { return m_FSM.GetCurrentStateID(); }
  145. bool IsIdle () { return m_FSM.GetCurrentState().IsIdle(); }
  146. /**@fn NetSyncCurrentStateID
  147. * @brief Engine callback - network synchronization of FSM's state. not intended to direct use.
  148. **/
  149. void NetSyncCurrentStateID (int id)
  150. {
  151. m_FSM.NetSyncCurrentStateID(id);
  152. }
  153. };