Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -34,24 +34,29 @@ namespace Barotrauma
protected override bool Filter(Character target)
{
if (!IsValidTarget(target, character, requireTreatableAfflictions: false)) { return false; }
if (GetTreatableAfflictions(target).Any())
if (!IsValidTarget(target, character, out bool ignoredasMinorWounds))
{
return true;
}
else
{
//the target might be at a low enough health to be considered a valid target,
//but if all afflictions are below treatment thresholds, the bot won't (and shouldn't) treat them
// -> make the bot speak to make it clear the bot intentionally ignores very minor injuries
if (!charactersWithMinorInjuries.Contains(character))
if (ignoredasMinorWounds)
{
character.Speak(TextManager.GetWithVariable("dialogignoreminorinjuries", "[targetname]", target.Name).Value,
null, 1.0f, $"notreatableafflictions{target.Name}".ToIdentifier(), 10.0f);
charactersWithMinorInjuries.Add(character);
//the target might be at a low enough health to be considered a valid target,
//but if all afflictions are below treatment thresholds, the bot won't (and shouldn't) treat them
// -> make the bot speak to make it clear the bot intentionally ignores very minor injuries
if (character.IsOnPlayerTeam && target != character && !charactersWithMinorInjuries.Contains(target))
{
// But only speak about targets when we are not already actively treating, in which case we should be speaking about the current target.
if (objectiveManager.GetFirstActiveObjective<AIObjectiveRescue>() == null)
{
charactersWithMinorInjuries.Add(target);
character.Speak(TextManager.GetWithVariable("dialogignoreminorinjuries", "[targetname]", target.Name).Value,
delay: 1.0f,
identifier: $"notreatableafflictions{target.Name}".ToIdentifier(),
minDurationBetweenSimilar: 10.0f);
}
}
}
return false;
}
}
return true;
}
protected override IEnumerable<Character> GetList() => Character.CharacterList;
@@ -103,12 +108,13 @@ namespace Barotrauma
return Math.Clamp(vitality, 0, 100);
}
public static IEnumerable<Affliction> GetTreatableAfflictions(Character character, bool ignoreTreatmentThreshold = false)
public static IEnumerable<Affliction> GetTreatableAfflictions(Character character, bool ignoreTreatmentThreshold)
{
var allAfflictions = character.CharacterHealth.GetAllAfflictions();
foreach (Affliction affliction in allAfflictions)
{
if (affliction.Prefab.IsBuff) { continue; }
if (!affliction.Prefab.HasTreatments) { continue; }
if (!ignoreTreatmentThreshold)
{
//other afflictions of the same type increase the "treatability"
@@ -116,7 +122,6 @@ namespace Barotrauma
float totalAfflictionStrength = character.CharacterHealth.GetTotalAdjustedAfflictionStrength(affliction);
if (totalAfflictionStrength < affliction.Prefab.TreatmentThreshold) { continue; }
}
if (affliction.Prefab.TreatmentSuitability.None(kvp => kvp.Value > 0)) { continue; }
if (allAfflictions.Any(otherAffliction => affliction.Prefab.IgnoreTreatmentIfAfflictedBy.Contains(otherAffliction.Identifier))) { continue; }
yield return affliction;
}
@@ -128,39 +133,50 @@ namespace Barotrauma
protected override void OnObjectiveCompleted(AIObjective objective, Character target)
=> HumanAIController.RemoveTargets<AIObjectiveRescueAll, Character>(character, target);
public static bool IsValidTarget(Character target, Character character, bool requireTreatableAfflictions = true)
public static bool IsValidTarget(Character target, Character character, out bool ignoredAsMinorWounds)
{
ignoredAsMinorWounds = false;
if (target == null || target.IsDead || target.Removed) { return false; }
if (target.IsInstigator) { return false; }
if (target.IsPet) { return false; }
if (!HumanAIController.IsFriendly(character, target, onlySameTeam: true)) { return false; }
bool isBelowTreatmentThreshold;
float vitalityFactor;
if (character.AIController is HumanAIController humanAI)
{
if (GetVitalityFactor(target) >= GetVitalityThreshold(humanAI.ObjectiveManager, character, target))
{
return false;
}
if (!humanAI.ObjectiveManager.HasOrder<AIObjectiveRescueAll>())
{
if (!character.IsMedic && target != character)
{
// Don't allow to treat others autonomously, unless we are a medic
return false;
}
// Ignore unsafe hulls, unless ordered
if (humanAI.UnsafeHulls.Contains(target.CurrentHull))
{
return false;
}
}
if (requireTreatableAfflictions && GetTreatableAfflictions(target).None())
{
return false;
}
if (!IsValidTargetForAI(target, humanAI)) { return false; }
vitalityFactor = GetVitalityFactor(target);
isBelowTreatmentThreshold = vitalityFactor < GetVitalityThreshold(humanAI.ObjectiveManager, character, target);
}
else
{
if (GetVitalityFactor(target) >= vitalityThreshold) { return false; }
vitalityFactor = GetVitalityFactor(target);
isBelowTreatmentThreshold = vitalityFactor < vitalityThreshold;
}
bool hasTreatableAfflictions = GetTreatableAfflictions(target, ignoreTreatmentThreshold: false).Any();
bool isValidTarget = isBelowTreatmentThreshold && hasTreatableAfflictions;
if (!isValidTarget)
{
ignoredAsMinorWounds = hasTreatableAfflictions || vitalityFactor < 100;
}
return isValidTarget;
}
private static bool IsValidTargetForAI(Character target, HumanAIController humanAI)
{
Character character = humanAI.Character;
if (!humanAI.ObjectiveManager.HasOrder<AIObjectiveRescueAll>())
{
if (!character.IsMedic && target != character)
{
// Don't allow to treat others autonomously, unless we are a medic
return false;
}
// Ignore unsafe hulls, unless ordered
if (humanAI.UnsafeHulls.Contains(target.CurrentHull))
{
return false;
}
}
if (character.Submarine != null)
{
@@ -189,11 +205,5 @@ namespace Barotrauma
}
return character.GetDamageDoneByAttacker(target) <= 0;
}
public override void Reset()
{
base.Reset();
charactersWithMinorInjuries.Clear();
}
}
}