actionattachonselection.c 4.2 KB

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