Example #1
0
        /// <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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
        }