actionattachonselection.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. class ActionAttachOnSelection: ActionSingleUseBase
  2. {
  3. void ActionAttachOnSelection()
  4. {
  5. m_Text = "#attach";
  6. }
  7. override void CreateConditionComponents()
  8. {
  9. m_ConditionItem = new CCINonRuined();
  10. m_ConditionTarget = new CCTCursor();
  11. }
  12. override ActionData CreateActionData()
  13. {
  14. AttachActionData action_data = new AttachActionData();
  15. return action_data;
  16. }
  17. int FindSlotIdToAttachOrCombine(PlayerBase player, ActionTarget target, ItemBase item)
  18. {
  19. EntityAI targetEntity = EntityAI.Cast(target.GetObject());
  20. if (targetEntity && item)
  21. {
  22. GameInventory inv = targetEntity.GetInventory();
  23. if (!inv)
  24. return InventorySlots.INVALID;
  25. int slotsCount = item.GetInventory().GetSlotIdCount();
  26. array<string> selections = new array<string>();
  27. targetEntity.GetActionComponentNameList(target.GetComponentIndex(), selections);
  28. foreach (string selection : selections)
  29. {
  30. int slotId = -1;
  31. if (!targetEntity.TranslateSlotFromSelection(selection, slotId))
  32. slotId = InventorySlots.GetSlotIdFromString(selection);
  33. if (slotId == -1)
  34. continue;
  35. for (int i=0; i < slotsCount; ++i)
  36. {
  37. int itemSlotId = item.GetInventory().GetSlotId(i);
  38. if (slotId == itemSlotId)
  39. {
  40. ItemBase currentAttachment = ItemBase.Cast(inv.FindAttachment(slotId));
  41. if (currentAttachment)
  42. {
  43. if (currentAttachment.CanBeCombined(item))
  44. return itemSlotId;
  45. }
  46. else
  47. {
  48. if (inv.CanAddAttachment(item))
  49. return itemSlotId;
  50. }
  51. }
  52. }
  53. }
  54. }
  55. return InventorySlots.INVALID;
  56. }
  57. override bool SetupAction(PlayerBase player, ActionTarget target, ItemBase item, out ActionData action_data, Param extra_data = null)
  58. {
  59. int attSlotId = InventorySlots.INVALID;
  60. if (!GetGame().IsDedicatedServer() )
  61. {
  62. attSlotId = FindSlotIdToAttachOrCombine(player, target, item);
  63. }
  64. if (super.SetupAction( player, target, item, action_data, extra_data))
  65. {
  66. if (!GetGame().IsDedicatedServer())
  67. {
  68. if (attSlotId != InventorySlots.INVALID)
  69. {
  70. AttachActionData action_data_a = AttachActionData.Cast(action_data);
  71. action_data_a.m_AttSlot = attSlotId;
  72. return true;
  73. }
  74. return false;
  75. }
  76. return true;
  77. }
  78. return false;
  79. }
  80. override bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item)
  81. {
  82. if (GetGame().IsMultiplayer() && GetGame().IsServer())
  83. return true;
  84. if (target.GetObject() && target.GetObject().CanUseConstruction())
  85. return false;
  86. return FindSlotIdToAttachOrCombine(player, target, item) != InventorySlots.INVALID;
  87. }
  88. override void OnExecuteServer( ActionData action_data )
  89. {
  90. if (GetGame().IsMultiplayer())
  91. return;
  92. ClearInventoryReservationEx(action_data);
  93. AttachActionData action_data_a = AttachActionData.Cast(action_data);
  94. EntityAI entity;
  95. if (action_data.m_Target.IsProxy())
  96. {
  97. entity = EntityAI.Cast(action_data.m_Target.GetParent());
  98. }
  99. else
  100. {
  101. entity = EntityAI.Cast(action_data.m_Target.GetObject());
  102. }
  103. if (entity && action_data.m_MainItem)
  104. {
  105. action_data.m_Player.PredictiveTakeEntityToTargetAttachmentEx(entity, action_data_a.m_MainItem, action_data_a.m_AttSlot);
  106. }
  107. }
  108. override void OnExecuteClient(ActionData action_data)
  109. {
  110. ClearInventoryReservationEx(action_data);
  111. EntityAI targetEntity = EntityAI.Cast(action_data.m_Target.GetObject());
  112. EntityAI itemEntity = action_data.m_MainItem;
  113. AttachActionData action_data_a = AttachActionData.Cast(action_data);
  114. ItemBase attachment = ItemBase.Cast(targetEntity.GetInventory().FindAttachment(action_data_a.m_AttSlot));
  115. if (attachment)
  116. {
  117. attachment.CombineItemsClient(itemEntity);
  118. }
  119. else
  120. {
  121. ItemBase item_base = ItemBase.Cast( itemEntity );
  122. float stackable = item_base.GetTargetQuantityMax( action_data_a.m_AttSlot );
  123. if (stackable == 0 || stackable >= item_base.GetQuantity())
  124. {
  125. action_data.m_Player.PredictiveTakeEntityToTargetAttachmentEx(targetEntity, itemEntity, action_data_a.m_AttSlot);
  126. }
  127. else if (stackable != 0 && stackable < item_base.GetQuantity())
  128. {
  129. item_base.SplitIntoStackMaxClient(targetEntity, action_data_a.m_AttSlot);
  130. }
  131. }
  132. }
  133. }