using Barotrauma.Items.Components; using Microsoft.Xna.Framework; using System; using System.Linq; namespace Barotrauma { class AIObjectiveContainItem: AIObjective { public override string DebugTag => "contain item"; public Func GetItemPriority; public int targetItemCount = 1; public string[] ignoredContainerIdentifiers; public bool checkInventory = true; //can either be a tag or an identifier public readonly string[] itemIdentifiers; public readonly ItemContainer container; private bool isCompleted; private AIObjectiveGetItem getItemObjective; private AIObjectiveGoTo goToObjective; public AIObjectiveContainItem(Character character, string itemIdentifier, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, container, objectiveManager, priorityModifier) { } public AIObjectiveContainItem(Character character, string[] itemIdentifiers, ItemContainer container, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base (character, objectiveManager, priorityModifier) { this.itemIdentifiers = itemIdentifiers; for (int i = 0; i < itemIdentifiers.Length; i++) { itemIdentifiers[i] = itemIdentifiers[i].ToLowerInvariant(); } this.container = container; } public override bool IsCompleted() { int containedItemCount = 0; foreach (Item item in container.Inventory.Items) { if (item != null && itemIdentifiers.Any(id => item.Prefab.Identifier == id || item.HasTag(id))) { containedItemCount++; } } return containedItemCount >= targetItemCount; } public override float GetPriority() { if (objectiveManager.CurrentOrder == this) { return AIObjectiveManager.OrderPriority; } return 1.0f; } protected override void Act(float deltaTime) { //get the item that should be contained Item itemToContain = null; foreach (string identifier in itemIdentifiers) { itemToContain = character.Inventory.FindItemByIdentifier(identifier) ?? character.Inventory.FindItemByTag(identifier); if (itemToContain != null && itemToContain.Condition > 0.0f) { break; } } if (itemToContain == null) { if (getItemObjective != null && getItemObjective.IsCompleted()) { getItemObjective = null; targetItemCount--; } TryAddSubObjective(ref getItemObjective, () => new AIObjectiveGetItem(character, itemIdentifiers, objectiveManager, checkInventory: checkInventory) { GetItemPriority = GetItemPriority, ignoredContainerIdentifiers = ignoredContainerIdentifiers }); return; } if (container.Item.ParentInventory == character.Inventory) { character.Inventory.RemoveItem(itemToContain); container.Inventory.TryPutItem(itemToContain, null); } else { if (!character.CanInteractWith(container.Item, out _, checkLinked: false)) { TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(container.Item, character, objectiveManager)); return; } container.Combine(itemToContain); } } public override bool IsDuplicate(AIObjective otherObjective) { if (!(otherObjective is AIObjectiveContainItem objective)) { return false; } if (objective.container != container) { return false; } if (objective.itemIdentifiers.Length != itemIdentifiers.Length) { return false; } for (int i = 0; i < itemIdentifiers.Length; i++) { if (objective.itemIdentifiers[i] != itemIdentifiers[i]) { return false; } } return true; } } }