public bool MatchesItem(Item item)
 {
     if (item == null)
     {
         return(false);
     }
     if (excludedIdentifiers.Any(id => item.Prefab.Identifier == id || item.HasTag(id)))
     {
         return(false);
     }
     return(identifiers.Any(id => item.Prefab.Identifier == id || item.HasTag(id)));
 }
Exemple #2
0
 public bool MatchesItem(Item item)
 {
     if (item == null)
     {
         return(false);
     }
     if (excludedIdentifiers.Any(id => item.Prefab.Identifier == id || item.HasTag(id)))
     {
         return(false);
     }
     return(Identifiers.Any(id => item.Prefab.Identifier == id || item.HasTag(id) || (AllowVariants && item.Prefab.VariantOf?.Identifier == id)));
 }
Exemple #3
0
        public override void Start(Level level)
        {
            //ruin items are allowed to spawn close to the sub
            float   minDistance = spawnPositionType == Level.PositionType.Ruin ? 0.0f : Level.Loaded.Size.X * 0.3f;
            Vector2 position    = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);

            item = new Item(itemPrefab, position, null);
            item.body.FarseerBody.IsKinematic = true;

            if (item.HasTag("alien"))
            {
                //try to find an artifact holder and place the artifact inside it
                foreach (Item it in Item.ItemList)
                {
                    if (it.Submarine != null || !it.HasTag("artifactholder"))
                    {
                        continue;
                    }

                    var itemContainer = it.GetComponent <Items.Components.ItemContainer>();
                    if (itemContainer == null)
                    {
                        continue;
                    }
                    if (itemContainer.Combine(item, user: null))
                    {
                        break;                                          // Placement successful
                    }
                }
            }
        }
Exemple #4
0
 protected override void Act(float deltaTime)
 {
     // Only continue when the get item sub objectives have been completed.
     if (subObjectives.Any())
     {
         return;
     }
     if (HumanAIController.FindSuitableContainer(character, item, ignoredContainers, ref itemIndex, out Item suitableContainer))
     {
         itemIndex = 0;
         if (suitableContainer != null)
         {
             bool equip = item.HasTag(AIObjectiveFindDivingGear.HEAVY_DIVING_GEAR) || (
                 item.GetComponent <Wearable>() == null &&
                 item.AllowedSlots.None(s =>
                                        s == InvSlotType.Card ||
                                        s == InvSlotType.Head ||
                                        s == InvSlotType.Headset ||
                                        s == InvSlotType.InnerClothes ||
                                        s == InvSlotType.OuterClothes));
             TryAddSubObjective(ref decontainObjective, () => new AIObjectiveDecontainItem(character, item, objectiveManager, targetContainer: suitableContainer.GetComponent <ItemContainer>())
             {
                 Equip       = equip,
                 DropIfFails = true
             },
                                onCompleted: () =>
             {
                 if (equip)
                 {
                     HumanAIController.ReequipUnequipped();
                 }
                 IsCompleted = true;
             },
                                onAbandon: () =>
             {
                 if (equip)
                 {
                     HumanAIController.ReequipUnequipped();
                 }
                 if (decontainObjective != null && decontainObjective.ContainObjective != null && decontainObjective.ContainObjective.CanBeCompleted)
                 {
                     ignoredContainers.Add(suitableContainer);
                 }
                 else
                 {
                     Abandon = true;
                 }
             });
         }
         else
         {
             Abandon = true;
         }
     }
     else
     {
         objectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime);
     }
 }
 public bool MatchesItem(Item item)
 {
     if (item == null)
     {
         return(false);
     }
     return(names.Any(name => item.Name == name || item.HasTag(name)));
 }
        public virtual void Apply(ActionType type, float deltaTime, Entity entity, List <ISerializableEntity> targets, Character causecharacter = null, string identifier = "")
        {
            if (this.type != type)
            {
                return;
            }

            //remove invalid targets
            if (targetNames != null)
            {
                targets.RemoveAll(t =>
                {
                    Item item = t as Item;
                    if (item == null)
                    {
                        return(!targetNames.Contains(t.Name));
                    }
                    else
                    {
                        if (item.HasTag(targetNames))
                        {
                            return(false);
                        }
                        if (item.Prefab.NameMatches(targetNames))
                        {
                            return(false);
                        }
                    }
                    return(true);
                });
                if (targets.Count == 0)
                {
                    return;
                }
            }

            if (!HasRequiredItems(entity) || !HasRequiredConditions(targets))
            {
                return;
            }

            if (duration > 0.0f && !Stackable)
            {
                //ignore if not stackable and there's already an identical statuseffect
                DurationListElement existingEffect = DurationList.Find(d => d.Parent == this && d.Targets.SequenceEqual(targets));
                if (existingEffect != null)
                {
                    existingEffect.Timer          = Math.Max(existingEffect.Timer, duration);
                    existingEffect.causecharacter = causecharacter;
                    return;
                }
            }

            Apply(deltaTime, entity, targets, null, causecharacter, identifier);
        }
 private bool CheckItem(Item item)
 {
     if (item.NonInteractable)
     {
         return(false);
     }
     if (ignoredItems.Contains(item))
     {
         return(false);
     }
     ;
     if (item.Condition < TargetCondition)
     {
         return(false);
     }
     if (ItemFilter != null && !ItemFilter(item))
     {
         return(false);
     }
     return(itemIdentifiers.Any(id => id == item.Prefab.Identifier || item.HasTag(id)));
 }
