weaponchamberinglooped.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. // load x bullets
  2. class LoopedChambering_EndLoop extends WeaponStartAction
  3. {
  4. override bool IsWaitingForActionFinish () { return true; }
  5. };
  6. class LoopedChambering_Wait4ShowBullet2 extends WeaponStateBase
  7. {
  8. override bool IsWaitingForActionFinish () { return false; }
  9. };
  10. class LoopedChambering extends WeaponStateBase
  11. {
  12. WeaponActions m_action;
  13. int m_startActionType;
  14. int m_endActionType;
  15. Magazine m_srcMagazine; /// source of the cartridge
  16. ref InventoryLocation m_srcMagazinePrevLocation;
  17. ref WeaponStateBase m_start;
  18. ref WeaponEjectCasing m_eject;
  19. ref WeaponChambering_Base m_chamber;
  20. ref LoopedChambering_Wait4ShowBullet2 m_w4sb2;
  21. ref WeaponStartAction m_endLoop;
  22. ref BulletHide_W4T m_hideB;
  23. void LoopedChambering (Weapon_Base w = NULL, WeaponStateBase parent = NULL, WeaponActions action = WeaponActions.NONE, int startActionType = -1, int endActionType = -1)
  24. {
  25. m_action = action;
  26. m_startActionType = startActionType;
  27. m_endActionType = endActionType;
  28. // setup nested state machine
  29. m_start = new WeaponChambering_Start(m_weapon, this, m_action, m_startActionType);
  30. m_eject = new WeaponEjectCasing(m_weapon, this);
  31. m_chamber = new WeaponChambering_Cartridge_ChambToMag(m_weapon, this);
  32. m_w4sb2 = LoopedChambering_Wait4ShowBullet2(m_weapon, this);
  33. m_hideB = new BulletHide_W4T(m_weapon, this);
  34. m_endLoop = new LoopedChambering_EndLoop(m_weapon, this, m_action, m_endActionType); // @NOTE: termination playing action - dummy?
  35. // events
  36. WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
  37. WeaponEventContinuousLoadBulletStart __lS_ = new WeaponEventContinuousLoadBulletStart;
  38. WeaponEventContinuousLoadBulletEnd __lE_ = new WeaponEventContinuousLoadBulletEnd;
  39. WeaponEventAnimBulletShow __bs_ = new WeaponEventAnimBulletShow;
  40. WeaponEventAnimBulletHide __bh_ = new WeaponEventAnimBulletHide;
  41. WeaponEventAnimBulletEject __be_ = new WeaponEventAnimBulletEject;
  42. WeaponEventAnimBulletInMagazine __bM_ = new WeaponEventAnimBulletInMagazine;
  43. WeaponEventAnimBulletShow2 _bs2_ = new WeaponEventAnimBulletShow2;
  44. m_fsm = new WeaponFSM(this); // @NOTE: set owner of the submachine fsm
  45. m_fsm.AddTransition(new WeaponTransition(m_start, __be_, m_eject));
  46. m_fsm.AddTransition(new WeaponTransition(m_start, __bs_, m_chamber));
  47. m_fsm.AddTransition(new WeaponTransition(m_eject, __bs_, m_chamber));
  48. m_fsm.AddTransition(new WeaponTransition(m_chamber, __bM_, m_w4sb2, NULL, new GuardAnd(new GuardAnd(new WeaponGuardHasAmmoInLoopedState(m_chamber), new WeaponGuardInternalMagazineHasRoomForBullet(m_weapon)),new WeaponGuardWeaponManagerWantContinue())));
  49. m_fsm.AddTransition(new WeaponTransition(m_chamber, __bM_, m_endLoop));
  50. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, __bh_, m_hideB));
  51. m_fsm.AddTransition(new WeaponTransition(m_hideB, __bs_, m_chamber));
  52. m_fsm.AddTransition(new WeaponTransition(m_endLoop, _fin_, NULL));
  53. // Safety exits
  54. m_fsm.AddTransition(new WeaponTransition(m_hideB, _fin_, null));
  55. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, _fin_, null));
  56. m_fsm.AddTransition(new WeaponTransition(m_chamber, _fin_, null));
  57. m_fsm.AddTransition(new WeaponTransition(m_eject , _fin_, null));
  58. m_fsm.AddTransition(new WeaponTransition(m_start , _fin_, null));
  59. m_fsm.SetInitialState(m_start);
  60. }
  61. override void OnEntry (WeaponEventBase e)
  62. {
  63. if (e != NULL)
  64. {
  65. m_srcMagazine = e.m_magazine;
  66. if (m_srcMagazine != NULL)
  67. {
  68. m_weapon.SelectionBulletHide();
  69. InventoryLocation newSrc = new InventoryLocation;
  70. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(newSrc);
  71. m_srcMagazinePrevLocation = newSrc;
  72. // move to LH
  73. InventoryLocation lhand = new InventoryLocation;
  74. lhand.SetAttachment(e.m_player, m_srcMagazine, InventorySlots.LEFTHAND);
  75. if (GameInventory.LocationSyncMoveEntity(newSrc, lhand))
  76. {
  77. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - ammo pile removed from inv (inv->LHand)"); }
  78. }
  79. else
  80. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, error - cannot remove ammo pile from inv");
  81. m_chamber.m_srcMagazine = m_srcMagazine;
  82. }
  83. else
  84. {
  85. Print("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering m_srcMagazine = NULL");
  86. }
  87. }
  88. else
  89. {
  90. Print("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering (e=NULL), m_srcMagazine=" + m_srcMagazine.ToString());
  91. }
  92. super.OnEntry(e); // @NOTE: super at the end (prevent override from submachine start)
  93. }
  94. override void OnExit (WeaponEventBase e)
  95. {
  96. bool done = false;
  97. if (m_srcMagazine)
  98. {
  99. e.m_player.GetInventory().ClearInventoryReservationEx( m_srcMagazine , m_srcMagazinePrevLocation );
  100. InventoryLocation leftHandIl = new InventoryLocation;
  101. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(leftHandIl);
  102. if (leftHandIl.IsValid())
  103. {
  104. if (m_srcMagazinePrevLocation && m_srcMagazinePrevLocation.IsValid())
  105. {
  106. if (vector.DistanceSq(m_srcMagazinePrevLocation.GetPos(), leftHandIl.GetPos()) < WeaponManager.MAX_DROP_MAGAZINE_DISTANCE_SQ)
  107. {
  108. if (GameInventory.LocationCanMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  109. {
  110. if (GameInventory.LocationSyncMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  111. {
  112. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - ammo pile removed from left hand to previous location (LHand->inv) - exit"); }
  113. done = true;
  114. }
  115. }
  116. }
  117. }
  118. if( !done)
  119. {
  120. InventoryLocation il = new InventoryLocation;
  121. e.m_player.GetInventory().FindFreeLocationFor( m_srcMagazine, FindInventoryLocationType.CARGO, il );
  122. if(!il || !il.IsValid())
  123. {
  124. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_srcMagazine))
  125. {
  126. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - no inventory space for ammo pile - dropped to ground - exit"); }
  127. }
  128. else
  129. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, error - cannot drop ammo pile from left hand after not found inventory space for ammo pile - exit");
  130. }
  131. else
  132. {
  133. if (GameInventory.LocationSyncMoveEntity(leftHandIl, il))
  134. {
  135. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - ammo pile removed from left hand (LHand->inv) - exit"); }
  136. }
  137. else
  138. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, error - cannot remove ammo pile from wpn - exit");
  139. }
  140. }
  141. }
  142. }
  143. super.OnExit(e);
  144. m_srcMagazine = NULL;
  145. m_chamber.m_srcMagazine = NULL;
  146. m_srcMagazinePrevLocation = NULL;
  147. }
  148. override void OnAbort (WeaponEventBase e)
  149. {
  150. bool done = false;
  151. if (m_srcMagazine)
  152. {
  153. e.m_player.GetInventory().ClearInventoryReservationEx( m_srcMagazine , m_srcMagazinePrevLocation );
  154. InventoryLocation leftHandIl = new InventoryLocation;
  155. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(leftHandIl);
  156. if (leftHandIl.IsValid())
  157. {
  158. if (m_srcMagazinePrevLocation && m_srcMagazinePrevLocation.IsValid())
  159. {
  160. if (vector.DistanceSq(m_srcMagazinePrevLocation.GetPos(), leftHandIl.GetPos()) < WeaponManager.MAX_DROP_MAGAZINE_DISTANCE_SQ)
  161. {
  162. if (GameInventory.LocationCanMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  163. {
  164. if (GameInventory.LocationSyncMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  165. {
  166. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - ammo pile removed from left hand to previous location (LHand->inv) - abort"); }
  167. done = true;
  168. }
  169. }
  170. }
  171. }
  172. if( !done)
  173. {
  174. InventoryLocation il = new InventoryLocation;
  175. e.m_player.GetInventory().FindFreeLocationFor( m_srcMagazine, FindInventoryLocationType.CARGO, il );
  176. if(!il || !il.IsValid())
  177. {
  178. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_srcMagazine))
  179. {
  180. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - no inventory space for ammo pile - dropped to ground - abort"); }
  181. }
  182. else
  183. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, error - cannot drop ammo pile from left hand after not found inventory space for ammo pile - abort");
  184. }
  185. else
  186. {
  187. if (GameInventory.LocationSyncMoveEntity(leftHandIl, il))
  188. {
  189. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, ok - ammo pile removed from left hand (LHand->inv) - abort"); }
  190. }
  191. else
  192. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering, error - cannot remove ammo pile from wpn - abort");
  193. }
  194. }
  195. }
  196. }
  197. super.OnAbort(e);
  198. m_srcMagazine = NULL;
  199. m_chamber.m_srcMagazine = NULL;
  200. m_srcMagazinePrevLocation = NULL;
  201. }
  202. override bool SaveCurrentFSMState (ParamsWriteContext ctx)
  203. {
  204. if (!super.SaveCurrentFSMState(ctx))
  205. return false;
  206. if (!ctx.Write(m_srcMagazine))
  207. {
  208. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering.SaveCurrentFSMState: cannot save m_srcMagazine for weapon=" + m_weapon);
  209. return false;
  210. }
  211. if (!OptionalLocationWriteToContext(m_srcMagazinePrevLocation, ctx))
  212. {
  213. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering.SaveCurrentFSMState: cannot write m_srcMagazinePrevLocation for weapon=" + m_weapon);
  214. return false;
  215. }
  216. return true;
  217. }
  218. override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
  219. {
  220. if (!super.LoadCurrentFSMState(ctx, version))
  221. return false;
  222. if (!ctx.Read(m_srcMagazine))
  223. {
  224. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering.LoadCurrentFSMState: cannot read m_srcMagazine for weapon=" + m_weapon);
  225. return false;
  226. }
  227. if (!OptionalLocationReadFromContext(m_srcMagazinePrevLocation, ctx))
  228. {
  229. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChambering.LoadCurrentFSMState: cannot read m_srcMagazinePrevLocation for weapon=" + m_weapon);
  230. return false;
  231. }
  232. return true;
  233. }
  234. };
  235. class LoopedChamberingEjectLast extends WeaponStateBase
  236. {
  237. WeaponActions m_action;
  238. int m_startActionType;
  239. int m_endActionType;
  240. Magazine m_srcMagazine; /// source of the cartridge
  241. ref InventoryLocation m_srcMagazinePrevLocation;
  242. ref WeaponStateBase m_start;
  243. ref WeaponEjectCasing m_eject;
  244. ref WeaponChambering_Base m_chamber;
  245. ref LoopedChambering_Wait4ShowBullet2 m_w4sb2;
  246. ref WeaponStartAction m_endLoop;
  247. ref BulletHide_W4T m_hideB;
  248. ref WeaponChamberFromInnerMag_W4T m_chamberFromInnerMag;
  249. void LoopedChamberingEjectLast (Weapon_Base w = NULL, WeaponStateBase parent = NULL, WeaponActions action = WeaponActions.NONE, int startActionType = -1, int endActionType = -1)
  250. {
  251. m_action = action;
  252. m_startActionType = startActionType;
  253. m_endActionType = endActionType;
  254. // setup nested state machine
  255. m_start = new WeaponChambering_Start(m_weapon, this, m_action, m_startActionType);
  256. m_eject = new WeaponEjectCasing(m_weapon, this);
  257. m_chamber = new WeaponChambering_Cartridge_InnerMag(m_weapon, this);
  258. m_w4sb2 = new LoopedChambering_Wait4ShowBullet2(m_weapon, this);
  259. m_hideB = new BulletHide_W4T(m_weapon, this);
  260. m_chamberFromInnerMag = new WeaponChamberFromInnerMag_W4T(m_weapon, this);
  261. m_endLoop = new LoopedChambering_EndLoop(m_weapon, this, m_action, m_endActionType); // @NOTE: termination playing action - dummy?
  262. // events
  263. WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
  264. WeaponEventContinuousLoadBulletStart __lS_ = new WeaponEventContinuousLoadBulletStart;
  265. WeaponEventContinuousLoadBulletEnd __lE_ = new WeaponEventContinuousLoadBulletEnd;
  266. WeaponEventAnimCocked __wc_ = new WeaponEventAnimCocked;
  267. WeaponEventAnimBulletShow __bs_ = new WeaponEventAnimBulletShow;
  268. WeaponEventAnimBulletHide __bh_ = new WeaponEventAnimBulletHide;
  269. WeaponEventAnimBulletEject __be_ = new WeaponEventAnimBulletEject;
  270. WeaponEventAnimBulletInMagazine __bM_ = new WeaponEventAnimBulletInMagazine;
  271. WeaponEventAnimBulletShow2 _bs2_ = new WeaponEventAnimBulletShow2;
  272. m_fsm = new WeaponFSM(this); // @NOTE: set owner of the submachine fsm
  273. m_fsm.AddTransition(new WeaponTransition(m_start , __bs_, m_chamber));
  274. m_fsm.AddTransition(new WeaponTransition(m_chamber, __bM_, m_w4sb2, NULL, new GuardAnd(new GuardAnd(new WeaponGuardHasAmmoInLoopedState(m_chamber), new WeaponGuardInternalMagazineHasRoomForBullet(m_weapon)),new WeaponGuardWeaponManagerWantContinue())));
  275. m_fsm.AddTransition(new WeaponTransition(m_chamber, __bM_, m_endLoop));
  276. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, __bh_, m_hideB));
  277. m_fsm.AddTransition(new WeaponTransition(m_hideB, __bs_, m_chamber));
  278. m_fsm.AddTransition(new WeaponTransition(m_endLoop, _fin_, NULL));
  279. m_fsm.AddTransition(new WeaponTransition(m_hideB, __be_, m_eject));
  280. m_fsm.AddTransition(new WeaponTransition(m_endLoop, __be_, m_eject));
  281. m_fsm.AddTransition(new WeaponTransition(m_eject, __wc_, m_chamberFromInnerMag));
  282. m_fsm.AddTransition(new WeaponTransition(m_chamberFromInnerMag, _fin_, NULL));
  283. // Safety exits
  284. m_fsm.AddTransition(new WeaponTransition(m_hideB, _fin_, null));
  285. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, _fin_, null));
  286. m_fsm.AddTransition(new WeaponTransition(m_chamber, _fin_, null));
  287. m_fsm.AddTransition(new WeaponTransition(m_eject , _fin_, null));
  288. m_fsm.AddTransition(new WeaponTransition(m_start , _fin_, null));
  289. m_fsm.SetInitialState(m_start);
  290. }
  291. override void OnEntry (WeaponEventBase e)
  292. {
  293. if (e != NULL)
  294. {
  295. m_srcMagazine = e.m_magazine;
  296. if (m_srcMagazine != NULL)
  297. {
  298. InventoryLocation newSrc = new InventoryLocation;
  299. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(newSrc);
  300. m_srcMagazinePrevLocation = newSrc;
  301. // move to LH
  302. InventoryLocation lhand = new InventoryLocation;
  303. lhand.SetAttachment(e.m_player, m_srcMagazine, InventorySlots.LEFTHAND);
  304. if (GameInventory.LocationSyncMoveEntity(newSrc, lhand))
  305. {
  306. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from inv (inv->LHand)"); }
  307. }
  308. else
  309. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot remove ammo pile from inv");
  310. m_chamber.m_srcMagazine = m_srcMagazine;
  311. }
  312. else
  313. {
  314. Print("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast m_srcMagazine = NULL");
  315. }
  316. }
  317. else
  318. {
  319. Print("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast (e=NULL), m_srcMagazine=" + m_srcMagazine.ToString());
  320. }
  321. super.OnEntry(e); // @NOTE: super at the end (prevent override from submachine start)
  322. }
  323. override void OnExit (WeaponEventBase e)
  324. {
  325. bool done = false;
  326. if (m_srcMagazine)
  327. {
  328. e.m_player.GetInventory().ClearInventoryReservationEx( m_srcMagazine , m_srcMagazinePrevLocation );
  329. InventoryLocation leftHandIl = new InventoryLocation;
  330. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(leftHandIl);
  331. if (leftHandIl.IsValid())
  332. {
  333. if (m_srcMagazinePrevLocation && m_srcMagazinePrevLocation.IsValid())
  334. {
  335. if (vector.DistanceSq(m_srcMagazinePrevLocation.GetPos(), leftHandIl.GetPos()) < WeaponManager.MAX_DROP_MAGAZINE_DISTANCE_SQ)
  336. {
  337. if (GameInventory.LocationCanMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  338. {
  339. if (GameInventory.LocationSyncMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  340. {
  341. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand to previous location (LHand->inv) - exit"); }
  342. done = true;
  343. }
  344. }
  345. }
  346. }
  347. if (!done)
  348. {
  349. InventoryLocation il = new InventoryLocation;
  350. e.m_player.GetInventory().FindFreeLocationFor( m_srcMagazine, FindInventoryLocationType.CARGO, il );
  351. if (!il || !il.IsValid())
  352. {
  353. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_srcMagazine))
  354. {
  355. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - no inventory space for ammo pile - dropped to ground - exit"); }
  356. }
  357. else
  358. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot drop ammo pile from left hand after not found inventory space for ammo pile - exit");
  359. }
  360. else
  361. {
  362. if (GameInventory.LocationSyncMoveEntity(leftHandIl, il))
  363. {
  364. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand (LHand->inv) - exit"); }
  365. }
  366. else
  367. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot remove ammo pile from wpn - exit");
  368. }
  369. }
  370. }
  371. }
  372. super.OnExit(e);
  373. m_srcMagazine = NULL;
  374. m_chamber.m_srcMagazine = NULL;
  375. m_srcMagazinePrevLocation = NULL;
  376. }
  377. override void OnAbort (WeaponEventBase e)
  378. {
  379. bool done = false;
  380. if (m_srcMagazine)
  381. {
  382. e.m_player.GetInventory().ClearInventoryReservationEx( m_srcMagazine , m_srcMagazinePrevLocation );
  383. InventoryLocation leftHandIl = new InventoryLocation;
  384. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(leftHandIl);
  385. if (leftHandIl.IsValid())
  386. {
  387. if (m_srcMagazinePrevLocation && m_srcMagazinePrevLocation.IsValid())
  388. {
  389. if (vector.DistanceSq(m_srcMagazinePrevLocation.GetPos(), leftHandIl.GetPos()) < WeaponManager.MAX_DROP_MAGAZINE_DISTANCE_SQ)
  390. {
  391. if (GameInventory.LocationCanMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  392. {
  393. if (GameInventory.LocationSyncMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  394. {
  395. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand to previous location (LHand->inv) - abort"); }
  396. done = true;
  397. }
  398. }
  399. }
  400. }
  401. if (!done)
  402. {
  403. InventoryLocation il = new InventoryLocation;
  404. e.m_player.GetInventory().FindFreeLocationFor( m_srcMagazine, FindInventoryLocationType.CARGO, il );
  405. if (!il || !il.IsValid())
  406. {
  407. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_srcMagazine))
  408. {
  409. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - no inventory space for ammo pile - dropped to ground - abort"); }
  410. }
  411. else
  412. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot drop ammo pile from left hand after not found inventory space for ammo pile - abort");
  413. }
  414. else
  415. {
  416. if (GameInventory.LocationSyncMoveEntity(leftHandIl, il))
  417. {
  418. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand (LHand->inv) - abort"); }
  419. }
  420. else
  421. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot remove ammo pile from wpn - abort");
  422. }
  423. }
  424. }
  425. }
  426. super.OnAbort(e);
  427. m_srcMagazine = NULL;
  428. m_chamber.m_srcMagazine = NULL;
  429. m_srcMagazinePrevLocation = NULL;
  430. }
  431. override bool SaveCurrentFSMState (ParamsWriteContext ctx)
  432. {
  433. if (!super.SaveCurrentFSMState(ctx))
  434. return false;
  435. if (!ctx.Write(m_srcMagazine))
  436. {
  437. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.SaveCurrentFSMState: cannot save m_srcMagazine for weapon=" + m_weapon);
  438. return false;
  439. }
  440. if (!OptionalLocationWriteToContext(m_srcMagazinePrevLocation, ctx))
  441. {
  442. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.SaveCurrentFSMState: cannot write m_srcMagazinePrevLocation for weapon=" + m_weapon);
  443. return false;
  444. }
  445. return true;
  446. }
  447. override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
  448. {
  449. if (!super.LoadCurrentFSMState(ctx, version))
  450. return false;
  451. if (!ctx.Read(m_srcMagazine))
  452. {
  453. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.LoadCurrentFSMState: cannot read m_srcMagazine for weapon=" + m_weapon);
  454. return false;
  455. }
  456. if (!OptionalLocationReadFromContext(m_srcMagazinePrevLocation, ctx))
  457. {
  458. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.LoadCurrentFSMState: cannot read m_srcMagazinePrevLocation for weapon=" + m_weapon);
  459. return false;
  460. }
  461. return true;
  462. }
  463. };