const int ITEMS_IN_ROW = 8; class Attachments { protected Container m_Parent; protected EntityAI m_Entity; protected ref AttachmentsWrapper m_AttachmentsContainer; protected ref array m_AttachmentSlotNames; protected ref array m_AttachmentSlotDisplayable; protected ref map m_AttachmentSlots; protected ref array m_AttachmentIDOrdered; protected int m_RowIndex; protected int m_AttachmentSlotID = -1; void Attachments( Container parent, EntityAI entity ) { m_Parent = parent; m_Entity = entity; m_AttachmentSlots = new map; m_AttachmentIDOrdered = new array; m_AttachmentSlotNames = GetItemSlots( entity ); m_AttachmentSlotDisplayable = new array; m_Entity.GetOnItemAttached().Insert( AttachmentAdded ); m_Entity.GetOnItemDetached().Insert( AttachmentRemoved ); m_Entity.GetOnAttachmentSetLock().Insert( OnAttachmentReservationSet ); m_Entity.GetOnAttachmentReleaseLock().Insert( OnAttachmentReservationRelease ); } void ~Attachments() { if( m_Entity ) { m_Entity.GetOnItemAttached().Remove( AttachmentAdded ); m_Entity.GetOnItemDetached().Remove( AttachmentRemoved ); m_Entity.GetOnAttachmentSetLock().Remove( OnAttachmentReservationSet ); m_Entity.GetOnAttachmentReleaseLock().Remove( OnAttachmentReservationRelease ); } delete m_AttachmentsContainer; } AttachmentsWrapper GetWrapper() { return m_AttachmentsContainer; } bool IsEmpty() { return m_AttachmentsContainer.IsEmpty(); } bool IsItemActive() { ItemBase item = ItemBase.Cast( GetFocusedItem() ); if( !item ) { return false; } return !IsEmpty() && ( !QuantityConversions.HasItemQuantity( item ) || ( QuantityConversions.HasItemQuantity( item ) && !item.CanBeSplit() ) ); } bool IsItemWithQuantityActive() { ItemBase item = ItemBase.Cast( GetFocusedItem() ); if( !item ) { return false; } return !IsEmpty() && QuantityConversions.HasItemQuantity( item ) && item.CanBeSplit(); } void UnfocusAll() { m_AttachmentsContainer.UnfocusAll(); } void SetDefaultFocus( bool while_micromanagment_mode = false ) { m_AttachmentsContainer.SetDefaultFocus(while_micromanagment_mode); } void SetLastActive() { m_AttachmentsContainer.SetLastActive(); } void SetActive( bool active ) { m_AttachmentsContainer.SetActive(active); } void SelFirstActive() { m_AttachmentsContainer.SetFirstActive(); } SlotsIcon GetFocusedSlotsIcon() { return m_AttachmentsContainer.GetFocusedSlotsIcon(); } EntityAI GetFocusedItem() { return m_AttachmentsContainer.GetFocusedItem(); } int GetFocusedSlot() { SlotsIcon icon = m_AttachmentsContainer.GetFocusedSlotsIcon(); if (icon) return icon.GetSlotID(); return -1; } bool SelectItem() { ItemBase item = ItemBase.Cast( GetFocusedItem() ); SlotsIcon icon = GetFocusedSlotsIcon(); if (icon && !icon.IsOutOfReach()) { if (item && item.CanPutIntoHands(null)) { ItemManager.GetInstance().SetSelectedItemEx(item, null, icon); } else { ItemManager.GetInstance().SetSelectedItemEx(null, null, icon); } return true; } return false; } bool Select() { SlotsIcon selected_slot = ItemManager.GetInstance().GetSelectedIcon(); EntityAI selected_item = ItemManager.GetInstance().GetSelectedItem(); SlotsIcon focused_slot = GetFocusedSlotsIcon(); EntityAI focused_item = GetFocusedItem(); Man player = GetGame().GetPlayer(); if( focused_slot.IsReserved() || focused_item != selected_item && !(selected_slot && selected_slot.IsOutOfReach() ) ) { if( selected_item ) { if( selected_item.GetInventory().CanRemoveEntity() ) { if( m_Entity.GetInventory().CanAddAttachmentEx( selected_item, focused_slot.GetSlotID() ) ) { player.PredictiveTakeEntityToTargetAttachmentEx( m_Entity, selected_item, focused_slot.GetSlotID() ); ItemManager.GetInstance().SetSelectedItemEx(null, null, null); return true; } else if( m_Entity.GetInventory().CanAddAttachment( selected_item ) ) { player.PredictiveTakeEntityToTargetAttachment(m_Entity, selected_item); ItemManager.GetInstance().SetSelectedItemEx(null, null, null); return true; } } } else { if ( focused_item && !focused_slot.IsOutOfReach() ) { EntityAI item_in_hands = GetGame().GetPlayer().GetHumanInventory().GetEntityInHands(); InventoryLocation il = new InventoryLocation; focused_item.GetInventory().GetCurrentInventoryLocation( il ); bool reachable = AttachmentsOutOfReach.IsAttachmentReachable( m_Entity, "", il.GetSlot() ); if( reachable && focused_item.GetInventory().CanRemoveEntity() ) { if( item_in_hands && item_in_hands.GetInventory().CanRemoveEntity() ) { if( GameInventory.CanSwapEntitiesEx( item_in_hands, focused_item ) ) { player.PredictiveSwapEntities( item_in_hands, focused_item ); return true; } } else { if( player.GetHumanInventory().CanAddEntityInHands( focused_item ) ) { player.PredictiveTakeEntityToHands( focused_item ); return true; } } } } } } return false; } int GetRecipeCount( bool recipe_anywhere, EntityAI entity1, EntityAI entity2 ) { PluginRecipesManager plugin_recipes_manager = PluginRecipesManager.Cast( GetPlugin( PluginRecipesManager ) ); return plugin_recipes_manager.GetValidRecipes( ItemBase.Cast( entity1 ), ItemBase.Cast( entity2 ), null, PlayerBase.Cast( GetGame().GetPlayer() ) ); } bool CanCombine() { ItemBase ent = ItemBase.Cast( GetFocusedItem() ); ItemBase item_in_hands = ItemBase.Cast( GetGame().GetPlayer().GetHumanInventory().GetEntityInHands() ); return ( ItemManager.GetCombinationFlags( item_in_hands, ent ) != 0 ); } bool CanCombineAmmo() { PlayerBase m_player = PlayerBase.Cast( GetGame().GetPlayer() ); ItemBase ent = ItemBase.Cast( GetFocusedItem() ); ItemBase item_in_hands = ItemBase.Cast( GetGame().GetPlayer().GetHumanInventory().GetEntityInHands() ); ActionManagerClient amc; Class.CastTo(amc, m_player.GetActionManager()); return ( amc.CanPerformActionFromInventory( item_in_hands, ent ) ); } bool CanEquip() { EntityAI entity = ItemBase.Cast( GetFocusedItem() ); InventoryLocation il = new InventoryLocation; if( !entity || entity.IsInherited( Magazine ) ) { return false; } return GetGame().GetPlayer().GetInventory().FindFreeLocationFor( entity, FindInventoryLocationType.ATTACHMENT, il ); } bool Combine() { ItemBase ent = ItemBase.Cast( GetFocusedItem() ); ItemBase item_in_hands = ItemBase.Cast( GetGame().GetPlayer().GetHumanInventory().GetEntityInHands() ); Icon hands_icon = ItemManager.GetInstance().GetHandsPreview().GetIcon(); if ( item_in_hands && ent && hands_icon ) { return hands_icon.CombineItems( item_in_hands, ent ); } return false; } bool SplitItem() { ItemBase entity = ItemBase.Cast( GetFocusedItem() ); if( entity && !entity.IsInherited( Magazine ) && !GetFocusedSlotsIcon().IsOutOfReach() ) { if( entity.HasQuantity() ) { entity.OnRightClick(); return true; } } return false; } bool EquipItem() { ItemBase entity = ItemBase.Cast( GetFocusedItem() ); if( entity && !entity.IsInherited( Magazine ) && !GetFocusedSlotsIcon().IsOutOfReach() ) { GetGame().GetPlayer().PredictiveTakeEntityToInventory( FindInventoryLocationType.ATTACHMENT, entity ); return true; } return false; } bool TransferItem() { EntityAI entity = GetFocusedItem(); if( entity && !GetFocusedSlotsIcon().IsOutOfReach() ) { GetGame().GetPlayer().PredictiveTakeEntityToInventory( FindInventoryLocationType.CARGO, entity ); return true; } return false; } bool InspectItem() { EntityAI entity = GetFocusedItem(); if( entity ) { m_Parent.InspectItem( entity ); return true; } return false; } bool TransferItemToVicinity() { ItemBase item = ItemBase.Cast(GetFocusedItem()); PlayerBase player = PlayerBase.Cast( GetGame().GetPlayer()); if (item && !GetFocusedSlotsIcon().IsOutOfReach() ) { if (item.GetTargetQuantityMax() < item.GetQuantity()) item.SplitIntoStackMaxClient( null, -1 ); else player.PhysicalPredictiveDropItem(item); return true; } return false; } bool IsActive() { return m_Parent.GetMainWidget().FindAnyWidget("AttachmentsWrapper").GetAlpha() > 0; } int GetAttachmentHeight() { return m_AttachmentsContainer.Count(); } void UpdateInterval() { SlotsIcon icon; int slot_id; m_AttachmentSlotDisplayable.Clear(); int i = 0; for (i = m_AttachmentSlotNames.Count() - 1; i >=0; --i) { slot_id = InventorySlots.GetSlotIdFromString( m_AttachmentSlotNames[i] ); if (m_Entity.CanDisplayAttachmentSlot(slot_id)) { m_AttachmentSlotDisplayable.Insert(m_AttachmentSlotNames[i]); } else { icon = m_AttachmentSlots.Get( slot_id ); if (icon) { icon.GetMainWidget().Show( false ); if( GetFocusedSlotsIcon() == icon ) { SetDefaultFocus(); } // radial icon (collabsable icon handling) icon.UpdateInterval(); } } } if ( m_AttachmentSlotDisplayable.Count() == 0 ) { if (m_Parent) { m_Parent.UpdateRadialIcon(); //m_Parent.Close(); } } for (i = 0; i < m_AttachmentSlotDisplayable.Count(); ++i) { slot_id = InventorySlots.GetSlotIdFromString( m_AttachmentSlotDisplayable[i] ); icon = m_AttachmentSlots.Get( slot_id ); EntityAI item = icon.GetEntity(); icon.GetMainWidget().Show( true ); icon.UpdateInterval(); if ( item ) { bool draggable = true; if(icon.IsReserved()) { draggable = false; } if( m_Entity.GetInventory().GetSlotLock( slot_id ) && ItemManager.GetInstance().GetDraggedItem() != item ) { icon.GetMountedWidget().Show( true ); draggable = false; } else { icon.GetMountedWidget().Show( false ); } PlayerBase p = PlayerBase.Cast( GetGame().GetPlayer() ); bool in_hands_condition = m_Entity.GetHierarchyRoot() && item.GetInventory().CanRemoveEntity(); bool in_vicinity_condition = !m_Entity.GetHierarchyRoot() && AttachmentsOutOfReach.IsAttachmentReachable( m_Entity, m_AttachmentSlotDisplayable[i] ); if( in_hands_condition || in_vicinity_condition ) { icon.GetOutOfReachWidget().Show( false ); } else { icon.GetOutOfReachWidget().Show( true ); draggable = false; } if( draggable ) { icon.GetPanelWidget().SetFlags( WidgetFlags.DRAGGABLE ); } else { icon.GetPanelWidget().ClearFlags( WidgetFlags.DRAGGABLE ); } } } m_AttachmentsContainer.GetRootWidget().Update(); } array GetSlotsSorted() { return m_AttachmentIDOrdered; } void AttachmentAdded(EntityAI item, string slot, EntityAI parent) { int slot_id = InventorySlots.GetSlotIdFromString(slot); SlotsIcon icon = m_AttachmentSlots.Get(slot_id); if (icon) { icon.SetSlotID(slot_id); icon.SetSlotDisplayName(InventorySlots.GetSlotDisplayName(slot_id)); if (item) { icon.Init(item); } } } void AttachmentRemoved(EntityAI item, string slot, EntityAI parent) { int slot_id = InventorySlots.GetSlotIdFromString(slot); SlotsIcon icon = m_AttachmentSlots.Get(slot_id); if (icon) { icon.Clear(); } } void OnAttachmentReservationSet( EntityAI item, int slot_id ) { SlotsIcon icon = m_AttachmentSlots.Get( slot_id ); if (item) { icon.Init( item, true ); } } void OnAttachmentReservationRelease( EntityAI item, int slot_id ) { SlotsIcon icon = m_AttachmentSlots.Get( slot_id ); icon.Clear(); } void InitAttachmentGrid( int att_row_index ) { SlotsIcon icon; int i; m_RowIndex = att_row_index; int number_of_rows = Math.Ceil( m_AttachmentSlotNames.Count() / ITEMS_IN_ROW ); string name = m_Entity.GetDisplayName(); name.ToUpper(); m_AttachmentsContainer = new AttachmentsWrapper( m_Parent ); m_AttachmentsContainer.SetParent( this ); m_AttachmentsContainer.SetFalseAttachmentsHeaderText(name); m_AttachmentsContainer.GetRootWidget().SetSort( att_row_index ); m_Parent.Insert( m_AttachmentsContainer, att_row_index ); for ( i = 0; i < number_of_rows; i++ ) { SlotsContainer ic = new SlotsContainer( m_AttachmentsContainer, m_Entity ); m_AttachmentsContainer.Insert( ic ); if( i == ( number_of_rows - 1 ) && m_AttachmentSlotNames.Count() % ITEMS_IN_ROW != 0 ) { ic.SetColumnCount( m_AttachmentSlotNames.Count() % ITEMS_IN_ROW ); } else { ic.SetColumnCount( ITEMS_IN_ROW ); } for( int j = 0; j < ITEMS_IN_ROW; j++ ) { icon = ic.GetSlotIcon( j ); WidgetEventHandler.GetInstance().RegisterOnDropReceived( icon.GetMainWidget(), m_Parent, "OnDropReceivedFromHeader2" ); WidgetEventHandler.GetInstance().RegisterOnDropReceived( icon.GetGhostSlot(), m_Parent, "OnDropReceivedFromHeader2" ); WidgetEventHandler.GetInstance().RegisterOnDropReceived( icon.GetPanelWidget(), m_Parent, "OnDropReceivedFromHeader2" ); WidgetEventHandler.GetInstance().RegisterOnDraggingOver( icon.GetMainWidget(), m_Parent, "DraggingOverHeader" ); WidgetEventHandler.GetInstance().RegisterOnDraggingOver( icon.GetGhostSlot(), m_Parent, "DraggingOverHeader" ); WidgetEventHandler.GetInstance().RegisterOnDraggingOver( icon.GetPanelWidget(), m_Parent, "DraggingOverHeader" ); WidgetEventHandler.GetInstance().RegisterOnMouseButtonDown( icon.GetMainWidget(), m_Parent, "MouseClick2" ); WidgetEventHandler.GetInstance().RegisterOnMouseButtonDown( icon.GetGhostSlot(), m_Parent, "MouseClick2" ); WidgetEventHandler.GetInstance().RegisterOnMouseButtonDown( icon.GetPanelWidget(), m_Parent, "MouseClick2" ); } } for ( i = 0; i < m_AttachmentSlotNames.Count(); i++ ) { icon = SlotsContainer.Cast( m_AttachmentsContainer.Get( ( i / ITEMS_IN_ROW ) ) ).GetSlotIcon( i % ITEMS_IN_ROW ); WidgetEventHandler.GetInstance().RegisterOnDoubleClick( icon.GetPanelWidget(), m_Parent, "DoubleClick" ); string path = "CfgSlots" + " Slot_" + m_AttachmentSlotNames[i]; //Show different magazine icon for firearms and pistols if ( m_AttachmentSlotNames[i] == "magazine" ) { if ( !m_Entity.IsInherited( Pistol_Base ) ) path = "CfgSlots" + " Slot_" + "magazine2"; } string icon_name = ""; //icon_name must be in format "set: image:" if( GetGame().ConfigGetText( path + " ghostIcon", icon_name ) && icon_name != "" ) icon.GetGhostSlot().LoadImageFile( 0, StaticGUIUtils.VerifyIconImageString(StaticGUIUtils.IMAGESETGROUP_INVENTORY,icon_name) ); int slot_id = InventorySlots.GetSlotIdFromString( m_AttachmentSlotNames[i] ); m_AttachmentSlots.Insert( slot_id, icon ); m_AttachmentIDOrdered.Insert(slot_id); icon.SetSlotID(slot_id); icon.SetSlotDisplayName(InventorySlots.GetSlotDisplayName(slot_id)); EntityAI item = m_Entity.GetInventory().FindAttachment( slot_id ); if( item ) AttachmentAdded( item, m_AttachmentSlotNames[i], m_Entity ); else icon.Clear(); if (m_Entity.CanDisplayAttachmentSlot(slot_id)) { icon.GetMainWidget().Show( true ); } else { icon.GetMainWidget().Show( false ); } } if( m_AttachmentSlotNames.Count() > 0 ) { int row_index = number_of_rows - 1; SlotsContainer row_last = SlotsContainer.Cast( m_AttachmentsContainer.Get( row_index ) ); if( row_last ) { for( int k = ((m_AttachmentSlotNames.Count() - 1) % ITEMS_IN_ROW) + 1; k < ITEMS_IN_ROW; k++ ) { row_last.GetSlotIcon( k ).GetMainWidget().Show( false ); } row_last.GetRootWidget().Update(); row_last.GetRootWidget().GetParent().Update(); } } m_AttachmentsContainer.RecomputeOpenedContainers(); } array GetItemSlots( EntityAI e ) { TStringArray searching_in = new TStringArray; searching_in.Insert( CFG_VEHICLESPATH ); searching_in.Insert( CFG_WEAPONSPATH ); searching_in.Insert( CFG_MAGAZINESPATH ); array attachments_slots = new array; int i = 0; for ( int s = 0; s < searching_in.Count(); ++s ) { string cfg_name = searching_in.Get( s ); string path = cfg_name + " " + e.GetType(); if ( GetGame().ConfigIsExisting( path ) ) { GetGame().ConfigGetTextArray( path + " attachments", attachments_slots ); if ( e.IsWeapon() && (!e.ConfigIsExisting("DisplayMagazine") || e.ConfigGetBool("DisplayMagazine")) ) { attachments_slots.Insert( "magazine" ); } return attachments_slots; } } if ( e.IsWeapon() && (!e.ConfigIsExisting("DisplayMagazine") || e.ConfigGetBool("DisplayMagazine")) ) { attachments_slots.Insert( "magazine" ); } return attachments_slots; } void ShowFalseAttachmentsHeader(bool show) { m_AttachmentsContainer.ShowFalseAttachmentsHeader(show); } void SetFalseAttachmentsHeaderText(string text) { m_AttachmentsContainer.SetFalseAttachmentsHeaderText(text); } TextWidget GetFalseHeaderTextWidget() { return m_AttachmentsContainer.GetFalseHeaderTextWidget(); } void SetAttachmentSlotID(int slotID) { m_AttachmentSlotID = slotID; } int GetAttachmentSlotID() { return m_AttachmentSlotID; } }