Exemple #8
0
        public override void Start(Level level)
        {
            //ruin items are allowed to spawn close to the sub
            float   minDistance = spawnPositionType == Level.PositionType.Ruin ? 0.0f : Level.Loaded.Size.X * 0.3f;
            Vector2 position    = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);

            item = new Item(itemPrefab, position, null);
            item.MoveWithLevel = true;
            item.body.FarseerBody.IsKinematic = true;

            if (item.HasTag("alien"))
            {
                //try to find a nearby artifact holder (or any alien itemcontainer) and place the artifact inside it
                foreach (Item it in Item.ItemList)
                {
                    if (it.Submarine != null || !it.HasTag("alien"))
                    {
                        continue;
                    }

                    if (Math.Abs(item.WorldPosition.X - it.WorldPosition.X) > 2000.0f)
                    {
                        continue;
                    }
                    if (Math.Abs(item.WorldPosition.Y - it.WorldPosition.Y) > 2000.0f)
                    {
                        continue;
                    }

                    var itemContainer = it.GetComponent <Items.Components.ItemContainer>();
                    if (itemContainer == null)
                    {
                        continue;
                    }

                    itemContainer.Combine(item);
                    break;
                }
            }
        }
 private bool CheckItem(Item i) => itemIdentifiers.Any(id => i.Prefab.Identifier == id || i.HasTag(id)) && i.ConditionPercentage >= ConditionLevel && !i.IsThisOrAnyContainerIgnoredByAI();
Exemple #10
0
 private bool CheckItem(Item i) => itemIdentifiers.Any(id => i.Prefab.Identifier == id || i.HasTag(id)) && i.ConditionPercentage > ConditionLevel;
