Client LuaCsForBarotrauma
AIObjectiveLoadItems.cs
3 using System;
4 using System.Collections.Generic;
5 using System.Collections.Immutable;
6 using System.Linq;
7 
8 namespace Barotrauma
9 {
11  {
12  public override Identifier Identifier { get; set; } = "load items".ToIdentifier();
13  protected override float IgnoreListClearInterval => 20.0f;
14  protected override bool ResetWhenClearingIgnoreList => false;
15 
16  private ImmutableArray<Identifier> TargetContainerTags { get; }
17  private List<Item> TargetContainers { get; } = new List<Item>();
18  private ItemCondition TargetCondition { get; }
19 
20  public enum ItemCondition
21  {
22  Empty,
23  Full
24  }
25 
26  public AIObjectiveLoadItems(Character character, AIObjectiveManager objectiveManager, Identifier option, ImmutableArray<Identifier> containerTags, Item targetContainer = null, float priorityModifier = 1)
27  : base(character, objectiveManager, priorityModifier, option)
28  {
29  if ((containerTags == null || containerTags.None()) && targetContainer == null)
30  {
31  Abandon = true;
32  return;
33  }
34  else
35  {
36  TargetContainerTags = containerTags.ToImmutableArray();
37  }
38  if (targetContainer != null)
39  {
40  TargetContainers.Add(targetContainer);
41  }
42  else
43  {
44  foreach (Item item in Item.ItemList)
45  {
46  if (!OrderPrefab.TargetItemsMatchItem(TargetContainerTags, item)) { continue; }
47  TargetContainers.Add(item);
48  }
49  }
50  TargetCondition = option == "turretammo" ? ItemCondition.Empty : ItemCondition.Full;
51  }
52 
53  protected override bool IsValidTarget(Item target)
54  {
55  //don't pass TargetContainerTags to the method (no need to filter by tags anymore, it's already done when populating TargetContainers)
56  if (!IsValidTarget(target, character, null, TargetCondition)) { return false; }
57  if (target.CurrentHull == null || target.CurrentHull.FireSources.Count > 0) { return false; }
58  if (Character.CharacterList.Any(c => c.CurrentHull == target.CurrentHull && !HumanAIController.IsFriendly(c) && HumanAIController.IsActive(c))) { return false; }
59  return true;
60  }
61 
62  public static bool IsValidTarget(Item item, Character character, ImmutableArray<Identifier>? targetContainerTags = null, ItemCondition? targetCondition = null)
63  {
64  if (item == null || item.Removed) { return false; }
65  if (targetContainerTags.HasValue && !OrderPrefab.TargetItemsMatchItem(targetContainerTags.Value, item)) { return false; }
66  if ((item.GetComponent<ItemContainer>() is not ItemContainer container)) { return false; }
67  if (container.Inventory == null) { return false; }
68  if (targetCondition.HasValue && container.Inventory.IsFull() && container.Inventory.AllItems.None(i => ItemMatchesTargetCondition(i, targetCondition.Value))) { return false; }
69  if (!AIObjectiveCleanupItems.IsItemInsideValidSubmarine(item, character)) { return false; }
70  if (item.GetRootInventoryOwner() is Character owner && owner != character) { return false; }
71  if (item.IsClaimedByBallastFlora) { return false; }
72  if (!item.HasAccess(character)) { return false; }
73  // Ignore items that require power but don't have it
74  if (item.GetComponent<Powered>() is Powered powered && powered.PowerConsumption > 0 && powered.Voltage < powered.MinVoltage) { return false; }
75  return true;
76  }
77 
78  public static bool ItemMatchesTargetCondition(Item item, ItemCondition targetCondition)
79  {
80  if(item == null) { return false; }
81  try
82  {
83  return targetCondition switch
84  {
85  ItemCondition.Empty => item.Condition <= 0.1f,
86  ItemCondition.Full => item.IsFullCondition,
87  _ => throw new NotImplementedException(),
88  };
89  }
90  catch (NotImplementedException)
91  {
92 #if DEBUG
93  DebugConsole.LogError($"Unexpected target condition \"{targetCondition}\" in AIObjectiveLoadItems.ItemMatchesTargetCondition");
94 #endif
95  return false;
96  }
97  }
98 
99  protected override IEnumerable<Item> GetList() => TargetContainers;
100 
101  protected override AIObjective ObjectiveConstructor(Item target)
102  => new AIObjectiveLoadItem(target, TargetContainerTags, TargetCondition, Option, character, objectiveManager, PriorityModifier);
103 
104  protected override void OnObjectiveCompleted(AIObjective objective, Item target)
105  => HumanAIController.RemoveTargets<AIObjectiveLoadItems, Item>(character, target);
106 
107  protected override float GetTargetPriority()
108  {
109  if (Targets.None()) { return 0; }
110  if (objectiveManager.IsOrder(this))
111  {
112  float prio = objectiveManager.GetOrderPriority(this);
113  if (subObjectives.All(so => so.SubObjectives.None() || so.Priority <= 0))
114  {
115  ForceWalk = true;
116  }
117  return prio;
118  }
119  return AIObjectiveManager.RunPriority - 0.5f;
120  }
121  }
122 }
static bool IsItemInsideValidSubmarine(Item item, Character character)
static bool ItemMatchesTargetCondition(Item item, ItemCondition targetCondition)
override IEnumerable< Item > GetList()
List of all possible items of the specified type. Used for filtering the removed objectives.
static bool IsValidTarget(Item item, Character character, ImmutableArray< Identifier >? targetContainerTags=null, ItemCondition? targetCondition=null)
override float GetTargetPriority()
Returns a priority value based on the current targets (e.g. high prio when there's lots of severe fir...
override AIObjective ObjectiveConstructor(Item target)
override bool IsValidTarget(Item target)
AIObjectiveLoadItems(Character character, AIObjectiveManager objectiveManager, Identifier option, ImmutableArray< Identifier > containerTags, Item targetContainer=null, float priorityModifier=1)
override void OnObjectiveCompleted(AIObjective objective, Item target)
An objective that creates specific kinds of subobjectives for specific types of targets,...
const float RunPriority
Objectives with a priority equal to or higher than this make the character run.
static bool IsActive(Character c)
static bool IsFriendly(Character me, Character other, bool onlySameTeam=false)
static readonly List< Item > ItemList
bool HasAccess(Character character)
Used by the AI to check whether they can (in principle) and are allowed (in practice) to interact wit...
bool TargetItemsMatchItem(Item item, Identifier option=default)
Definition: Order.cs:439