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))); }
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))); }
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 } } } }
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))); }
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();
private bool CheckItem(Item i) => itemIdentifiers.Any(id => i.Prefab.Identifier == id || i.HasTag(id)) && i.ConditionPercentage > ConditionLevel;
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); }); } }