Client LuaCsForBarotrauma
AIObjectiveDecontainItem.cs
3 using System;
4 using System.Collections.Immutable;
5 using System.Linq;
6 
7 namespace Barotrauma
8 {
10  {
11  public override Identifier Identifier { get; set; } = "decontain item".ToIdentifier();
12  protected override bool AllowWhileHandcuffed => false;
13 
14  public Func<Item, float> GetItemPriority;
15 
16  //can either be a tag or an identifier
17  private readonly Identifier[] itemIdentifiers;
18  private readonly ItemContainer sourceContainer;
19  private readonly ItemContainer targetContainer;
20  private readonly Item targetItem;
21 
22  private AIObjectiveGetItem getItemObjective;
23  private AIObjectiveContainItem containObjective;
24 
25  public AIObjectiveGetItem GetItemObjective => getItemObjective;
26  public AIObjectiveContainItem ContainObjective => containObjective;
27 
28  public Item TargetItem => targetItem;
29  public ItemContainer TargetContainer => targetContainer;
30 
31  public bool Equip { get; set; }
32 
33  public bool TakeWholeStack { get; set; }
34 
40  public bool DropIfFails { get; set; } = true;
41 
45  public bool RemoveExistingWhenNecessary { get; set; }
46  public Func<Item, bool> RemoveExistingPredicate { get; set; }
47  public int? RemoveExistingMax { get; set; }
48  public string AbandonGetItemDialogueIdentifier { get; set; }
49  public Func<bool> AbandonGetItemDialogueCondition { get; set; }
50 
51  public AIObjectiveDecontainItem(Character character, Item targetItem, AIObjectiveManager objectiveManager, ItemContainer sourceContainer = null, ItemContainer targetContainer = null, float priorityModifier = 1)
52  : base(character, objectiveManager, priorityModifier)
53  {
54  this.targetItem = targetItem;
55  this.sourceContainer = sourceContainer;
56  this.targetContainer = targetContainer;
57  }
58 
59  public AIObjectiveDecontainItem(Character character, Identifier itemIdentifier, AIObjectiveManager objectiveManager, ItemContainer sourceContainer, ItemContainer targetContainer = null, float priorityModifier = 1)
60  : this(character, new Identifier[] { itemIdentifier }, objectiveManager, sourceContainer, targetContainer, priorityModifier) { }
61 
62  public AIObjectiveDecontainItem(Character character, Identifier[] itemIdentifiers, AIObjectiveManager objectiveManager, ItemContainer sourceContainer, ItemContainer targetContainer = null, float priorityModifier = 1)
63  : base(character, objectiveManager, priorityModifier)
64  {
65  this.itemIdentifiers = itemIdentifiers;
66  for (int i = 0; i < itemIdentifiers.Length; i++)
67  {
68  itemIdentifiers[i] = itemIdentifiers[i];
69  }
70  this.sourceContainer = sourceContainer;
71  this.targetContainer = targetContainer;
72  }
73 
74  protected override bool CheckObjectiveSpecific() => IsCompleted;
75 
76  protected override void Act(float deltaTime)
77  {
78  Item itemToDecontain =
79  targetItem ??
80  sourceContainer.Inventory.FindItem(i => itemIdentifiers.Any(id => i.Prefab.Identifier == id || i.HasTag(id) && !i.IgnoreByAI(character)), recursive: false);
81 
82  if (itemToDecontain == null)
83  {
84  Abandon = true;
85  return;
86  }
87  if (itemToDecontain.IgnoreByAI(character))
88  {
89  Abandon = true;
90  return;
91  }
92  if (targetContainer == null)
93  {
94  if (sourceContainer == null)
95  {
96  Abandon = true;
97  return;
98  }
99  if (itemToDecontain.Container != sourceContainer.Item)
100  {
101  itemToDecontain.Drop(character);
102  IsCompleted = true;
103  return;
104  }
105  }
106  else if (targetContainer.Inventory.Contains(itemToDecontain))
107  {
108  IsCompleted = true;
109  return;
110  }
111  if (getItemObjective == null && !itemToDecontain.IsOwnedBy(character))
112  {
113  TryAddSubObjective(ref getItemObjective,
114  constructor: () => new AIObjectiveGetItem(character, targetItem, objectiveManager, Equip)
115  {
116  CannotFindDialogueCondition = AbandonGetItemDialogueCondition,
117  CannotFindDialogueIdentifierOverride = AbandonGetItemDialogueIdentifier,
118  SpeakIfFails = AbandonGetItemDialogueIdentifier != null,
120  },
121  onAbandon: () => Abandon = true);
122  return;
123  }
124  if (targetContainer != null)
125  {
126  TryAddSubObjective(ref containObjective,
127  constructor: () => new AIObjectiveContainItem(character, itemToDecontain, targetContainer, objectiveManager)
128  {
129  MoveWholeStack = TakeWholeStack,
130  Equip = Equip,
131  RemoveEmpty = false,
134  RemoveMax = RemoveExistingMax,
136  ignoredContainerIdentifiers = sourceContainer?.Item.Prefab.Identifier.ToEnumerable().ToImmutableHashSet()
137  },
138  onCompleted: () => IsCompleted = true,
139  onAbandon: () => Abandon = true);
140  }
141  else
142  {
143  itemToDecontain.Drop(character);
144  IsCompleted = true;
145  }
146  }
147 
148  public override void Reset()
149  {
150  base.Reset();
151  getItemObjective = null;
152  containObjective = null;
153  }
154 
155  protected override void OnAbandon()
156  {
157  base.OnAbandon();
158  if (DropIfFails && targetItem != null && targetItem.IsOwnedBy(character))
159  {
160  targetItem.Drop(character);
161  }
162  }
163  }
164 }
AIObjectiveDecontainItem(Character character, Identifier itemIdentifier, AIObjectiveManager objectiveManager, ItemContainer sourceContainer, ItemContainer targetContainer=null, float priorityModifier=1)
AIObjectiveDecontainItem(Character character, Identifier[] itemIdentifiers, AIObjectiveManager objectiveManager, ItemContainer sourceContainer, ItemContainer targetContainer=null, float priorityModifier=1)
bool RemoveExistingWhenNecessary
Should existing item(s) be removed from the targetContainer if the targetItem won't fit otherwise?
override bool CheckObjectiveSpecific()
Should return whether the objective is completed or not.
AIObjectiveDecontainItem(Character character, Item targetItem, AIObjectiveManager objectiveManager, ItemContainer sourceContainer=null, ItemContainer targetContainer=null, float priorityModifier=1)
bool DropIfFails
If true drops the item when containing the item fails. In both cases abandons the objective....
override void Act(float deltaTime)
void Drop(Character dropper, bool createNetworkEvent=true, bool setTransform=true)
bool IgnoreByAI(Character character)
bool IsOwnedBy(Entity entity)
Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine, ushort id=Entity.NullEntityID, bool callOnItemLoaded=true)