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  private AIObjectiveGoTo gotoObjective;
19 
21  : base(character, objectiveManager, priorityModifier)
22  {
23  Item = item;
24  }
25 
26  protected override void Act(float deltaTime)
27  {
28  if (subObjectives.Any()) { return; }
29 
30  if (deconstructor == null)
31  {
32  deconstructor = FindDeconstructor();
33  if (deconstructor == null)
34  {
35  Abandon = true;
36  return;
37  }
38  }
39 
40  TryAddSubObjective(ref decontainObjective,
42  sourceContainer: Item.Container?.GetComponent<ItemContainer>(), targetContainer: deconstructor.InputContainer, priorityModifier: PriorityModifier)
43  {
44  Equip = true,
45  RemoveExistingWhenNecessary = true
46  },
47  onCompleted: () =>
48  {
49  if (character.CanInteractWith(deconstructor.Item))
50  {
51  StartDeconstruction();
52  }
53  else
54  {
55  TryAddSubObjective(ref gotoObjective,
56  constructor: () => new AIObjectiveGoTo(Item, character, objectiveManager, priorityModifier: PriorityModifier),
57  onCompleted: () =>
58  {
59  StartDeconstruction();
60  RemoveSubObjective(ref gotoObjective);
61  },
62  onAbandon: () =>
63  {
64  Abandon = true;
65  });
66  }
67  RemoveSubObjective(ref decontainObjective);
68  },
69  onAbandon: () =>
70  {
71  Abandon = true;
72  });
73  }
74 
75  private void StartDeconstruction()
76  {
77  StartDeconstructor();
78  //make sure the item gets moved to the main sub if the crew leaves while a bot is deconstructing something in the outpost
79  if (deconstructor.Item.Submarine is { Info.IsOutpost: true })
80  {
81  HumanAIController.HandleRelocation(Item);
82  deconstructor.RelocateOutputToMainSub = true;
83  }
84  IsCompleted = true;
85  }
86 
87  private Deconstructor FindDeconstructor()
88  {
89  Deconstructor closestDeconstructor = null;
90  float bestDistFactor = 0;
91  foreach (var otherItem in Item.ItemList)
92  {
93  var potentialDeconstructor = otherItem.GetComponent<Deconstructor>();
94  if (potentialDeconstructor?.InputContainer == null) { continue; }
95  if (!potentialDeconstructor.InputContainer.Inventory.CanBePut(Item)) { continue; }
96  if (!potentialDeconstructor.Item.HasAccess(character)) { continue; }
97  float distFactor = GetDistanceFactor(Item.WorldPosition, potentialDeconstructor.Item.WorldPosition, factorAtMaxDistance: 0.2f);
98  if (distFactor > bestDistFactor)
99  {
100  closestDeconstructor = potentialDeconstructor;
101  bestDistFactor = distFactor;
102  }
103  }
104  return closestDeconstructor;
105  }
106 
107  private void StartDeconstructor()
108  {
109  deconstructor.SetActive(active: true, user: character, createNetworkEvent: true);
110  }
111 
112  protected override bool CheckObjectiveState()
113  {
114  if (Item.IgnoreByAI(character))
115  {
116  Abandon = true;
117  }
118  else if (deconstructor != null && deconstructor.Item.IgnoreByAI(character))
119  {
120  Abandon = true;
121  }
122  return !Abandon && IsCompleted;
123  }
124 
125  public override void Reset()
126  {
127  base.Reset();
128  decontainObjective = null;
129  }
130 
131  public void DropTarget()
132  {
133  if (Item != null && character.HasItem(Item))
134  {
135  Item.Drop(character);
136  }
137  }
138  }
139 }
AIObjectiveDeconstructItem(Item item, Character character, AIObjectiveManager objectiveManager, float priorityModifier=1)
override bool CheckObjectiveState()
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)