protected override void Act(float deltaTime)
        {
            if (character.LockHands)
            {
                Abandon = true;
                return;
            }
            if (character.Submarine == null)
            {
                Abandon = true;
                return;
            }
            if (identifiersOrTags != null && !isDoneSeeking)
            {
                if (checkInventory)
                {
                    if (CheckInventory())
                    {
                        isDoneSeeking = true;
                    }
                }
                if (!isDoneSeeking)
                {
                    if (!AllowDangerousPressure)
                    {
                        bool dangerousPressure = character.CurrentHull == null || character.CurrentHull.LethalPressure > 0 && character.PressureProtection <= 0;
                        if (dangerousPressure)
                        {
#if DEBUG
                            string itemName = targetItem != null ? targetItem.Name : identifiersOrTags.FirstOrDefault();
                            DebugConsole.NewMessage($"{character.Name}: Seeking item ({itemName}) aborted, because the pressure is dangerous.", Color.Yellow);
#endif
                            Abandon = true;
                            return;
                        }
                    }
                    FindTargetItem();
                    if (!objectiveManager.IsCurrentOrder <AIObjectiveGoTo>())
                    {
                        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
                    ignoredItems.Add(targetItem);
                    ResetInternal();
                }
                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, 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;
                }

                Inventory itemInventory = targetItem.ParentInventory;
                var       slots         = itemInventory?.FindIndices(targetItem);
                if (HumanAIController.TakeItem(targetItem, character.Inventory, Equip, Wear, storeUnequipped: true))
                {
                    if (TakeWholeStack && slots != null)
                    {
                        foreach (int slot in slots)
                        {
                            foreach (Item item in itemInventory.GetItemsAt(slot).ToList())
                            {
                                HumanAIController.TakeItem(item, character.Inventory, equip: false, storeUnequipped: true);
                            }
                        }
                    }
                    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 (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 = obj => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget,
                        SpeakIfFails = false
                    });
                },
                                   onAbandon: () =>
                {
                    if (originalTarget == null)
                    {
                        // Try again
                        ignoredItems.Add(targetItem);
                        ResetInternal();
                    }
                    else
                    {
                        Abandon = true;
                    }
                },
                                   onCompleted: () => RemoveSubObjective(ref goToObjective));
            }
        }
Esempio n. 2
0
        protected override void Act(float deltaTime)
        {
            if (container == null || (container.Item != null && container.Item.IsThisOrAnyContainerIgnoredByAI()))
            {
                Abandon = true;
                return;
            }
            ItemToContain = item ?? character.Inventory.FindItem(i => CheckItem(i) && i.Container != container.Item, recursive: true);
            if (ItemToContain != null)
            {
                if (!character.CanInteractWith(ItemToContain, checkLinked: false))
                {
                    Abandon = true;
                    return;
                }
                if (character.CanInteractWith(container.Item, checkLinked: false))
                {
                    if (RemoveExisting)
                    {
                        HumanAIController.UnequipContainedItems(container.Item);
                    }
                    else if (RemoveEmpty)
                    {
                        HumanAIController.UnequipEmptyItems(container.Item);
                    }
                    Inventory originalInventory = ItemToContain.ParentInventory;
                    var       slots             = originalInventory?.FindIndices(ItemToContain);
                    if (container.Inventory.TryPutItem(ItemToContain, null))
                    {
                        if (MoveWholeStack && slots != null)
                        {
                            foreach (int slot in slots)
                            {
                                foreach (Item item in originalInventory.GetItemsAt(slot).ToList())
                                {
                                    container.Inventory.TryPutItem(item, null);
                                }
                            }

                            IsCompleted = true;
                        }
                    }
                    else
                    {
                        if (ItemToContain.ParentInventory == character.Inventory && character.Submarine == Submarine.MainSub)
                        {
                            ItemToContain.Drop(character);
                        }
                        Abandon = true;
                    }
                }
                else
                {
                    TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(container.Item, character, objectiveManager, getDivingGearIfNeeded: AllowToFindDivingGear)
                    {
                        DialogueIdentifier = "dialogcannotreachtarget",
                        TargetName         = container.Item.Name,
                        abortCondition     = obj => !ItemToContain.IsOwnedBy(character),
                        SpeakIfFails       = !objectiveManager.IsCurrentOrder <AIObjectiveCleanupItems>()
                    },
                                       onAbandon: () => Abandon = true,
                                       onCompleted: () => RemoveSubObjective(ref goToObjective));
                }
            }
            else
            {
                if (character.Submarine == null)
                {
                    Abandon = true;
                }
                else
                {
                    // No matching items in the inventory, try to get an item
                    TryAddSubObjective(ref getItemObjective, () =>
                                       new AIObjectiveGetItem(character, itemIdentifiers, objectiveManager, equip: Equip, checkInventory: checkInventory, spawnItemIfNotFound: spawnItemIfNotFound)
                    {
                        GetItemPriority             = GetItemPriority,
                        ignoredContainerIdentifiers = ignoredContainerIdentifiers,
                        ignoredItems           = containedItems,
                        AllowToFindDivingGear  = AllowToFindDivingGear,
                        AllowDangerousPressure = AllowDangerousPressure,
                        TargetCondition        = ConditionLevel
                    }, onAbandon: () =>
                    {
                        Abandon = true;
                    }, onCompleted: () =>
                    {
                        if (getItemObjective?.TargetItem != null)
                        {
                            containedItems.Add(getItemObjective.TargetItem);
                        }
                        RemoveSubObjective(ref getItemObjective);
                    });
                }
            }
        }
