Client LuaCsForBarotrauma
AIObjectiveDeconstructItem.cs
2 using System.Linq;
3 
4 namespace Barotrauma
5 {
7  {
8  public override Identifier Identifier { get; set; } = "deconstruct item".ToIdentifier();
9  protected override bool AllowWhileHandcuffed => false;
10 
11  protected override bool AllowInFriendlySubs => true;
12 
13  public readonly Item Item;
14 
15  private Deconstructor deconstructor;
16 
17  private AIObjectiveDecontainItem decontainObjective;
18 
20  : base(character, objectiveManager, priorityModifier)
21  {
22  Item = item;
23  }
24 
25  protected override void Act(float deltaTime)
26  {
27  if (subObjectives.Any()) { return; }
28 
29  if (deconstructor == null)
30  {
31  deconstructor = FindDeconstructor();
32  if (deconstructor == null)
33  {
34  Abandon = true;
35  return;
36  }
37  }
38 
39  TryAddSubObjective(ref decontainObjective,
41  sourceContainer: Item.Container?.GetComponent<ItemContainer>(), targetContainer: deconstructor.InputContainer, priorityModifier: PriorityModifier)
42  {
43  Equip = true,
44  RemoveExistingWhenNecessary = true
45  },
46  onCompleted: () =>
47  {
48  StartDeconstructor();
49  //make sure the item gets moved to the main sub if the crew leaves while a bot is deconstructing something in the outpost
50  if (deconstructor.Item.Submarine is { Info.IsOutpost: true })
51  {
53  deconstructor.RelocateOutputToMainSub = true;
54  }
55  IsCompleted = true;
56  RemoveSubObjective(ref decontainObjective);
57  },
58  onAbandon: () =>
59  {
60  Abandon = true;
61  });
62  }
63 
64  private Deconstructor FindDeconstructor()
65  {
66  Deconstructor closestDeconstructor = null;
67  float bestDistFactor = 0;
68  foreach (var otherItem in Item.ItemList)
69  {
70  var potentialDeconstructor = otherItem.GetComponent<Deconstructor>();
71  if (potentialDeconstructor?.InputContainer == null) { continue; }
72  if (!potentialDeconstructor.InputContainer.Inventory.CanBePut(Item)) { continue; }
73  if (!potentialDeconstructor.Item.HasAccess(character)) { continue; }
74  float distFactor = GetDistanceFactor(Item.WorldPosition, potentialDeconstructor.Item.WorldPosition, factorAtMaxDistance: 0.2f);
75  if (distFactor > bestDistFactor)
76  {
77  closestDeconstructor = potentialDeconstructor;
78  bestDistFactor = distFactor;
79  }
80  }
81  return closestDeconstructor;
82  }
83 
84  private void StartDeconstructor()
85  {
86  deconstructor.SetActive(active: true, user: character, createNetworkEvent: true);
87  }
88 
89  protected override bool CheckObjectiveSpecific()
90  {
91  if (Item.IgnoreByAI(character))
92  {
93  Abandon = true;
94  }
95  else if (deconstructor != null && deconstructor.Item.IgnoreByAI(character))
96  {
97  Abandon = true;
98  }
99  return !Abandon && IsCompleted;
100  }
101 
102  public override void Reset()
103  {
104  base.Reset();
105  decontainObjective = null;
106  }
107 
108  public void DropTarget()
109  {
110  if (Item != null && character.HasItem(Item))
111  {
112  Item.Drop(character);
113  }
114  }
115  }
116 }
AIObjectiveDeconstructItem(Item item, Character character, AIObjectiveManager objectiveManager, float priorityModifier=1)
override bool CheckObjectiveSpecific()
Should return whether the objective is completed or not.
void Drop(Character dropper, bool createNetworkEvent=true, bool setTransform=true)
bool IgnoreByAI(Character character)
void SetActive(bool active, Character user=null, bool createNetworkEvent=false)
bool RelocateOutputToMainSub
Should the output items left in the deconstructor be automatically moved to the main sub at the end o...