v1.4.4.1 (Blood in the Water Update)

This commit is contained in:
Regalis11
2024-04-24 18:09:05 +03:00
parent 89b91d1c3e
commit ff1b8951a7
397 changed files with 15250 additions and 6479 deletions
@@ -278,52 +278,66 @@ namespace Barotrauma
float cprSuitability = Target.Oxygen < 0.0f ? -Target.Oxygen * 100.0f : 0.0f;
//find which treatments are the most suitable to treat the character's current condition
Target.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, user: character, normalize: false, predictFutureDuration: 10.0f);
//check if we already have a suitable treatment for any of the afflictions
float bestSuitability = 0.0f;
Item bestItem = null;
Affliction afflictionToTreat = null;
foreach (Affliction affliction in GetSortedAfflictions(Target))
{
if (affliction == null) { throw new Exception("Affliction was null"); }
if (affliction.Prefab == null) { throw new Exception("Affliction prefab was null"); }
float bestSuitability = 0.0f;
Item bestItem = null;
foreach (KeyValuePair<Identifier, float> treatmentSuitability in affliction.Prefab.TreatmentSuitabilities)
//find which treatments are the most suitable to treat the character's current condition
Target.CharacterHealth.GetSuitableTreatments(
currentTreatmentSuitabilities,
limb: Target.CharacterHealth.GetAfflictionLimb(affliction),
user: character,
predictFutureDuration: 10.0f);
foreach (KeyValuePair<Identifier, float> treatmentSuitability in currentTreatmentSuitabilities)
{
if (currentTreatmentSuitabilities.ContainsKey(treatmentSuitability.Key) &&
currentTreatmentSuitabilities[treatmentSuitability.Key] > bestSuitability)
float thisSuitability = currentTreatmentSuitabilities[treatmentSuitability.Key];
if (thisSuitability <= 0) { continue; }
Item matchingItem = FindMedicalItem(character.Inventory, treatmentSuitability.Key);
//allow taking items from the target's inventory too if the target is unconscious
if (matchingItem == null && Target.IsIncapacitated)
{
Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key, true);
//allow taking items from the target's inventory too if the target is unconscious
if (matchingItem == null && Target.IsIncapacitated)
{
matchingItem ??= Target.Inventory?.FindItemByIdentifier(treatmentSuitability.Key, true);
}
if (matchingItem != null)
{
bestItem = matchingItem;
bestSuitability = currentTreatmentSuitabilities[treatmentSuitability.Key];
}
matchingItem = FindMedicalItem(Target.Inventory, treatmentSuitability.Key);
}
}
if (bestItem != null)
{
if (Target != character) { character.SelectCharacter(Target); }
ApplyTreatment(affliction, bestItem);
//wait a bit longer after applying a treatment to wait for potential side-effects to manifest
treatmentTimer = TreatmentDelay * 4;
return;
if (matchingItem == null) { continue; }
//also check how suitable the treatment is for the specific affliction we're now checking
//we don't want to e.g. give fentanyl for oxygen low just because the character has burns on other limbs
//that would also be healed by it!
float suitabilityForThisAffliction = affliction.Prefab.GetTreatmentSuitability(matchingItem);
float totalSuitability = thisSuitability * suitabilityForThisAffliction;
if (matchingItem != null && totalSuitability > bestSuitability)
{
bestItem = matchingItem;
afflictionToTreat = affliction;
bestSuitability = totalSuitability;
}
}
}
if (bestItem != null && bestSuitability > cprSuitability)
{
if (Target != character) { character.SelectCharacter(Target); }
ApplyTreatment(afflictionToTreat, bestItem);
//wait a bit longer after applying a treatment to wait for potential side-effects to manifest
treatmentTimer = TreatmentDelay * 4;
return;
}
// Find treatments outside of own inventory only if inside the own sub.
if (character.Submarine != null && character.Submarine.TeamID == character.TeamID)
{
//get "overall" suitability for no specific limb at this point
Target.CharacterHealth.GetSuitableTreatments(
currentTreatmentSuitabilities, user: character, predictFutureDuration: 10.0f);
//didn't have any suitable treatments available, try to find some medical items
if (currentTreatmentSuitabilities.Any(s => s.Value > cprSuitability))
{
itemNameList.Clear();
suitableItemIdentifiers.Clear();
foreach (KeyValuePair<Identifier, float> treatmentSuitability in currentTreatmentSuitabilities)
foreach (KeyValuePair<Identifier, float> treatmentSuitability in currentTreatmentSuitabilities.OrderByDescending(s => s.Value))
{
if (treatmentSuitability.Value <= cprSuitability) { continue; }
if (ItemPrefab.Prefabs.TryGet(treatmentSuitability.Key, out ItemPrefab itemPrefab))
@@ -420,6 +434,28 @@ namespace Barotrauma
}
}
public static Item FindMedicalItem(Inventory inventory, Identifier itemIdentifier)
{
return FindMedicalItem(inventory, it => it.Prefab.Identifier == itemIdentifier);
}
public static Item FindMedicalItem(Inventory inventory, Func<Item, bool> predicate)
{
if (inventory == null) { return null; }
//prefer items not in a container
Item match = inventory.FindItem(predicate, recursive: false);
if (match != null) { return match; }
//start from the inventories with most slots
//= prefer taking items from things like toolbelts or doctor's uniforms, as opposed to e.g. autoinjectors which tend to have one or two slots
foreach (var potentialContainer in inventory.AllItems.OrderByDescending(it => it.OwnInventory?.Capacity ?? -1))
{
match = potentialContainer.OwnInventory?.FindItem(predicate, recursive: true);
if (match != null) { return match; }
}
return null;
}
private void SpeakCannotTreat()
{
LocalizedString msg = character == Target ?