humaninventory.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. /**@class HumanInventory
  2. * @brief inventory for plain man/human
  3. *
  4. * HumanInventory has simple synchronous operations only, i.e.
  5. * no animations are involved while adding/removing/swapping to/from hands.
  6. *
  7. * Animations are added on higher level of hierarchy (DayZPlayerInventory for example)
  8. **/
  9. class HumanInventory : GameInventory
  10. {
  11. int m_syncClearUserReservationindex = -1;
  12. //int m_UserReservationToClear = -1;
  13. /**@fn GetEntityInHands
  14. * @return entity in hands
  15. **/
  16. proto native EntityAI GetEntityInHands();
  17. /**@fn CanAddEntityInHands
  18. * @brief alternative for TestAddEntityInHands(e, true, true, true);
  19. **/
  20. proto native bool CanAddEntityInHands(EntityAI e);
  21. /**@fn TestAddEntityInHands
  22. * @param[in] e entity to test for taking in hands
  23. * @param[in] do_item_check deny if entity is not InventoryItem
  24. * @param[in] do_occupancy_test deny if there is item in hands already
  25. * @param[in] do_script_check deny if script conditions fail
  26. * @return true if item passed all tests
  27. **/
  28. proto native bool TestAddEntityInHands(EntityAI e, bool do_resevation_check, bool do_item_check, bool do_lock_check, bool do_occupancy_test, bool do_script_check);
  29. /**@fn CanRemoveEntityInHands
  30. * @return true if entity can be removed from hands
  31. **/
  32. proto native bool CanRemoveEntityInHands();
  33. proto native bool CanOpenInventory();
  34. /**@fn CreateInHands
  35. * @brief creates new entity in hands
  36. * @param[in] typeName type name of the entity to be created
  37. * @return new entity or null otherwise
  38. **/
  39. proto native EntityAI CreateInHands(string typeName);
  40. proto native int GetUserReservedLocationCount();
  41. proto native int FindUserReservedLocationIndex(notnull EntityAI e);
  42. proto native int FindCollidingUserReservedLocationIndex(notnull EntityAI e, notnull InventoryLocation dst);
  43. proto native void GetUserReservedLocation(int index, out notnull InventoryLocation dst);
  44. proto native int FindFirstUserReservedLocationIndexForContainer(notnull EntityAI e);
  45. proto native void SetUserReservedLocation(notnull EntityAI eai, notnull InventoryLocation dst);
  46. proto native void ClearUserReservedLocation(notnull EntityAI eai);
  47. proto native bool ClearUserReservedLocationAtIndex(int index);
  48. proto native void ClearUserReservedLocationForContainer(notnull EntityAI eai);
  49. proto native bool GetDebugFlag();
  50. /**
  51. * @fn CreateInInventory
  52. * @brief creates entity somewhere in inventory
  53. *
  54. * @param[in] type \p item type to be placed in inventory
  55. * @return created entity
  56. **/
  57. override EntityAI CreateInInventory(string type)
  58. {
  59. EntityAI newEntity = super.CreateInInventory(type);
  60. if (newEntity == null)
  61. newEntity = CreateInHands(type);
  62. return newEntity;
  63. }
  64. void ClearUserReservedLocationSynced(notnull EntityAI eai)
  65. {
  66. if (GetGame().IsClient())
  67. m_syncClearUserReservationindex = FindUserReservedLocationIndex(eai);
  68. else if (!GetGame().IsMultiplayer())
  69. {
  70. ClearUserReservedLocation(eai);
  71. eai.GetOnReleaseLock().Invoke(eai);
  72. }
  73. }
  74. void ClearUserReservedLocationAtIndexSynced(int index)
  75. {
  76. if (GetGame().IsClient())
  77. m_syncClearUserReservationindex = index;
  78. else if (!GetGame().IsMultiplayer())
  79. {
  80. ClearUserReservedLocationAtIndex(index);
  81. InventoryLocation il = new InventoryLocation();
  82. GetUserReservedLocation(index,il);
  83. EntityAI item = il.GetItem();
  84. item.GetOnReleaseLock().Invoke(item);
  85. }
  86. }
  87. Man GetManOwner()
  88. {
  89. return Man.Cast(GetInventoryOwner());
  90. }
  91. bool HasEntityInHands(EntityAI e)
  92. {
  93. return e == GetEntityInHands();
  94. }
  95. bool ProcessHandEvent(HandEventBase e);
  96. void OnHandsStateChanged(HandStateBase src, HandStateBase dst);
  97. void OnHandsExitedStableState(HandStateBase src, HandStateBase dst);
  98. void OnHandsEnteredStableState(HandStateBase src, HandStateBase dst);
  99. void OnEntityInHandsCreated(InventoryLocation src)
  100. {
  101. InventoryLocation cpy = new InventoryLocation();
  102. cpy.Copy(src);
  103. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] OnEntityInHandsCreated src=" + InventoryLocation.DumpToStringNullSafe(cpy));
  104. ProcessHandEvent(new HandEventCreated(GetManOwner(), src));
  105. }
  106. void OnEntityInHandsDestroyed(InventoryLocation src)
  107. {
  108. InventoryLocation cpy = new InventoryLocation();
  109. cpy.Copy(src);
  110. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] OnEntityInHandsDestroyed src=" + InventoryLocation.DumpToStringNullSafe(cpy));
  111. ProcessHandEvent(new HandEventDestroyed(GetManOwner(), cpy));
  112. }
  113. bool HandEvent(InventoryMode mode, HandEventBase e)
  114. {
  115. return true;
  116. }
  117. override bool DropEntity(InventoryMode mode, EntityAI owner, notnull EntityAI item)
  118. {
  119. InventoryLocation src = new InventoryLocation();
  120. if (item && item.GetInventory() && item.GetInventory().GetCurrentInventoryLocation(src))
  121. {
  122. switch (src.GetType())
  123. {
  124. case InventoryLocationType.HANDS:
  125. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::DropEntity(" + typename.EnumToString(InventoryMode, mode) + ") item=" + item);
  126. HandEvent(mode, new HandEventDrop(GetManOwner(), src));
  127. return true;
  128. default:
  129. return super.DropEntity(mode, owner, item);
  130. }
  131. }
  132. Error("No inventory location");
  133. return false;
  134. }
  135. bool ThrowEntity(EntityAI item, vector dir, float force)
  136. {
  137. if (GetGame().IsServer() && GetGame().IsMultiplayer())
  138. return false;
  139. DayZPlayer player = DayZPlayer.Cast(item.GetHierarchyRootPlayer());
  140. InventoryMode invMode = InventoryMode.PREDICTIVE;
  141. if (player.NeedInventoryJunctureFromServer(item, item.GetHierarchyParent(), null))
  142. invMode = InventoryMode.JUNCTURE;
  143. InventoryLocation src = new InventoryLocation();
  144. if (item && item.GetInventory() && item.GetInventory().GetCurrentInventoryLocation(src))
  145. {
  146. switch (src.GetType())
  147. {
  148. case InventoryLocationType.HANDS:
  149. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::ThrowEntity item=" + item);
  150. HandEventThrow throwEvent = new HandEventThrow(GetManOwner(), src);
  151. throwEvent.SetForce(dir * force);
  152. HandEvent(invMode, throwEvent);
  153. return true;
  154. default:
  155. DropEntity(invMode, player, item);
  156. return true;
  157. }
  158. }
  159. Error("No inventory location");
  160. return false;
  161. }
  162. bool RedirectToHandEvent(InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  163. {
  164. if (src.GetType() == InventoryLocationType.HANDS)
  165. {
  166. Man man_src = Man.Cast(src.GetParent());
  167. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HI::RedirectToHandEvent - source location == HANDS, player has to handle this");
  168. EntityAI item = src.GetItem();
  169. int r_index = FindUserReservedLocationIndex(item);
  170. if (r_index >= 0)
  171. {
  172. InventoryLocation r_il = new InventoryLocation();
  173. GetUserReservedLocation(r_index,r_il);
  174. ClearUserReservedLocationAtIndex(r_index);
  175. int r_type = r_il.GetType();
  176. if (r_type == InventoryLocationType.CARGO || r_type == InventoryLocationType.PROXYCARGO)
  177. {
  178. r_il.GetParent().GetOnReleaseLock().Invoke(item);
  179. }
  180. else if (r_type == InventoryLocationType.ATTACHMENT)
  181. {
  182. r_il.GetParent().GetOnAttachmentReleaseLock().Invoke(item, r_il.GetSlot());
  183. }
  184. }
  185. man_src.GetHumanInventory().HandEvent(mode, new HandEventMoveTo(man_src, src, dst));
  186. return true;
  187. }
  188. if (dst.GetType() == InventoryLocationType.HANDS)
  189. {
  190. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HI::RedirectToHandEvent - dst location == HANDS, player has to handle this");
  191. Man man_dst = Man.Cast(dst.GetParent());
  192. man_dst.GetHumanInventory().HandEvent(mode, new HandEventTake(man_dst, src));
  193. return true;
  194. }
  195. return false;
  196. }
  197. override bool TakeToDst(InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  198. {
  199. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] Take2Dst(" + typename.EnumToString(InventoryMode, mode) + ") src=" + InventoryLocation.DumpToStringNullSafe(src) + " dst=" + InventoryLocation.DumpToStringNullSafe(dst));
  200. if (GetManOwner().IsAlive() && RedirectToHandEvent(mode, src, dst))
  201. return true;
  202. return super.TakeToDst(mode, src, dst);
  203. }
  204. override bool TakeEntityToInventory(InventoryMode mode, FindInventoryLocationType flags, notnull EntityAI item)
  205. {
  206. InventoryLocation src = new InventoryLocation();
  207. if (item.GetInventory().GetCurrentInventoryLocation(src))
  208. {
  209. InventoryLocation dst = new InventoryLocation();
  210. if (FindFreeLocationFor(item, flags, dst))
  211. {
  212. if (RedirectToHandEvent(mode, src, dst))
  213. return true;
  214. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::Take2Inv(" + typename.EnumToString(InventoryMode, mode) + ") item=" + item);
  215. return super.TakeEntityToInventory(mode, flags, item);
  216. }
  217. else
  218. return false; // no room
  219. }
  220. Error("HumanInventory::TakeEntityToInventory: No inventory location");
  221. return false;
  222. }
  223. /**
  224. \brief Put item into into cargo on specific cargo location
  225. */
  226. override bool TakeEntityToCargoEx(InventoryMode mode, notnull EntityAI item, int idx, int row, int col)
  227. {
  228. InventoryLocation src = new InventoryLocation();
  229. if (item.GetInventory().GetCurrentInventoryLocation(src))
  230. {
  231. switch (src.GetType())
  232. {
  233. case InventoryLocationType.HANDS:
  234. if (GetInventoryOwner().IsAlive())
  235. {
  236. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::Take2Cgo(" + typename.EnumToString(InventoryMode, mode) + ") item=" + item + " row=" + row + " col=" + col);
  237. InventoryLocation dst = new InventoryLocation();
  238. dst.SetCargo(GetInventoryOwner(), item, idx, row, col, item.GetInventory().GetFlipCargo());
  239. HandEvent(mode, new HandEventMoveTo(GetManOwner(), src, dst));
  240. return true;
  241. }
  242. return super.TakeEntityToCargoEx(mode, item, idx, row, col);
  243. default:
  244. return super.TakeEntityToCargoEx(mode, item, idx, row, col);
  245. }
  246. }
  247. Error("HumanInventory::TakeEntityToCargoEx: No inventory location");
  248. return false;
  249. }
  250. override bool TakeEntityAsAttachmentEx(InventoryMode mode, notnull EntityAI item, int slot)
  251. {
  252. InventoryLocation src = new InventoryLocation();
  253. if (item.GetInventory().GetCurrentInventoryLocation(src))
  254. {
  255. switch (src.GetType())
  256. {
  257. case InventoryLocationType.HANDS:
  258. if (GetInventoryOwner().IsAlive())
  259. {
  260. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::Take2Att(" + typename.EnumToString(InventoryMode, mode) + ") item=" + item + " slot=" + slot);
  261. InventoryLocation dst = new InventoryLocation();
  262. EntityAI src_entity = GetInventoryOwner();
  263. dst.SetAttachment(src_entity, item, slot);
  264. HandEvent(mode, new HandEventMoveTo(GetManOwner(), src, dst));
  265. return true;
  266. }
  267. return super.TakeEntityAsAttachmentEx(mode, item, slot);
  268. default:
  269. return super.TakeEntityAsAttachmentEx(mode, item, slot);
  270. }
  271. }
  272. Error("HumanInventory::TakeEntityAsAttachmentEx: No inventory location");
  273. return false;
  274. }
  275. override bool SwapEntities(InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2)
  276. {
  277. InventoryLocation src1, src2, dst1, dst2;
  278. if (GameInventory.MakeSrcAndDstForSwap(item1, item2, src1, src2, dst1, dst2))
  279. {
  280. bool handled = false;
  281. switch (src1.GetType())
  282. {
  283. case InventoryLocationType.HANDS:
  284. //! returns item to previous location, if available
  285. InventoryLocation fswap_dst2 = new InventoryLocation;
  286. if ( SwappingToPreviousLocation(item1, item2, fswap_dst2) )
  287. {
  288. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::Swap HandEventForceSwap(" + typename.EnumToString(InventoryMode, mode) + ") IH=src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2));
  289. HandEvent(mode, new HandEventForceSwap(GetManOwner(), src1, src2, dst1, fswap_dst2));
  290. }
  291. else
  292. {
  293. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::Swap HandEventSwap(" + typename.EnumToString(InventoryMode, mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + "src2=" + InventoryLocation.DumpToStringNullSafe(src2));
  294. HandEvent(mode, new HandEventSwap(GetManOwner(), src1, src2, dst1, dst2));
  295. }
  296. handled = true;
  297. break;
  298. }
  299. switch (src2.GetType())
  300. {
  301. case InventoryLocationType.HANDS:
  302. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::Swap HandEventSwap2(" + typename.EnumToString(InventoryMode, mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " IH=src2=" + InventoryLocation.DumpToStringNullSafe(src2));
  303. HandEvent(mode, new HandEventSwap(GetManOwner(), src2, src1, dst2, dst1));
  304. handled = true;
  305. break;
  306. }
  307. if (!handled)
  308. return super.SwapEntities(mode, item1, item2);
  309. return true;
  310. }
  311. Error("HumanInventory::SwapEntities: cannot create src1, src2, dst1, dst2");
  312. return false;
  313. }
  314. override bool ForceSwapEntities(InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation item2_dst)
  315. {
  316. InventoryLocation src1, src2, dst1;
  317. if (GameInventory.MakeSrcAndDstForForceSwap(item1, item2, src1, src2, dst1, item2_dst))
  318. {
  319. GameInventory manOwnerInventory = GetManOwner().GetInventory();
  320. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::FSwap(" + typename.EnumToString(InventoryMode, mode) + ") dst1=" + InventoryLocation.DumpToStringNullSafe(dst1)+ " dst2=" + InventoryLocation.DumpToStringNullSafe(item2_dst));
  321. bool handled = false;
  322. switch (src1.GetType())
  323. {
  324. case InventoryLocationType.HANDS:
  325. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::FSwap-HND@1(" + typename.EnumToString(InventoryMode, mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) + " item2_dst=" + InventoryLocation.DumpToStringNullSafe(item2_dst));
  326. HandEventBase e = new HandEventForceSwap(GetManOwner(), src1, src2, dst1, item2_dst);
  327. e.ReserveInventory();
  328. HandEvent(mode, e);
  329. handled = true;
  330. break;
  331. }
  332. switch (src2.GetType())
  333. {
  334. case InventoryLocationType.HANDS:
  335. //! returns item to previous location, if available
  336. InventoryLocation fswap_dst2 = new InventoryLocation;
  337. if ( SwappingToPreviousLocation(item2, item1, fswap_dst2))
  338. {
  339. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::FSwap-PREV(" + typename.EnumToString(InventoryMode, mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) + " fswap_dst2=" + InventoryLocation.DumpToStringNullSafe(fswap_dst2));
  340. HandEvent(mode, new HandEventForceSwap(GetManOwner(), src1, src2, dst1, fswap_dst2));
  341. }
  342. else
  343. {
  344. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::FSwap-HND@2(" + typename.EnumToString(InventoryMode, mode) + ") src1=" + InventoryLocation.DumpToStringNullSafe(src1) + " src2=" + InventoryLocation.DumpToStringNullSafe(src2) + " dst1=" + InventoryLocation.DumpToStringNullSafe(dst1) + " item2_dst=" + InventoryLocation.DumpToStringNullSafe(item2_dst));
  345. HandEvent(mode, new HandEventForceSwap(GetManOwner(), src1, src2, dst1, item2_dst));
  346. }
  347. handled = true;
  348. break;
  349. }
  350. bool returnValue = true;
  351. if (!handled)
  352. returnValue = super.ForceSwapEntities(mode, item1, item2, item2_dst);
  353. return returnValue;
  354. }
  355. Error("HumanInventory::ForceSwapEntities: No inventory location");
  356. return false;
  357. }
  358. override bool LocalDestroyEntity(notnull EntityAI item)
  359. {
  360. InventoryLocation src = new InventoryLocation();
  361. if (item.GetInventory().GetCurrentInventoryLocation(src))
  362. {
  363. switch (src.GetType())
  364. {
  365. case InventoryLocationType.HANDS:
  366. if (GetInventoryOwner().IsAlive())
  367. {
  368. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::LocalDestroy inv item=" + item);
  369. HandEvent(InventoryMode.LOCAL, new HandEventDestroy(GetManOwner(), src));
  370. return true;
  371. }
  372. return super.LocalDestroyEntity(item);
  373. default:
  374. return super.LocalDestroyEntity(item);
  375. }
  376. }
  377. Error("LocalDestroyEntity: No inventory location");
  378. return false;
  379. }
  380. override bool ReplaceItemWithNew(InventoryMode mode, ReplaceItemWithNewLambdaBase lambda)
  381. {
  382. EntityAI itemInHands = GetEntityInHands();
  383. if (itemInHands == lambda.m_OldItem)
  384. return ReplaceItemInHandsWithNew(mode, lambda);
  385. return super.ReplaceItemWithNew(mode, lambda);
  386. }
  387. bool ReplaceItemElsewhereWithNewInHands(InventoryMode mode, ReplaceItemWithNewLambdaBase lambda)
  388. {
  389. return ReplaceItemInElsewhereWithNewinHandsImpl(mode, new HandEventDestroyElsewhereAndReplaceWithNewInHands(GetManOwner(), null, lambda));
  390. }
  391. protected bool ReplaceItemInElsewhereWithNewinHandsImpl(InventoryMode mode, HandEventBase e)
  392. {
  393. if (GetEntityInHands())
  394. {
  395. Error("[inv] HumanInventory::ReplaceItemInElsewhereWithNewinHandsImpl Item in hands, event=" + e.DumpToString());
  396. return false;
  397. }
  398. InventoryLocation dst = e.GetDst();
  399. if (dst)
  400. {
  401. switch (dst.GetType())
  402. {
  403. case InventoryLocationType.HANDS:
  404. if (GetInventoryOwner().IsAlive())
  405. {
  406. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::ReplaceItemInElsewhereWithNewinHandsImpl event=" + e);
  407. HandEvent(mode, e);
  408. return true;
  409. }
  410. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::ReplaceItemInElsewhereWithNewinHandsImpl DEAD_owner=" + GetInventoryOwner().GetName() +"="+ GetInventoryOwner());
  411. Error("HumanInventory::ReplaceItemInElsewhereWithNewinHandsImpl TODO"); // replace-with-new in corpse's hands, not implemented
  412. return false;
  413. default:
  414. Error("[inv] HumanInventory::ReplaceItemInElsewhereWithNewinHandsImpl src has to be hands");
  415. return false;
  416. }
  417. }
  418. Error("[inv] HumanInventory::ReplaceItemInElsewhereWithNewinHandsImpl no dst in event, event=" + e.DumpToString());
  419. return false;
  420. }
  421. protected bool ReplaceItemInHandsWithNewImpl(InventoryMode mode, HandEventBase e)
  422. {
  423. EntityAI itemInHands = GetEntityInHands();
  424. InventoryLocation src = new InventoryLocation();
  425. if (itemInHands && itemInHands.GetInventory().GetCurrentInventoryLocation(src))
  426. {
  427. switch (src.GetType())
  428. {
  429. case InventoryLocationType.HANDS:
  430. if ((mode != InventoryMode.SERVER) && GetInventoryOwner().IsAlive())
  431. {
  432. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::ReplaceItemInHandsWithNewImpl event=" + e);
  433. HandEvent(mode, e);
  434. return true;
  435. }
  436. if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] HumanInventory::ReplaceItemInHandsWithNewImpl DEAD_owner=" + GetInventoryOwner().GetName() +"="+ GetInventoryOwner());
  437. HandEvent(mode, e);
  438. return true;
  439. default:
  440. Error("[inv] HumanInventory::ReplaceItemInHandsWithNewImpl src has to be hands");
  441. return false;
  442. }
  443. }
  444. Error("[inv] HumanInventory::ReplaceItemInHandsWithNewImpl No item in hands, event=" + e.DumpToString());
  445. return false;
  446. }
  447. bool ReplaceItemInHandsWithNew(InventoryMode mode, ReplaceItemWithNewLambdaBase lambda)
  448. {
  449. return ReplaceItemInHandsWithNewImpl(mode, new HandEventDestroyAndReplaceWithNew(GetManOwner(), null, lambda));
  450. }
  451. bool ReplaceItemInHandsWithNewElsewhere(InventoryMode mode, ReplaceItemWithNewLambdaBase lambda)
  452. {
  453. return ReplaceItemInHandsWithNewImpl(mode, new HandEventDestroyAndReplaceWithNewElsewhere(GetManOwner(), null, lambda));
  454. }
  455. bool SwappingToPreviousLocation(EntityAI item1, EntityAI item2, out InventoryLocation dst)
  456. {
  457. bool SwapToPrevious = true;
  458. InventoryLocation src1 = new InventoryLocation();
  459. InventoryLocation src2 = new InventoryLocation();
  460. dst = new InventoryLocation();
  461. if (item1.GetInventory().GetCurrentInventoryLocation(src1) && item2.GetInventory().GetCurrentInventoryLocation(src2))
  462. {
  463. if (item1.m_OldLocation && item1.m_OldLocation.IsValid() && !item1.m_OldLocation.CollidesWith(src2) && item1.m_OldLocation.GetParent() && item1.m_OldLocation.GetParent().GetHierarchyRootPlayer())
  464. {
  465. dst.Copy(item1.m_OldLocation);
  466. int count = item1.GetInventory().GetSlotIdCount();
  467. if (count > 0 && src2.GetType() == InventoryLocationType.ATTACHMENT) //item2 is currently attached somewhere
  468. {
  469. for (int i = 0; i < count; i++)
  470. {
  471. int slotID = item1.GetInventory().GetSlotId(i);
  472. if (src2.GetSlot() == slotID) //can be attached into the same slot. And will be.
  473. return false;
  474. }
  475. }
  476. if (!item1.m_OldLocation.GetParent().GetInventory().LocationCanAddEntity(item1.m_OldLocation))
  477. SwapToPrevious = false;
  478. if (CanSwapEntitiesEx(item1,item2))
  479. SwapToPrevious = false;
  480. if (SwapToPrevious)
  481. return true;
  482. }
  483. }
  484. return false;
  485. }
  486. void HandleInventoryManipulation();
  487. void Update(float delta_time)
  488. {
  489. HandleInventoryManipulation();
  490. if ( m_syncClearUserReservationindex != -1 && ScriptInputUserData.CanStoreInputUserData())
  491. {
  492. ScriptInputUserData ctx = new ScriptInputUserData();
  493. ctx.Write(INPUT_UDT_INVENTORY);
  494. ctx.Write(InventoryCommandType.USER_RESERVATION_CANCEL);
  495. ctx.Write(m_syncClearUserReservationindex);
  496. ctx.Send();
  497. InventoryLocation il = new InventoryLocation();
  498. GetUserReservedLocation(m_syncClearUserReservationindex,il);
  499. ClearUserReservedLocationAtIndex(m_syncClearUserReservationindex);
  500. EntityAI item = il.GetItem();
  501. item.GetOnReleaseLock().Invoke(item);
  502. m_syncClearUserReservationindex = -1;
  503. }
  504. }
  505. bool ValidateUserReservationCancel(inout Serializer ctx, InventoryValidation validation)
  506. {
  507. validation.m_Result = InventoryValidationResult.SUCCESS;
  508. int index = -1;
  509. if (!ctx.Read(index))
  510. {
  511. //! TODO(kumarjac): It returned true and claimed success before, is this correct?
  512. return true;
  513. }
  514. ClearUserReservedLocationAtIndex(index);
  515. //m_UserReservationToClear = index;
  516. return true;
  517. }
  518. bool PostDeferredEventTakeToDst(InventoryMode mode, notnull InventoryLocation src, notnull InventoryLocation dst)
  519. {
  520. return true;
  521. }
  522. bool PostDeferredForceSwapEntities(InventoryMode mode, notnull EntityAI item1, notnull EntityAI item2, notnull InventoryLocation dst1, notnull InventoryLocation dst2)
  523. {
  524. return true;
  525. }
  526. }