weaponchamberinglooped.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  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 = new 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 LoopedChambering_Wait4ShowBullet2 m_w4sb2;
  245. ref WeaponStartAction m_endLoop;
  246. ref BulletHide_W4T m_hideB;
  247. ref WeaponChamberFromInnerMag_W4T m_chamberFromInnerMag;
  248. ref WeaponChambering_Base m_mag;
  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_mag = new WeaponChambering_InternalMagazine_OnExit(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_mag));
  274. m_fsm.AddTransition(new WeaponTransition(m_mag, __bM_, m_w4sb2, NULL, new GuardAnd(new GuardAnd(new WeaponGuardHasAmmoInLoopedState(m_mag), new WeaponGuardInternalMagazineHasRoomForBullet(m_weapon)),new WeaponGuardWeaponManagerWantContinue())));
  275. m_fsm.AddTransition(new WeaponTransition(m_mag, __bM_, m_endLoop));
  276. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, __bh_, m_hideB));
  277. m_fsm.AddTransition(new WeaponTransition(m_hideB, __bs_, m_mag));
  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_mag, _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_mag.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_mag.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_mag.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. };
  464. class LoopedChamberingCombineChamberInternalMagazine extends WeaponStateBase
  465. {
  466. WeaponActions m_action;
  467. int m_startActionType;
  468. int m_endActionType;
  469. Magazine m_srcMagazine; /// source of the cartridge
  470. ref InventoryLocation m_srcMagazinePrevLocation;
  471. ref WeaponStateBase m_start;
  472. ref LoopedChambering_Wait4ShowBullet2 m_w4sb2;
  473. ref WeaponStartAction m_endLoop;
  474. ref BulletHide_W4T m_hideB;
  475. ref WeaponChamberFromInnerMag_W4T m_chamberFromInnerMag;
  476. ref WeaponChambering_Base m_chamber;
  477. ref WeaponChambering_Base m_mag;
  478. void LoopedChamberingCombineChamberInternalMagazine (Weapon_Base w = NULL, WeaponStateBase parent = NULL, WeaponActions action = WeaponActions.NONE, int startActionType = -1, int endActionType = -1)
  479. {
  480. m_action = action;
  481. m_startActionType = startActionType;
  482. m_endActionType = endActionType;
  483. // setup nested state machine
  484. m_start = new WeaponChambering_Start(m_weapon, this, m_action, m_startActionType);
  485. m_chamber = new WeaponChambering_Cartridge(m_weapon, this);
  486. m_mag = new WeaponChambering_InternalMagazine_OnExit(m_weapon, this);
  487. m_w4sb2 = new LoopedChambering_Wait4ShowBullet2(m_weapon, this);
  488. m_hideB = new BulletHide_W4T(m_weapon, this);
  489. m_chamberFromInnerMag = new WeaponChamberFromInnerMag_W4T(m_weapon, this);
  490. m_endLoop = new LoopedChambering_EndLoop(m_weapon, this, m_action, m_endActionType); // @NOTE: termination playing action - dummy?
  491. // events
  492. WeaponEventBase _fin_ = new WeaponEventHumanCommandActionFinished;
  493. WeaponEventContinuousLoadBulletStart __lS_ = new WeaponEventContinuousLoadBulletStart;
  494. WeaponEventContinuousLoadBulletEnd __lE_ = new WeaponEventContinuousLoadBulletEnd;
  495. WeaponEventAnimCocked __wc_ = new WeaponEventAnimCocked;
  496. WeaponEventAnimBulletShow __bs_ = new WeaponEventAnimBulletShow;
  497. WeaponEventAnimBulletHide __bh_ = new WeaponEventAnimBulletHide;
  498. WeaponEventAnimBulletEject __be_ = new WeaponEventAnimBulletEject;
  499. WeaponEventAnimBulletInMagazine __bM_ = new WeaponEventAnimBulletInMagazine;
  500. WeaponEventAnimBulletInChamber __bc_ = new WeaponEventAnimBulletInChamber;
  501. WeaponEventAnimBulletShow2 _bs2_ = new WeaponEventAnimBulletShow2;
  502. m_fsm = new WeaponFSM(this); // @NOTE: set owner of the submachine fsm
  503. m_fsm.AddTransition(new WeaponTransition(m_start , __bs_, m_chamber));
  504. m_fsm.AddTransition(new WeaponTransition(m_mag, __bM_, m_w4sb2, NULL, new GuardAnd(new GuardAnd(new WeaponGuardHasAmmoInLoopedState(m_mag), new WeaponGuardInternalMagazineHasRoomForBullet(m_weapon)),new WeaponGuardWeaponManagerWantContinue())));
  505. m_fsm.AddTransition(new WeaponTransition(m_chamber, __bc_, m_w4sb2, NULL, new GuardAnd(new GuardAnd(new WeaponGuardHasAmmoInLoopedState(m_chamber), new WeaponGuardInternalMagazineHasRoomForBullet(m_weapon)),new WeaponGuardWeaponManagerWantContinue())));
  506. m_fsm.AddTransition(new WeaponTransition(m_mag, __bM_, m_endLoop));
  507. m_fsm.AddTransition(new WeaponTransition(m_chamber, __bc_, m_endLoop));
  508. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, __bh_, m_hideB));
  509. m_fsm.AddTransition(new WeaponTransition(m_hideB, __bs_, m_mag));
  510. m_fsm.AddTransition(new WeaponTransition(m_endLoop, _fin_, NULL));
  511. //m_fsm.AddTransition(new WeaponTransition(m_chamberFromInnerMag, _fin_, NULL));
  512. // Safety exits
  513. m_fsm.AddTransition(new WeaponTransition(m_hideB, _fin_, null));
  514. m_fsm.AddTransition(new WeaponTransition(m_w4sb2, _fin_, null));
  515. m_fsm.AddTransition(new WeaponTransition(m_chamber, _fin_, null));
  516. m_fsm.AddTransition(new WeaponTransition(m_start , _fin_, null));
  517. m_fsm.SetInitialState(m_start);
  518. }
  519. override void OnEntry (WeaponEventBase e)
  520. {
  521. if (e != NULL)
  522. {
  523. m_srcMagazine = e.m_magazine;
  524. if (m_srcMagazine != NULL)
  525. {
  526. InventoryLocation newSrc = new InventoryLocation;
  527. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(newSrc);
  528. m_srcMagazinePrevLocation = newSrc;
  529. // move to LH
  530. InventoryLocation lhand = new InventoryLocation;
  531. lhand.SetAttachment(e.m_player, m_srcMagazine, InventorySlots.LEFTHAND);
  532. if (GameInventory.LocationSyncMoveEntity(newSrc, lhand))
  533. {
  534. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from inv (inv->LHand)"); }
  535. }
  536. else
  537. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot remove ammo pile from inv");
  538. m_chamber.m_srcMagazine = m_srcMagazine;
  539. m_mag.m_srcMagazine = m_srcMagazine;
  540. }
  541. else
  542. {
  543. Print("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast m_srcMagazine = NULL");
  544. }
  545. }
  546. else
  547. {
  548. Print("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast (e=NULL), m_srcMagazine=" + m_srcMagazine.ToString());
  549. }
  550. super.OnEntry(e); // @NOTE: super at the end (prevent override from submachine start)
  551. }
  552. override void OnExit (WeaponEventBase e)
  553. {
  554. bool done = false;
  555. if (m_srcMagazine)
  556. {
  557. e.m_player.GetInventory().ClearInventoryReservationEx( m_srcMagazine , m_srcMagazinePrevLocation );
  558. InventoryLocation leftHandIl = new InventoryLocation;
  559. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(leftHandIl);
  560. if (leftHandIl.IsValid())
  561. {
  562. if (m_srcMagazinePrevLocation && m_srcMagazinePrevLocation.IsValid())
  563. {
  564. if (vector.DistanceSq(m_srcMagazinePrevLocation.GetPos(), leftHandIl.GetPos()) < WeaponManager.MAX_DROP_MAGAZINE_DISTANCE_SQ)
  565. {
  566. if (GameInventory.LocationCanMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  567. {
  568. if (GameInventory.LocationSyncMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  569. {
  570. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand to previous location (LHand->inv) - exit"); }
  571. done = true;
  572. }
  573. }
  574. }
  575. }
  576. if (!done)
  577. {
  578. InventoryLocation il = new InventoryLocation;
  579. e.m_player.GetInventory().FindFreeLocationFor( m_srcMagazine, FindInventoryLocationType.CARGO, il );
  580. if (!il || !il.IsValid())
  581. {
  582. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_srcMagazine))
  583. {
  584. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - no inventory space for ammo pile - dropped to ground - exit"); }
  585. }
  586. else
  587. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot drop ammo pile from left hand after not found inventory space for ammo pile - exit");
  588. }
  589. else
  590. {
  591. if (GameInventory.LocationSyncMoveEntity(leftHandIl, il))
  592. {
  593. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand (LHand->inv) - exit"); }
  594. }
  595. else
  596. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot remove ammo pile from wpn - exit");
  597. }
  598. }
  599. }
  600. }
  601. super.OnExit(e);
  602. m_srcMagazine = NULL;
  603. m_chamber.m_srcMagazine = NULL;
  604. m_mag.m_srcMagazine = NULL;
  605. m_srcMagazinePrevLocation = NULL;
  606. }
  607. override void OnAbort (WeaponEventBase e)
  608. {
  609. bool done = false;
  610. if (m_srcMagazine)
  611. {
  612. e.m_player.GetInventory().ClearInventoryReservationEx( m_srcMagazine , m_srcMagazinePrevLocation );
  613. InventoryLocation leftHandIl = new InventoryLocation;
  614. m_srcMagazine.GetInventory().GetCurrentInventoryLocation(leftHandIl);
  615. if (leftHandIl.IsValid())
  616. {
  617. if (m_srcMagazinePrevLocation && m_srcMagazinePrevLocation.IsValid())
  618. {
  619. if (vector.DistanceSq(m_srcMagazinePrevLocation.GetPos(), leftHandIl.GetPos()) < WeaponManager.MAX_DROP_MAGAZINE_DISTANCE_SQ)
  620. {
  621. if (GameInventory.LocationCanMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  622. {
  623. if (GameInventory.LocationSyncMoveEntity(leftHandIl,m_srcMagazinePrevLocation))
  624. {
  625. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand to previous location (LHand->inv) - abort"); }
  626. done = true;
  627. }
  628. }
  629. }
  630. }
  631. if (!done)
  632. {
  633. InventoryLocation il = new InventoryLocation;
  634. e.m_player.GetInventory().FindFreeLocationFor( m_srcMagazine, FindInventoryLocationType.CARGO, il );
  635. if (!il || !il.IsValid())
  636. {
  637. if (DayZPlayerUtils.HandleDropMagazine(e.m_player, m_srcMagazine))
  638. {
  639. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - no inventory space for ammo pile - dropped to ground - abort"); }
  640. }
  641. else
  642. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot drop ammo pile from left hand after not found inventory space for ammo pile - abort");
  643. }
  644. else
  645. {
  646. if (GameInventory.LocationSyncMoveEntity(leftHandIl, il))
  647. {
  648. if (LogManager.IsWeaponLogEnable()) { wpnDebugPrint("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, ok - ammo pile removed from left hand (LHand->inv) - abort"); }
  649. }
  650. else
  651. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast, error - cannot remove ammo pile from wpn - abort");
  652. }
  653. }
  654. }
  655. }
  656. super.OnAbort(e);
  657. m_srcMagazine = NULL;
  658. m_chamber.m_srcMagazine = NULL;
  659. m_mag.m_srcMagazine = NULL;
  660. m_srcMagazinePrevLocation = NULL;
  661. }
  662. override bool SaveCurrentFSMState (ParamsWriteContext ctx)
  663. {
  664. if (!super.SaveCurrentFSMState(ctx))
  665. return false;
  666. if (!ctx.Write(m_srcMagazine))
  667. {
  668. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.SaveCurrentFSMState: cannot save m_srcMagazine for weapon=" + m_weapon);
  669. return false;
  670. }
  671. if (!OptionalLocationWriteToContext(m_srcMagazinePrevLocation, ctx))
  672. {
  673. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.SaveCurrentFSMState: cannot write m_srcMagazinePrevLocation for weapon=" + m_weapon);
  674. return false;
  675. }
  676. return true;
  677. }
  678. override bool LoadCurrentFSMState (ParamsReadContext ctx, int version)
  679. {
  680. if (!super.LoadCurrentFSMState(ctx, version))
  681. return false;
  682. if (!ctx.Read(m_srcMagazine))
  683. {
  684. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.LoadCurrentFSMState: cannot read m_srcMagazine for weapon=" + m_weapon);
  685. return false;
  686. }
  687. if (!OptionalLocationReadFromContext(m_srcMagazinePrevLocation, ctx))
  688. {
  689. Error("[wpnfsm] " + Object.GetDebugName(m_weapon) + " LoopedChamberingEjectLast.LoadCurrentFSMState: cannot read m_srcMagazinePrevLocation for weapon=" + m_weapon);
  690. return false;
  691. }
  692. return true;
  693. }
  694. };