weaponattachmagazine.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. class RemoveNewMagazineFromInventory extends WeaponStateBase
  2. {
  3. Magazine m_newMagazine; /// magazine that will be removed from inventory
  4. ref InventoryLocation m_newSrc;
  5. void RemoveNewMagazineFromInventory (Weapon_Base w = NULL, WeaponStateBase parent = NULL)
  6. {
  7. m_newMagazine = NULL;
  8. m_newSrc = NULL;
  9. }
  10. override void OnEntry (WeaponEventBase e)
  11. {
  12. if(e)
  13. {
  14. if (!m_newSrc.IsValid())
  15. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory m_newSrc=invalid, item not in bubble?");
  16. if (m_newMagazine && m_newSrc && m_newSrc.IsValid())
  17. {
  18. InventoryLocation curr = new InventoryLocation;
  19. m_newMagazine.GetInventory().GetCurrentInventoryLocation(curr);
  20. if (m_newSrc.GetType() == InventoryLocationType.GROUND && curr.GetType() == InventoryLocationType.ATTACHMENT && curr.GetSlot() == InventorySlots.LEFTHAND)
  21. {
  22. // already in LH
  23. }
  24. else
  25. {
  26. InventoryLocation lhand = new InventoryLocation;
  27. lhand.SetAttachment(e.m_player, m_newMagazine, InventorySlots.LEFTHAND);
  28. if (GameInventory.LocationSyncMoveEntity(m_newSrc, lhand))
  29. {
  30. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory, ok - new magazine removed from inv (inv->LHand)"); }
  31. }
  32. else
  33. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory, error - cannot new remove mag from inv");
  34. }
  35. }
  36. else
  37. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory, error - no magazines configured for replace (m_old=m_new=NULL)");
  38. }
  39. super.OnEntry(e);
  40. }
  41. override void OnAbort (WeaponEventBase e)
  42. {
  43. m_newMagazine = NULL;
  44. m_newSrc = NULL;
  45. super.OnAbort(e);
  46. }
  47. override void OnExit (WeaponEventBase e)
  48. {
  49. m_weapon.ShowMagazine();
  50. m_newMagazine = NULL;
  51. m_newSrc = NULL;
  52. super.OnExit(e);
  53. }
  54. override bool SaveCurrentFSMState (ParamsWriteContext ctx)
  55. {
  56. if (!super.SaveCurrentFSMState(ctx))
  57. return false;
  58. if (!ctx.Write(m_newMagazine))
  59. {
  60. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory.SaveCurrentFSMState: cannot write m_newMagazine for weapon=" + m_weapon);
  61. return false;
  62. }
  63. if (!OptionalLocationWriteToContext(m_newSrc, ctx))
  64. {
  65. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory.SaveCurrentFSMState: cannot write m_newSrc for weapon=" + m_weapon);
  66. return false;
  67. }
  68. return true;
  69. }
  70. override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
  71. {
  72. if (!super.LoadCurrentFSMState(ctx, version))
  73. return false;
  74. if (!ctx.Read(m_newMagazine))
  75. {
  76. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory.LoadCurrentFSMState: cannot read m_newMagazine for weapon=" + m_weapon);
  77. return false;
  78. }
  79. if (!OptionalLocationReadFromContext(m_newSrc, ctx))
  80. {
  81. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " RemoveNewMagazineFromInventory.LoadCurrentFSMState: cannot read m_newSrc for weapon=" + m_weapon);
  82. return false;
  83. }
  84. return true;
  85. }
  86. };
  87. class RemoveNewMagazineFromInventory_OnEntryShowMag extends RemoveNewMagazineFromInventory
  88. {
  89. override void OnEntry (WeaponEventBase e)
  90. {
  91. if(e)
  92. m_weapon.ShowMagazine();
  93. super.OnEntry(e);
  94. }
  95. };
  96. class WeaponAttachMagazine extends WeaponStateBase
  97. {
  98. WeaponActions m_action;
  99. int m_actionType;
  100. ref WeaponStartAction m_start;
  101. ref AttachNewMagazine m_attach;
  102. ref WeaponChamberFromAttMag_W4T m_chamber;
  103. ref WeaponCharging_CK m_onCK;
  104. ref WeaponEjectCasing m_eject;
  105. void WeaponAttachMagazine (Weapon_Base w = NULL, WeaponStateBase parent = NULL, WeaponActions action = WeaponActions.NONE, int actionType = -1)
  106. {
  107. m_action = action;
  108. m_actionType = actionType;
  109. // setup nested state machine
  110. m_start = new WeaponStartAction(m_weapon, this, m_action, m_actionType);
  111. m_eject = new WeaponEjectCasing(m_weapon, this);
  112. m_attach = new AttachNewMagazine(m_weapon, this);
  113. m_chamber = new WeaponChamberFromAttMag_W4T(m_weapon, this);
  114. m_onCK = new WeaponCharging_CK(m_weapon, this);
  115. // events: MS, MA, BE, CK
  116. WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
  117. WeaponEventBase __ms_ = new WeaponEventAnimMagazineShow;
  118. WeaponEventBase __so_ = new WeaponEventAnimSliderOpen;
  119. WeaponEventBase __ma_ = new WeaponEventAnimMagazineAttached;
  120. WeaponEventBase __ck_ = new WeaponEventAnimCocked;
  121. m_fsm = new WeaponFSM(this); // @NOTE: set owner of the submachine fsm
  122. m_fsm.AddTransition(new WeaponTransition( m_start, __ms_, m_attach));
  123. m_fsm.AddTransition(new WeaponTransition( m_start, __so_, m_eject));
  124. m_fsm.AddTransition(new WeaponTransition( m_eject, __ms_, m_attach));
  125. m_fsm.AddTransition(new WeaponTransition( m_attach, __ck_, m_chamber, NULL, new GuardAnd(new WeaponGuardCurrentChamberEmpty(m_weapon), new WeaponGuardHasAmmo(m_weapon)))); // when opened, there is no __be_ event
  126. m_fsm.AddTransition(new WeaponTransition( m_attach, __ck_, m_onCK, NULL, new GuardAnd(new WeaponGuardCurrentChamberEmpty(m_weapon), new GuardNot(new WeaponGuardHasAmmo(m_weapon)))));
  127. m_fsm.AddTransition(new WeaponTransition( m_attach, _fin_, NULL));
  128. m_fsm.AddTransition(new WeaponTransition( m_chamber, _fin_, NULL));
  129. m_fsm.AddTransition(new WeaponTransition( m_onCK, _fin_, NULL));
  130. // Safety exits
  131. m_fsm.AddTransition(new WeaponTransition(m_eject , _fin_, null));
  132. m_fsm.AddTransition(new WeaponTransition(m_start , _fin_, null));
  133. m_fsm.SetInitialState(m_start);
  134. }
  135. override void OnEntry (WeaponEventBase e)
  136. {
  137. if (e)
  138. {
  139. Magazine mag = e.m_magazine;
  140. InventoryLocation newSrc = new InventoryLocation;
  141. mag.GetInventory().GetCurrentInventoryLocation(newSrc);
  142. // move to LH
  143. InventoryLocation lhand = new InventoryLocation;
  144. lhand.SetAttachment(e.m_player, mag, InventorySlots.LEFTHAND);
  145. if (GameInventory.LocationSyncMoveEntity(newSrc, lhand))
  146. {
  147. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponAttachMagazine, ok - new magazine removed from inv (inv->LHand)"); }
  148. }
  149. else
  150. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponAttachMagazine, error - cannot new remove mag from inv");
  151. InventoryLocation il = new InventoryLocation;
  152. il.SetAttachment(m_weapon, mag, InventorySlots.MAGAZINE);
  153. m_attach.m_newMagazine = mag;
  154. m_attach.m_newDst = il;
  155. }
  156. super.OnEntry(e); // @NOTE: super at the end (prevent override from submachine start)
  157. }
  158. override void OnAbort (WeaponEventBase e)
  159. {
  160. EntityAI leftHandItem = e.m_player.GetInventory().FindAttachment(InventorySlots.LEFTHAND);
  161. Magazine mag = Magazine.Cast(leftHandItem);
  162. if(mag)
  163. {
  164. e.m_player.GetInventory().ClearInventoryReservationEx( mag , null );
  165. InventoryLocation il = new InventoryLocation;
  166. e.m_player.GetInventory().FindFreeLocationFor( mag, FindInventoryLocationType.CARGO, il );
  167. if(!il || !il.IsValid())
  168. {
  169. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, mag))
  170. {
  171. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponAttachMagazine, ok - no inventory space for old magazine - dropped to ground"); }
  172. }
  173. else
  174. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponAttachMagazine, error - cannot drop magazine from left hand after not found inventory space for old magazine");
  175. }
  176. else
  177. {
  178. InventoryLocation oldSrc = new InventoryLocation;
  179. mag.GetInventory().GetCurrentInventoryLocation(oldSrc);
  180. if (GameInventory.LocationSyncMoveEntity(oldSrc, il))
  181. {
  182. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponAttachMagazine, ok - old magazine removed from wpn (LHand->inv)"); }
  183. }
  184. else
  185. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " WeaponAttachMagazine, error - cannot remove old mag from wpn");
  186. }
  187. }
  188. super.OnAbort(e);
  189. }
  190. };