Exemple #11
0
        protected override void Act(float deltaTime)
        {
            FindTargetItem();
            if (targetItem == null || moveToTarget == null)
            {
                HumanAIController.ObjectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime);
                //SteeringManager.SteeringWander();
                return;
            }

            if (moveToTarget.CurrentHull == character.CurrentHull &&
                Vector2.DistanceSquared(character.Position, moveToTarget.Position) < MathUtils.Pow(targetItem.InteractDistance * 2, 2))
            {
                int targetSlot = -1;
                if (equip)
                {
                    var pickable = targetItem.GetComponent <Pickable>();
                    if (pickable == null)
                    {
                        canBeCompleted = false;
                        return;
                    }

                    //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
                            if (character.Inventory.Items[i] == null)
                            {
                                continue;
                            }

                            //try to move the existing item to LimbSlot.Any and continue if successful
                            if (character.Inventory.TryPutItem(character.Inventory.Items[i], character, new List <InvSlotType>()
                            {
                                InvSlotType.Any
                            }))
                            {
                                continue;
                            }

                            //if everything else fails, simply drop the existing item
                            character.Inventory.Items[i].Drop(character);
                        }
                    }
                }

                targetItem.TryInteract(character, false, true);

                if (targetSlot > -1 && !character.HasEquippedItem(targetItem))
                {
                    character.Inventory.TryPutItem(targetItem, targetSlot, false, false, character);
                }
            }
            else
            {
                if (goToObjective == null || moveToTarget != goToObjective.Target)
                {
                    //check if we're already looking for a diving gear
                    bool gettingDivingGear = (targetItem != null && targetItem.Prefab.Identifier == "divingsuit" || targetItem.HasTag("diving")) ||
                                             (itemIdentifiers != null && (itemIdentifiers.Contains("diving") || itemIdentifiers.Contains("divingsuit")));

                    //don't attempt to get diving gear to reach the destination if the item we're trying to get is diving gear
                    goToObjective = new AIObjectiveGoTo(moveToTarget, character, false, !gettingDivingGear);
                }

                goToObjective.TryComplete(deltaTime);
                if (!goToObjective.CanBeCompleted)
                {
                    targetItem   = null;
                    moveToTarget = null;
                    ignoredItems.Add(targetItem);
                }
            }
        }
        public void PurchaseItemSwap(Item itemToRemove, ItemPrefab itemToInstall, bool force = false)
        {
            if (!CanUpgradeSub())
            {
                DebugConsole.ThrowError("Cannot swap items when switching to another submarine.");
                return;
            }
            if (itemToRemove == null)
            {
                DebugConsole.ThrowError($"Cannot swap null item!");
                return;
            }
            if (itemToRemove.HiddenInGame)
            {
                DebugConsole.ThrowError($"Cannot swap item \"{itemToRemove.Name}\" because it's set to be hidden in-game.");
                return;
            }
            if (!itemToRemove.AllowSwapping)
            {
                DebugConsole.ThrowError($"Cannot swap item \"{itemToRemove.Name}\" because it's configured to be non-swappable.");
                return;
            }
            if (!UpgradeCategory.Categories.Any(c => c.ItemTags.Any(t => itemToRemove.HasTag(t)) && c.ItemTags.Any(t => itemToInstall.Tags.Contains(t))))
            {
                DebugConsole.ThrowError($"Failed to swap item \"{itemToRemove.Name}\" with \"{itemToInstall.Name}\" (not in the same upgrade category).");
                return;
            }

            if (itemToRemove.prefab == itemToInstall)
            {
                DebugConsole.ThrowError($"Failed to swap item \"{itemToRemove.Name}\" (trying to swap with the same item!).");
                return;
            }
            SwappableItem?swappableItem = itemToRemove.Prefab.SwappableItem;

            if (swappableItem == null)
            {
                DebugConsole.ThrowError($"Failed to swap item \"{itemToRemove.Name}\" (not configured as a swappable item).");
                return;
            }

            int price = 0;

            if (!itemToRemove.AvailableSwaps.Contains(itemToInstall))
            {
                price = itemToInstall.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation);
            }

            if (force)
            {
                price = 0;
            }

            if (Campaign.Money >= price)
            {
                PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToRemove);
                if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
                {
                    // only make the NPC speak if more than 5 minutes have passed since the last purchased service
                    if (lastUpgradeSpeak == DateTime.MinValue || lastUpgradeSpeak.AddMinutes(5) < DateTime.Now)
                    {
                        UpgradeNPCSpeak(TextManager.Get("Dialog.UpgradePurchased"), Campaign.IsSinglePlayer);
                        lastUpgradeSpeak = DateTime.Now;
                    }
                }

                Campaign.Money -= price;

                itemToRemove.AvailableSwaps.Add(itemToRemove.Prefab);
                if (itemToInstall != null && !itemToRemove.AvailableSwaps.Contains(itemToInstall))
                {
                    itemToRemove.PurchasedNewSwap = true;
                    itemToRemove.AvailableSwaps.Add(itemToInstall);
                }

                if (itemToRemove.Prefab != itemToInstall && itemToInstall != null)
                {
                    itemToRemove.PendingItemSwap = itemToInstall;
                    PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
                    DebugLog($"CLIENT: Swapped item \"{itemToRemove.Name}\" with \"{itemToInstall.Name}\".", Color.Orange);
                }
                else
                {
                    DebugLog($"CLIENT: Cancelled swapping the item \"{itemToRemove.Name}\" with \"{(itemToRemove.PendingItemSwap?.Name ?? null)}\".", Color.Orange);
                }
                OnUpgradesChanged?.Invoke();
            }
            else
            {
                DebugConsole.ThrowError("Tried to swap an item with insufficient funds, the transaction has not been completed.\n" +
                                        $"Item to remove: {itemToRemove.Name}, Item to install: {itemToInstall.Name}, Cost: {price}, Have: {Campaign.Money}");
            }
        }
        protected override void Act(float deltaTime)
        {
            FindTargetItem();
            if (targetItem == null || moveToTarget == null)
            {
                character?.AIController?.SteeringManager?.Reset();
                return;
            }

            if (Vector2.Distance(character.Position, moveToTarget.Position) < targetItem.InteractDistance * 2.0f)
            {
                int targetSlot = -1;
                if (equip)
                {
                    var pickable = targetItem.GetComponent <Pickable>();
                    if (pickable == null)
                    {
                        canBeCompleted = false;
                        return;
                    }

                    //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(CharacterInventory.limbSlots[i]))
                            {
                                continue;
                            }

                            targetSlot = i;

                            //slot free, continue
                            if (character.Inventory.Items[i] == null)
                            {
                                continue;
                            }

                            //try to move the existing item to LimbSlot.Any and continue if successful
                            if (character.Inventory.TryPutItem(character.Inventory.Items[i], character, new List <InvSlotType>()
                            {
                                InvSlotType.Any
                            }))
                            {
                                continue;
                            }

                            //if everything else fails, simply drop the existing item
                            character.Inventory.Items[i].Drop();
                        }
                    }
                }

                targetItem.TryInteract(character, false, true);

                if (targetSlot > -1 && character.Inventory.IsInLimbSlot(targetItem, InvSlotType.Any))
                {
                    character.Inventory.TryPutItem(targetItem, targetSlot, false, character);
                }
            }
            else
            {
                if (goToObjective == null || moveToTarget != goToObjective.Target)
                {
                    //check if we're already looking for a diving gear
                    bool gettingDivingGear = (targetItem != null && targetItem.Prefab.NameMatches("Diving Gear") || targetItem.HasTag("diving")) ||
                                             (itemNames != null && (itemNames.Contains("diving") || itemNames.Contains("Diving Gear")));

                    //don't attempt to get diving gear to reach the destination if the item we're trying to get is diving gear
                    goToObjective = new AIObjectiveGoTo(moveToTarget, character, false, !gettingDivingGear);
                }

                goToObjective.TryComplete(deltaTime);
            }
        }
        protected override void Act(float deltaTime)
        {
            if (character.LockHands)
            {
                abandon = true;
                return;
            }

            FindTargetItem();
            if (targetItem == null || moveToTarget == null)
            {
                objectiveManager.GetObjective <AIObjectiveIdle>()?.Wander(deltaTime);
                return;
            }
            if (character.CanInteractWith(targetItem, out _, checkLinked: false))
            {
                if (IsTakenBySomeone(targetItem))
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Found an item, but it's equipped by someone else. Aborting.", Color.Yellow);
#endif
                    abandon = true;
                }
                else
                {
                    int targetSlot = -1;
                    if (equip)
                    {
                        var pickable = targetItem.GetComponent <Pickable>();
                        if (pickable == null)
                        {
                            abandon = true;
                            return;
                        }
                        //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
                                if (character.Inventory.Items[i] == null)
                                {
                                    continue;
                                }
                                //try to move the existing item to LimbSlot.Any and continue if successful
                                if (character.Inventory.TryPutItem(character.Inventory.Items[i], character, new List <InvSlotType>()
                                {
                                    InvSlotType.Any
                                }))
                                {
                                    continue;
                                }
                                //if everything else fails, simply drop the existing item
                                character.Inventory.Items[i].Drop(character);
                            }
                        }
                    }
                    targetItem.TryInteract(character, false, true);
                    if (targetSlot > -1 && !character.HasEquippedItem(targetItem))
                    {
                        character.Inventory.TryPutItem(targetItem, targetSlot, false, false, character);
                    }
                }
            }
            else
            {
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    //check if we're already looking for a diving gear
                    bool gettingDivingGear = (targetItem != null && targetItem.Prefab.Identifier == "divingsuit" || targetItem.HasTag("diving")) ||
                                             (itemIdentifiers != null && (itemIdentifiers.Contains("diving") || itemIdentifiers.Contains("divingsuit")));
                    return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: !gettingDivingGear));
                },
                                   onAbandon: () =>
                {
                    targetItem   = null;
                    moveToTarget = null;
                    ignoredItems.Add(targetItem);
                });
            }
        }