Client LuaCsForBarotrauma
AIObjectiveFixLeaks.cs
1 using Microsoft.Xna.Framework;
2 using System.Linq;
3 using System.Collections.Generic;
4 
5 namespace Barotrauma
6 {
8  {
9  public override Identifier Identifier { get; set; } = "fix leaks".ToIdentifier();
10  public override bool ForceRun => true;
11  public override bool KeepDivingGearOn => true;
12  protected override bool AllowInFriendlySubs => true;
13 
14  private Hull PrioritizedHull { get; set; }
15 
16  public AIObjectiveFixLeaks(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1, Hull prioritizedHull = null) : base(character, objectiveManager, priorityModifier)
17  {
18  PrioritizedHull = prioritizedHull;
19  }
20 
21  protected override bool IsValidTarget(Gap gap) => IsValidTarget(gap, character);
22 
23  public static float GetLeakSeverity(Gap leak)
24  {
25  if (leak == null) { return 0; }
26  float sizeFactor = MathHelper.Lerp(1, 10, MathUtils.InverseLerp(0, 200, leak.Size));
27  float severity = sizeFactor * leak.Open;
28  if (!leak.IsRoomToRoom)
29  {
30  severity *= 10;
31  // If there is a leak in the outer walls, the severity cannot be lower than 10, no matter how small the leak
32  return MathHelper.Clamp(severity, 10, 100);
33  }
34  else
35  {
36  return MathHelper.Min(severity, 100);
37  }
38  }
39 
40  protected override float GetTargetPriority()
41  {
42  int totalLeaks = Targets.Count;
43  if (totalLeaks == 0) { return 0; }
44  int otherFixers = HumanAIController.CountBotsInTheCrew(c => c != HumanAIController && c.ObjectiveManager.IsCurrentObjective<AIObjectiveFixLeaks>() && c.Character.Submarine == character.Submarine);
45  bool anyFixers = otherFixers > 0;
46  if (objectiveManager.IsOrder(this))
47  {
48  float ratio = anyFixers ? totalLeaks / (float)otherFixers : 1;
49  return Targets.Sum(t => GetLeakSeverity(t)) * ratio;
50  }
51  else
52  {
53  int secondaryLeaks = Targets.Count(l => l.IsRoomToRoom);
54  int leaks = totalLeaks - secondaryLeaks;
55  float ratio = leaks == 0 ? 1 : anyFixers ? leaks / (float)otherFixers : 1;
56  if (anyFixers && (ratio <= 1 || otherFixers > 5 || otherFixers / (float)HumanAIController.CountBotsInTheCrew() > 0.75f))
57  {
58  // Enough fixers
59  return 0;
60  }
61  return Targets.Sum(t => GetLeakSeverity(t)) * ratio;
62  }
63  }
64 
65  protected override IEnumerable<Gap> GetList() => Gap.GapList;
66  protected override AIObjective ObjectiveConstructor(Gap gap)
67  => new AIObjectiveFixLeak(gap, character, objectiveManager, priorityModifier: PriorityModifier, isPriority: gap.FlowTargetHull == PrioritizedHull);
68 
69  protected override void OnObjectiveCompleted(AIObjective objective, Gap target)
70  => HumanAIController.RemoveTargets<AIObjectiveFixLeaks, Gap>(character, target);
71 
72  public static bool IsValidTarget(Gap gap, Character character)
73  {
74  if (gap == null) { return false; }
75  // Don't fix a leak on a wall section set to be ignored
76  if (gap.ConnectedWall != null)
77  {
78  if (gap.ConnectedWall.Sections.Any(s => s.gap == gap && s.IgnoreByAI(character))) { return false; }
79  if (gap.ConnectedWall.MaxHealth <= 0.0f) { return false; }
80  }
81  if (gap.ConnectedWall == null || gap.ConnectedDoor != null || gap.Open <= 0 || gap.linkedTo.All(l => l == null)) { return false; }
82  if (gap.Submarine == null || character.Submarine == null) { return false; }
83  // Don't allow going into another sub, unless it's connected and of the same team and type.
84  if (!character.Submarine.IsEntityFoundOnThisSub(gap, includingConnectedSubs: true)) { return false; }
85  return true;
86  }
87  }
88 }
static float GetLeakSeverity(Gap leak)
override AIObjective ObjectiveConstructor(Gap gap)
override void OnObjectiveCompleted(AIObjective objective, Gap target)
static bool IsValidTarget(Gap gap, Character character)
AIObjectiveFixLeaks(Character character, AIObjectiveManager objectiveManager, float priorityModifier=1, Hull prioritizedHull=null)
override bool IsValidTarget(Gap gap)
override IEnumerable< Gap > GetList()
List of all possible items of the specified type. Used for filtering the removed objectives.
override float GetTargetPriority()
Returns a priority value based on the current targets (e.g. high prio when there's lots of severe fir...
An objective that creates specific kinds of subobjectives for specific types of targets,...
Submarine Submarine
Definition: Entity.cs:53
static int CountBotsInTheCrew(Character character, Func< HumanAIController, bool > predicate=null)
bool IsEntityFoundOnThisSub(MapEntity entity, bool includingConnectedSubs, bool allowDifferentTeam=false, bool allowDifferentType=false)