DIFF

ActionAttachOnSelection.c

class ActionAttachOnSelection: ActionSingleUseBase
{
	void ActionAttachOnSelection()
	{
		m_Text = "#attach";
	}
	
	override void CreateConditionComponents() 
	{
		m_ConditionItem 	= new CCINonRuined();
		m_ConditionTarget 	= new CCTCursor();
	}
	
	override ActionData CreateActionData()
	{
		AttachActionData action_data = new AttachActionData();
		return action_data;
	}
	
	int FindSlotIdToAttachOrCombine(PlayerBase player, ActionTarget target, ItemBase item)
	{
		EntityAI targetEntity = EntityAI.Cast(target.GetObject());
		if (targetEntity && item)
		{				
			GameInventory inv = targetEntity.GetInventory();
			if (!inv)
				return InventorySlots.INVALID;

			int slotsCount = item.GetInventory().GetSlotIdCount();			
			array<string> selections = new array<string>();
			targetEntity.GetActionComponentNameList(target.GetComponentIndex(), selections);

			foreach (string selection : selections)
			{
				int slotId = -1;
				if (!targetEntity.TranslateSlotFromSelection(selection, slotId))
					slotId = InventorySlots.GetSlotIdFromString(selection);

				if (slotId == -1)
					continue;

				for (int i=0; i < slotsCount; ++i)
				{
					int itemSlotId = item.GetInventory().GetSlotId(i);
					if (slotId == itemSlotId)
					{
						ItemBase currentAttachment = ItemBase.Cast(inv.FindAttachment(slotId));
						if (currentAttachment)
						{
							if (currentAttachment.CanBeCombined(item))
								return itemSlotId;
						}
						else
						{
							if (inv.CanAddAttachment(item))
								return itemSlotId;
						}	
					}
				}
			}
		}

		return InventorySlots.INVALID;
	}
	
	
	override bool SetupAction(PlayerBase player, ActionTarget target, ItemBase item, out ActionData action_data, Param extra_data = null)
	{
		int attSlotId = InventorySlots.INVALID;
		if (!g_Game.IsDedicatedServer() )
		{
			attSlotId = FindSlotIdToAttachOrCombine(player, target, item);
		}
		
		if (super.SetupAction( player, target, item, action_data, extra_data))
		{
			if (!g_Game.IsDedicatedServer())
			{
				if (attSlotId != InventorySlots.INVALID)
				{
					AttachActionData action_data_a = AttachActionData.Cast(action_data);
					action_data_a.m_AttSlot = attSlotId;
					
					return true;
				}

				return false;
			}

			return true;
		}

		return false;
	}

	override bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item)
	{
		if (g_Game.IsMultiplayer() && g_Game.IsServer())
			return true;
		
		if (target.GetObject() && target.GetObject().CanUseConstruction())
			return false;
		
		return FindSlotIdToAttachOrCombine(player, target, item) != InventorySlots.INVALID;
	}

	override void OnExecuteServer( ActionData action_data )
	{
		if (g_Game.IsMultiplayer())
			return;
		
		ClearInventoryReservationEx(action_data);
		
		AttachActionData action_data_a = AttachActionData.Cast(action_data);
		EntityAI entity;

		if (action_data.m_Target.IsProxy())
		{
			entity = EntityAI.Cast(action_data.m_Target.GetParent());
		}
		else
		{
			entity = EntityAI.Cast(action_data.m_Target.GetObject());
		}
		
		if (entity && action_data.m_MainItem)
		{
			action_data.m_Player.PredictiveTakeEntityToTargetAttachmentEx(entity, action_data_a.m_MainItem, action_data_a.m_AttSlot);
		}
	}
	
	override void OnExecuteClient(ActionData action_data)
	{
		ClearInventoryReservationEx(action_data);
		EntityAI targetEntity 	= EntityAI.Cast(action_data.m_Target.GetObject());
		EntityAI itemEntity 	= action_data.m_MainItem;
		
		AttachActionData action_data_a = AttachActionData.Cast(action_data);
		
		ItemBase attachment = ItemBase.Cast(targetEntity.GetInventory().FindAttachment(action_data_a.m_AttSlot));
		if (attachment)
		{
			attachment.CombineItemsClient(itemEntity);
		}
		else
		{
			ItemBase item_base	= ItemBase.Cast( itemEntity );
			float stackable	= item_base.GetTargetQuantityMax( action_data_a.m_AttSlot );
				
			if (stackable == 0 || stackable >= item_base.GetQuantity())
			{
				action_data.m_Player.PredictiveTakeEntityToTargetAttachmentEx(targetEntity, itemEntity, action_data_a.m_AttSlot);
			}
			else if (stackable != 0 && stackable < item_base.GetQuantity())
			{
				item_base.SplitIntoStackMaxClient(targetEntity, action_data_a.m_AttSlot);
			}
		}
	}
}