Esempio n. 3
0
        protected override void Act(float deltaTime)
        {
            if (container?.Item == null || container.Item.Removed || container.Item.IsThisOrAnyContainerIgnoredByAI(character))
            {
                Abandon = true;
                return;
            }
            ItemToContain = item ?? character.Inventory.FindItem(i => CheckItem(i) && i.Container != container.Item, recursive: true);
            if (ItemToContain != null)
            {
                if (!character.CanInteractWith(ItemToContain, checkLinked: false))
                {
                    Abandon = true;
                    return;
                }
                if (character.CanInteractWith(container.Item, checkLinked: false))
                {
                    if (RemoveExisting)
                    {
                        HumanAIController.UnequipContainedItems(container.Item);
                    }
                    else if (RemoveEmpty)
                    {
                        HumanAIController.UnequipEmptyItems(container.Item);
                    }
                    Inventory originalInventory = ItemToContain.ParentInventory;
                    var       slots             = originalInventory?.FindIndices(ItemToContain);
                    if (container.Inventory.TryPutItem(ItemToContain, null))
                    {
                        if (MoveWholeStack && slots != null)
                        {
                            foreach (int slot in slots)
                            {
                                foreach (Item item in originalInventory.GetItemsAt(slot).ToList())
                                {
                                    container.Inventory.TryPutItem(item, null);
                                }
                            }

                            IsCompleted = true;
                        }
                    }
                    else
                    {
                        if (ItemToContain.ParentInventory == character.Inventory && character.IsInFriendlySub)
                        {
                            ItemToContain.Drop(character);
                        }
                        Abandon = true;
                    }
                }
                else
                {
                    TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(container.Item, character, objectiveManager, getDivingGearIfNeeded: AllowToFindDivingGear)
                    {
                        DialogueIdentifier = "dialogcannotreachtarget",
                        TargetName         = container.Item.Name,
                        AbortCondition     = obj =>
                                             container?.Item == null || container.Item.Removed || container.Item.IsThisOrAnyContainerIgnoredByAI(character) ||
                                             ItemToContain == null || ItemToContain.Removed ||
                                             !ItemToContain.IsOwnedBy(character) || container.Item.GetRootInventoryOwner() is Character c && c != character,
                        SpeakIfFails = !objectiveManager.IsCurrentOrder <AIObjectiveCleanupItems>()
                    },