/// <summary> /// If there is room, puts the item in the inventory and returns true, otherwise returns false /// </summary> public override bool TryPutItem(Item item, Character user, List <InvSlotType> 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); }
/// <summary> /// If there is room, puts the item in the inventory and returns true, otherwise returns false /// </summary> public override bool TryPutItem(Item item, Character user, IEnumerable <InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool ignoreCondition = false) { if (allowedSlots == null || !allowedSlots.Any()) { return(false); } if (item == null) { #if DEBUG throw new Exception("item null"); #else return(false); #endif } if (item.Removed) { #if DEBUG throw new Exception("Tried to put a removed item (" + item.Name + ") in an inventory"); #else DebugConsole.ThrowError("Tried to put a removed item (" + item.Name + ") in an inventory.\n" + Environment.StackTrace.CleanupStackTrace()); return(false); #endif } bool inSuitableSlot = false; bool inWrongSlot = false; int currentSlot = -1; for (int i = 0; i < capacity; i++) { if (slots[i].Contains(item)) { currentSlot = i; if (allowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { inSuitableSlot = true; } else if (!allowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { inWrongSlot = true; } } } //all good if (inSuitableSlot && !inWrongSlot) { return(true); } //try to place the item in a LimbSlot.Any slot if that's allowed if (allowedSlots.Contains(InvSlotType.Any) && item.AllowedSlots.Contains(InvSlotType.Any)) { int freeIndex = CheckIfAnySlotAvailable(item, inWrongSlot); if (freeIndex > -1) { PutItem(item, freeIndex, user, true, createNetworkEvent); item.Unequip(character); return(true); } } int placedInSlot = -1; foreach (InvSlotType allowedSlot in allowedSlots) { if (allowedSlot.HasFlag(InvSlotType.RightHand) && character.AnimController.GetLimb(LimbType.RightHand) == null) { continue; } if (allowedSlot.HasFlag(InvSlotType.LeftHand) && character.AnimController.GetLimb(LimbType.LeftHand) == null) { continue; } //check if all the required slots are free bool free = true; for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(SlotTypes[i]) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) && slots[i].Items.Any(it => it != item)) { #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; } #endif if (!slots[i].First().AllowedSlots.Contains(InvSlotType.Any) || !TryPutItem(slots[i].FirstOrDefault(), character, new List <InvSlotType> { InvSlotType.Any }, true, ignoreCondition)) { free = false; #if CLIENT for (int j = 0; j < capacity; j++) { if (visualSlots != null && slots[j] == slots[i]) { visualSlots[j].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f); } } #endif } } } if (!free) { continue; } for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(SlotTypes[i]) && item.GetComponents <Pickable>().Any(p => p.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i]))) && slots[i].Empty()) { #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; } #endif bool removeFromOtherSlots = item.ParentInventory != this; if (placedInSlot == -1 && inWrongSlot) { if (!slots[i].HideIfEmpty || SlotTypes[currentSlot] != InvSlotType.Any) { removeFromOtherSlots = true; } } PutItem(item, i, user, removeFromOtherSlots, createNetworkEvent); item.Equip(character); placedInSlot = i; } } if (placedInSlot > -1) { break; } } return(placedInSlot > -1); }
/// <summary> /// If there is room, puts the item in the inventory and returns true, otherwise returns false /// </summary> public override bool TryPutItem(Item item, Character user, List <InvSlotType> allowedSlots = null, bool createNetworkEvent = true) { if (allowedSlots == null || !allowedSlots.Any()) { return(false); } bool inSuitableSlot = false; bool inWrongSlot = false; int currentSlot = -1; for (int i = 0; i < capacity; i++) { if (Items[i] == item) { currentSlot = i; if (allowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { inSuitableSlot = true; } else if (!allowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { inWrongSlot = true; } } } //all good if (inSuitableSlot && !inWrongSlot) { return(true); } //try to place the item in a LimbSlot.Any slot if that's allowed if (allowedSlots.Contains(InvSlotType.Any) && item.AllowedSlots.Contains(InvSlotType.Any)) { int freeIndex = CheckIfAnySlotAvailable(item, inWrongSlot); if (freeIndex > -1) { PutItem(item, freeIndex, user, true, createNetworkEvent); item.Unequip(character); return(true); } } int placedInSlot = -1; 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(SlotTypes[i]) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) && Items[i] != null && Items[i] != item) { #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; } #endif if (!Items[i].AllowedSlots.Contains(InvSlotType.Any) || !TryPutItem(Items[i], character, new List <InvSlotType> { InvSlotType.Any }, true)) { free = false; #if CLIENT for (int j = 0; j < capacity; j++) { if (slots != null && Items[j] == Items[i]) { slots[j].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f); } } #endif } } } if (!free) { continue; } for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(SlotTypes[i]) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) && Items[i] == null) { #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; } #endif bool removeFromOtherSlots = item.ParentInventory != this; if (placedInSlot == -1 && inWrongSlot) { if (!hideEmptySlot[i] || SlotTypes[currentSlot] != InvSlotType.Any) { removeFromOtherSlots = true; } } PutItem(item, i, user, removeFromOtherSlots, createNetworkEvent); item.Equip(character); placedInSlot = i; } } if (placedInSlot > -1) { break; } } return(placedInSlot > -1); }
protected override void Act(float deltaTime) { if (character.LockHands) { Abandon = true; return; } if (itemIdentifiers != null && !isDoneSeeking) { if (checkInventory) { if (CheckInventory()) { isDoneSeeking = true; } } if (!isDoneSeeking) { bool dangerousPressure = character.CurrentHull == null || character.CurrentHull.LethalPressure > 0; if (dangerousPressure) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Seeking item aborted, because the pressure is dangerous.", Color.Yellow); #endif Abandon = true; return; } FindTargetItem(); objectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime); return; } } if (targetItem == null || targetItem.Removed) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Target null or removed. Aborting.", Color.Red); #endif Abandon = true; return; } else if (isDoneSeeking && moveToTarget == null) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Move target null. Aborting.", Color.Red); #endif Abandon = true; return; } if (character.IsItemTakenBySomeoneElse(targetItem)) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Found an item, but it's already equipped by someone else.", Color.Yellow); #endif if (originalTarget == null) { // Try again Reset(); } else { Abandon = true; } return; } bool canInteract = false; if (moveToTarget is Character c) { if (character == c) { canInteract = true; moveToTarget = null; } else { character.SelectCharacter(c); canInteract = character.CanInteractWith(c, maxDist: DefaultReach); character.DeselectCharacter(); } } else if (moveToTarget is Item parentItem) { canInteract = character.CanInteractWith(parentItem, out _, checkLinked: false); } if (canInteract) { var pickable = targetItem.GetComponent <Pickable>(); if (pickable == null) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Target not pickable. Aborting.", Color.Yellow); #endif Abandon = true; return; } if (equip) { if (HumanAIController.TryToMoveItem(targetItem, character.Inventory)) { targetItem.Equip(character); IsCompleted = true; } else { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red); #endif Abandon = true; } } else { if (character.Inventory.TryPutItem(targetItem, character, new List <InvSlotType>() { InvSlotType.Any })) { IsCompleted = true; } else { Abandon = true; #if DEBUG DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red); #endif } } } else if (moveToTarget != null) { TryAddSubObjective(ref goToObjective, constructor: () => { return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach) { // If the root container changes, the item is no longer where it was (taken by someone -> need to find another item) abortCondition = () => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget, DialogueIdentifier = "dialogcannotreachtarget", TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString() }); }, onAbandon: () => { ignoredItems.Add(targetItem); Reset(); }, onCompleted: () => RemoveSubObjective(ref goToObjective)); } }
protected override void Act(float deltaTime) { if (character.LockHands) { Abandon = true; return; } if (itemIdentifiers != null && !isDoneSeeking) { if (checkInventory) { if (CheckInventory()) { isDoneSeeking = true; } } if (!isDoneSeeking) { bool dangerousPressure = character.CurrentHull == null || character.CurrentHull.LethalPressure > 0; if (dangerousPressure) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Seeking item aborted, because the pressure is dangerous.", Color.Yellow); #endif Abandon = true; return; } FindTargetItem(); objectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime); return; } } if (targetItem == null || targetItem.Removed) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Target null or removed. Aborting.", Color.Red); #endif Abandon = true; return; } if (character.IsItemTakenBySomeoneElse(targetItem)) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Found an item, but it's already equipped by someone else.", Color.Yellow); #endif // Try again Reset(); return; } bool canInteract = false; if (moveToTarget is Character c) { if (character == c) { canInteract = true; moveToTarget = null; } else { character.SelectCharacter(c); canInteract = character.CanInteractWith(c, maxDist: DefaultReach); character.DeselectCharacter(); } } else if (moveToTarget is Item parentItem) { canInteract = character.CanInteractWith(parentItem, out _, checkLinked: false); } if (canInteract) { var pickable = targetItem.GetComponent <Pickable>(); if (pickable == null) { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Target not pickable. Aborting.", Color.Yellow); #endif Abandon = true; return; } if (equip) { int targetSlot = -1; //check if all the slots required by the item are free foreach (InvSlotType slots in pickable.AllowedSlots) { if (slots.HasFlag(InvSlotType.Any)) { continue; } for (int i = 0; i < character.Inventory.Items.Length; i++) { //slot not needed by the item, continue if (!slots.HasFlag(character.Inventory.SlotTypes[i])) { continue; } targetSlot = i; //slot free, continue var otherItem = character.Inventory.Items[i]; if (otherItem == null) { continue; } //try to move the existing item to LimbSlot.Any and continue if successful if (otherItem.AllowedSlots.Contains(InvSlotType.Any) && character.Inventory.TryPutItem(otherItem, character, new List <InvSlotType>() { InvSlotType.Any })) { continue; } //if everything else fails, simply drop the existing item otherItem.Drop(character); } } if (character.Inventory.TryPutItem(targetItem, targetSlot, false, false, character)) { targetItem.Equip(character); IsCompleted = true; } else { #if DEBUG DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red); #endif Abandon = true; } } else { if (character.Inventory.TryPutItem(targetItem, null, new List <InvSlotType>() { InvSlotType.Any })) { IsCompleted = true; } else { Abandon = true; #if DEBUG DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red); #endif } } } else if (moveToTarget != null) { TryAddSubObjective(ref goToObjective, constructor: () => { return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach) { // If the root container changes, the item is no longer where it was (taken by someone -> need to find another item) abortCondition = () => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget, DialogueIdentifier = "dialogcannotreachtarget", TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString() }); }, onAbandon: () => { ignoredItems.Add(targetItem); Reset(); }, onCompleted: () => RemoveSubObjective(ref goToObjective)); } }
/// <summary> /// If there is room, puts the item in the inventory and returns true, otherwise returns false /// </summary> public override bool TryPutItem(Item item, Character user, List <InvSlotType> 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) { if (GameMain.NilMod.EnableGriefWatcher && GameMain.Server != null && user != null && user != character && user.TeamID == character.TeamID) { if (GameMain.Server.TraitorManager != null && !GameMain.Server.TraitorManager.IsTraitor(character)) { Barotrauma.Networking.Client warnedclient = GameMain.Server.ConnectedClients.Find(c => c.Character == user); //Code for mask item checks if (item.ContainedItems != null && item.ContainedItems.Count() > 0 && !character.IsDead && ((GameMain.Server.ConnectedClients.Find(c => c.Character == character) != null) || character.AIController == null) && user.TeamID == character.TeamID) { if (IsInLimbSlot(item, InvSlotType.Face) || IsInLimbSlot(item, InvSlotType.Head) || IsInLimbSlot(item, InvSlotType.Torso) || IsInLimbSlot(item, InvSlotType.Legs)) { //Mask item checks for (int y = 0; y < NilMod.NilModGriefWatcher.GWListMaskItems.Count; y++) { if (NilMod.NilModGriefWatcher.GWListMaskItems[y] == item.Name) { for (int z = 0; z < NilMod.NilModGriefWatcher.GWListMaskHazardous.Count; z++) { if (Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name).Contains(NilMod.NilModGriefWatcher.GWListMaskHazardous[z])) { NilMod.NilModGriefWatcher.SendWarning(user.LogName + " placed lethal wearable " + item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")" + " on " + character.LogName, warnedclient); } } } } } } if (!character.IsDead && ((GameMain.Server.ConnectedClients.Find(c => c.Character == character) != null) || character.AIController == null) && user.TeamID == character.TeamID) { //Incase a mod decides to have straightjackets or something if (IsInLimbSlot(item, InvSlotType.RightHand) || IsInLimbSlot(item, InvSlotType.LeftHand) || IsInLimbSlot(item, InvSlotType.Face) || IsInLimbSlot(item, InvSlotType.Head) || IsInLimbSlot(item, InvSlotType.Torso) || IsInLimbSlot(item, InvSlotType.Legs)) { //Handcuff checks for (int y = 0; y < NilMod.NilModGriefWatcher.GWListHandcuffs.Count; y++) { if (NilMod.NilModGriefWatcher.GWListHandcuffs[y] == item.Name) { NilMod.NilModGriefWatcher.SendWarning(user.LogName + " placed " + item.Name + " on " + character.LogName, warnedclient); } } } } } } return(true); } } return(placed); }