static void itemSpawned(Item item)
                    {
                        Submarine sub = item.Submarine ?? item.GetRootContainer()?.Submarine;

                        if (sub != null)
                        {
                            foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>())
                            {
                                wifiComponent.TeamID = sub.TeamID;
                            }
                        }
                    }
        public override void End()
        {
            var root = item.GetRootContainer() ?? item;

            if (root.CurrentHull?.Submarine == null || (!root.CurrentHull.Submarine.AtEndPosition && !root.CurrentHull.Submarine.AtStartPosition) || item.Removed)
            {
                return;
            }

            item?.Remove();
            item = null;
            GiveReward();
            completed = true;
            failed    = !completed && state > 0;
        }
        private bool HasItem(Item item)
        {
            bool isEquipped = !equip || character.HasEquippedItem(item);

            if (character.Inventory.Items.Contains(item) && isEquipped)
            {
                return(true);
            }
            if (!equip)
            {
                Item rootContainer = item.GetRootContainer();
                if (rootContainer != null && rootContainer.ParentInventory is CharacterInventory)
                {
                    return(rootContainer.ParentInventory.Owner == character);
                }
            }
            return(false);
        }
        public override void End()
        {
            var root = item?.GetRootContainer() ?? item;

            if (root?.CurrentHull?.Submarine == null || (!root.CurrentHull.Submarine.AtEndExit && !root.CurrentHull.Submarine.AtStartExit) || item.Removed)
            {
                return;
            }

            if (Prefab.LocationTypeChangeOnCompleted != null)
            {
                ChangeLocationType(Prefab.LocationTypeChangeOnCompleted);
            }

            item?.Remove();
            item = null;
            GiveReward();
            completed = true;
            failed    = !completed && state > 0;
        }
        private bool IsTakenBySomeone(Item item)
        {
            //if the item is inside a character's inventory, don't steal it unless the character is dead
            if (item.ParentInventory is CharacterInventory)
            {
                if (item.ParentInventory.Owner is Character owner && owner != character && !owner.IsDead)
                {
                    return(true);
                }
            }
            //if the item is inside an item, which is inside a character's inventory, don't steal it unless the character is dead
            Item rootContainer = item.GetRootContainer();

            if (rootContainer != null && rootContainer.ParentInventory is CharacterInventory)
            {
                if (rootContainer.ParentInventory.Owner is Character owner && owner != character && !owner.IsDead)
                {
                    return(true);
                }
            }
            return(false);
        }
        protected override void Act(float deltaTime)
        {
            if (character.LockHands)
            {
                Abandon = true;
                return;
            }
            if (itemIdentifiers != null && !isDoneSeeking)
            {
                if (checkInventory)
                {
                    if (CheckInventory())
                    {
                        isDoneSeeking = true;
                    }
                }
                if (!isDoneSeeking)
                {
                    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;
            }
            if (character.CanInteractWith(targetItem, out _, checkLinked: false))
            {
                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
            {
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear)
                    {
                        // 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.GetRootContainer() != rootContainer,
                        DialogueIdentifier = "dialogcannotreachtarget",
                        TargetName = moveToTarget.Name
                    });
                },
                                   onAbandon: () =>
                {
                    ignoredItems.Add(targetItem);
                    Reset();
                },
                                   onCompleted: () => RemoveSubObjective(ref goToObjective));
            }
        }