using Barotrauma.Items.Components; using Barotrauma.Networking; using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; namespace Barotrauma { [Flags] public enum InvSlotType { None = 0, Any = 1, RightHand = 2, LeftHand = 4, Head = 8, Torso = 16, Legs = 32, Face=64, Card=128 }; partial class CharacterInventory : Inventory { private Character character; public static InvSlotType[] limbSlots = new InvSlotType[] { InvSlotType.Head, InvSlotType.Torso, InvSlotType.Legs, InvSlotType.LeftHand, InvSlotType.RightHand, InvSlotType.Face, InvSlotType.Card, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any}; public CharacterInventory(int capacity, Character character) : base(character, capacity) { this.character = character; InitProjSpecific(); } partial void InitProjSpecific(); private bool UseItemOnSelf(int slotIndex) { if (Items[slotIndex] == null) return false; #if CLIENT if (GameMain.Client != null) { GameMain.Client.CreateEntityEvent(Items[slotIndex], new object[] { NetEntityEvent.Type.ApplyStatusEffect }); return true; } #endif if (GameMain.Server != null) { GameMain.Server.CreateEntityEvent(Items[slotIndex], new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnUse, character.ID }); } Items[slotIndex].ApplyStatusEffects(ActionType.OnUse, 1.0f, character); foreach (ItemComponent ic in Items[slotIndex].components) { if (ic.DeleteOnUse) { Entity.Spawner.AddToRemoveQueue(Items[slotIndex]); } } return true; } public int FindLimbSlot(InvSlotType limbSlot) { for (int i = 0; i < Items.Length; i++) { if (limbSlots[i] == limbSlot) return i; } return -1; } public bool IsInLimbSlot(Item item, InvSlotType limbSlot) { for (int i = 0; i /// If there is room, puts the item in the inventory and returns true, otherwise returns false /// public override bool TryPutItem(Item item, Character user, List allowedSlots = null, bool createNetworkEvent = true) { if (allowedSlots == null || !allowedSlots.Any()) return false; for (int i = 0; i < capacity; i++) { //already in the inventory and in a suitable slot if (Items[i] == item && allowedSlots.Any(a => a.HasFlag(limbSlots[i]))) { return true; } } //try to place the item in LimBlot.Any slot if that's allowed if (allowedSlots.Contains(InvSlotType.Any)) { for (int i = 0; i < capacity; i++) { if (Items[i] != null || limbSlots[i] != InvSlotType.Any) continue; PutItem(item, i, user, true, createNetworkEvent); item.Unequip(character); return true; } } bool placed = false; foreach (InvSlotType allowedSlot in allowedSlots) { //check if all the required slots are free bool free = true; for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(limbSlots[i]) && Items[i] != null && Items[i] != item) { free = false; #if CLIENT if (slots != null) slots[i].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); #endif } } if (!free) continue; for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(limbSlots[i]) && Items[i] == null) { PutItem(item, i, user, !placed, createNetworkEvent); item.Equip(character); placed = true; } } if (placed) { return true; } } return placed; } public override bool TryPutItem(Item item, int index, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true) { //there's already an item in the slot if (Items[index] != null) { if (Items[index] == item) return false; bool combined = false; if (allowCombine && Items[index].Combine(item)) { System.Diagnostics.Debug.Assert(Items[index] != null); Inventory otherInventory = Items[index].ParentInventory; if (otherInventory != null && otherInventory.Owner!=null) { } combined = true; } //if moving the item between slots in the same inventory else if (item.ParentInventory == this && allowSwapping) { int currentIndex = Array.IndexOf(Items, item); Item existingItem = Items[index]; for (int i = 0; i < capacity; i++) { if (Items[i] == item || Items[i] == existingItem) Items[i] = null; } //if the item in the slot can be moved to the slot of the moved item if (TryPutItem(existingItem, currentIndex, false, false, user, createNetworkEvent) && TryPutItem(item, index, false, false, user, createNetworkEvent)) { #if CLIENT for (int i = 0; i < capacity; i++) { if (Items[i] == item || Items[i] == existingItem) { slots[i].ShowBorderHighlight(Color.Green, 0.1f, 0.9f); } } #endif } else { for (int i = 0; i < capacity; i++) { if (Items[i] == item || Items[i] == existingItem) Items[i] = null; } //swapping the items failed -> move them back to where they were TryPutItem(item, currentIndex, false, false, user, createNetworkEvent); TryPutItem(existingItem, index, false, false, user, createNetworkEvent); #if CLIENT for (int i = 0; i < capacity; i++) { if (Items[i] == existingItem) { slots[i].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); } } #endif } } return combined; } if (limbSlots[index] == InvSlotType.Any) { if (!item.AllowedSlots.Contains(InvSlotType.Any)) return false; if (Items[index] != null) return Items[index] == item; PutItem(item, index, user, true, createNetworkEvent); return true; } InvSlotType placeToSlots = InvSlotType.None; bool slotsFree = true; List allowedSlots = item.AllowedSlots; foreach (InvSlotType allowedSlot in allowedSlots) { if (!allowedSlot.HasFlag(limbSlots[index])) continue; for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(limbSlots[i]) && Items[i] != null && Items[i] != item) { slotsFree = false; break; } placeToSlots = allowedSlot; } } if (!slotsFree) return false; return TryPutItem(item, user, new List() { placeToSlots }, createNetworkEvent); } } }