3 using System.Collections.Generic;
16 private readonly HashSet<Character> charactersWithMinorInjuries =
new HashSet<Character>();
18 private const float vitalityThreshold = 75;
19 private const float vitalityThresholdForOrders = 90;
24 return vitalityThreshold;
28 return character == target || manager.HasOrder<
AIObjectiveRescueAll>() ? vitalityThresholdForOrders : vitalityThreshold;
33 : base(character, objectiveManager, priorityModifier) { }
37 if (!
IsValidTarget(target, character, out
bool ignoredasMinorWounds))
39 if (ignoredasMinorWounds)
44 if (character.IsOnPlayerTeam && target != character && !charactersWithMinorInjuries.Contains(target))
49 charactersWithMinorInjuries.Add(target);
50 character.Speak(TextManager.GetWithVariable(
"dialogignoreminorinjuries",
"[targetname]", target.
Name).Value,
52 identifier: $
"notreatableafflictions{target.Name}".ToIdentifier(),
53 minDurationBetweenSimilar: 10.0f);
66 if (
Targets.None()) {
return 100; }
67 if (!objectiveManager.IsOrder(
this))
76 if (
Targets.Contains(character))
79 if (character.Bleeding > 10)
87 return worstCondition;
94 vitality += Math.Min(character.
Oxygen, 0);
97 float strength = character.CharacterHealth.GetPredictedStrength(affliction, predictFutureDuration: 10.0f);
98 vitality -= affliction.
GetVitalityDecrease(character.CharacterHealth, strength) / character.MaxVitality * 100;
115 return Math.Clamp(vitality, 0, 100);
121 foreach (
Affliction affliction
in allAfflictions)
125 if (!ignoreTreatmentThreshold)
129 float totalAfflictionStrength = character.CharacterHealth.GetTotalAdjustedAfflictionStrength(affliction);
133 yield
return affliction;
145 ignoredAsMinorWounds =
false;
146 if (target ==
null || target.
IsDead || target.
Removed) {
return false; }
148 if (target.
IsPet) {
return false; }
150 bool isBelowTreatmentThreshold;
151 float vitalityFactor;
154 if (!IsValidTargetForAI(target, humanAI)) {
return false; }
156 isBelowTreatmentThreshold = vitalityFactor <
GetVitalityThreshold(humanAI.ObjectiveManager, character, target);
161 isBelowTreatmentThreshold = vitalityFactor < vitalityThreshold;
164 bool isValidTarget = isBelowTreatmentThreshold && hasTreatableAfflictions;
167 ignoredAsMinorWounds = hasTreatableAfflictions || vitalityFactor < 100;
169 return isValidTarget;
177 if (!character.
IsMedic && target != character)
198 if (target != character && target.
IsBot && HumanAIController.IsActive(target) && target.
AIController is HumanAIController targetAI)
201 if (targetAI.ObjectiveManager.HasActiveObjective<AIObjectiveCombat>() ||
202 targetAI.ObjectiveManager.HasActiveObjective<AIObjectiveFindSafety>() ||
203 targetAI.ObjectiveManager.HasActiveObjective<AIObjectiveRescue>())
211 if (Character.CharacterList.Any(c => c.CurrentHull == target.
CurrentHull && !HumanAIController.IsFriendly(character, c) && HumanAIController.IsActive(c))) {
return false; }
readonly Character Character
An objective that creates specific kinds of subobjectives for specific types of targets,...
override bool AllowInAnySub
override bool AllowOutsideSubmarine
override void OnObjectiveCompleted(AIObjective objective, Character target)
static bool IsValidTarget(Character target, Character character, out bool ignoredAsMinorWounds)
override bool InverseTargetPriority
override Identifier Identifier
static IEnumerable< Affliction > GetTreatableAfflictions(Character character, bool ignoreTreatmentThreshold)
override IEnumerable< Character > 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...
static float GetVitalityThreshold(AIObjectiveManager manager, Character character, Character target)
AIObjectiveRescueAll(Character character, AIObjectiveManager objectiveManager, float priorityModifier=1)
static float GetVitalityFactor(Character character)
override bool IsValidTarget(Character target)
override AIObjective ObjectiveConstructor(Character target)
float GetVitalityDecrease(CharacterHealth characterHealth)
readonly AfflictionPrefab Prefab
AfflictionPrefab is a prefab that defines a type of affliction that can be applied to a character....
readonly bool IsBuff
If set to true, the game will recognize this affliction as a buff. This means, among other things,...
ImmutableHashSet< Identifier > IgnoreTreatmentIfAfflictedBy
Bots will not try to treat the affliction if the character has any of these afflictions
bool HasTreatments
Can this affliction be treated with some item?
static readonly Identifier ParalysisType
readonly Identifier AfflictionType
Arbitrary string that is used to identify the type of the affliction.
readonly float TreatmentThreshold
How strong the affliction needs to be before bots attempt to treat it. Also effects when the afflicti...
static readonly Identifier PoisonType
static AfflictionPrefab HuskInfection
IReadOnlyCollection< Affliction > GetAllAfflictions()
float GetDamageDoneByAttacker(Character otherCharacter)
CharacterHealth CharacterHealth
virtual AIController AIController
static readonly List< Character > CharacterList
bool IsTrueForAnyCrewMember(Func< Character, bool > predicate, bool onlyActive=true, bool onlyConnectedSubs=false)
Including the player characters in the same team.
AIObjectiveManager ObjectiveManager
static bool IsFriendly(Character me, Character other, bool onlySameTeam=false)
readonly HashSet< Hull > UnsafeHulls
bool IsEntityFoundOnThisSub(MapEntity entity, bool includingConnectedSubs, bool allowDifferentTeam=false, bool allowDifferentType=false)