Unstable 1.8.4.0

This commit is contained in:
Markus Isberg
2025-03-12 12:56:27 +00:00
parent a4c3e868e4
commit a4a3427e4e
627 changed files with 29860 additions and 10018 deletions
@@ -28,8 +28,6 @@ namespace Barotrauma
private bool stun = false;
private readonly List<Affliction> huskInfection = new List<Affliction>();
[Serialize(0f, IsPropertySaveable.Yes), Editable]
public override float Strength
{
@@ -62,7 +60,7 @@ namespace Barotrauma
}
}
private readonly AfflictionPrefabHusk HuskPrefab;
public readonly AfflictionPrefabHusk HuskPrefab;
private float DormantThreshold => HuskPrefab.DormantThreshold;
private float ActiveThreshold => HuskPrefab.ActiveThreshold;
@@ -129,7 +127,7 @@ namespace Barotrauma
{
State = InfectionState.Final;
ActivateHusk();
ApplyDamage(deltaTime, applyForce: true);
ApplyDamage(deltaTime);
character.SetStun(5);
}
}
@@ -192,27 +190,41 @@ namespace Barotrauma
prevDisplayedMessage = State;
}
private void ApplyDamage(float deltaTime, bool applyForce)
private const float DamageCooldown = 0.1f;
private float damageCooldownTimer;
private void ApplyDamage(float deltaTime)
{
int limbCount = character.AnimController.Limbs.Count(l => !l.IgnoreCollisions && !l.IsSevered && !l.Hidden);
if (damageCooldownTimer > 0)
{
damageCooldownTimer -= deltaTime;
return;
}
damageCooldownTimer = DamageCooldown;
int limbCount = character.AnimController.Limbs.Count(IsValidLimb);
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.IsSevered) { continue; }
if (limb.Hidden) { continue; }
if (!IsValidLimb(limb)) { continue; }
float random = Rand.Value();
huskInfection.Clear();
huskInfection.Add(AfflictionPrefab.InternalDamage.Instantiate(random * 10 * deltaTime / limbCount));
if (random == 0) { continue; }
const float damageRate = 2;
float dmg = random / limbCount * damageRate;
character.LastDamageSource = null;
float force = applyForce ? random * 0.5f * limb.Mass : 0;
character.DamageLimb(limb.WorldPosition, limb, huskInfection, 0, false, Rand.Vector(force));
var afflictions = AfflictionPrefab.InternalDamage.Instantiate(dmg).ToEnumerable();
const float forceMultiplier = 5;
float force = dmg * limb.Mass * forceMultiplier;
character.DamageLimb(limb.WorldPosition, limb, afflictions, stun: 0, playSound: false, Rand.Vector(force), ignoreDamageOverlay: true, recalculateVitality: false);
}
character.CharacterHealth.RecalculateVitality();
static bool IsValidLimb(Limb limb) => !limb.IgnoreCollisions && !limb.IsSevered && !limb.Hidden;
}
public void ActivateHusk()
{
if (huskAppendage == null && character.Params.UseHuskAppendage)
{
huskAppendage = AttachHuskAppendage(character, Prefab as AfflictionPrefabHusk);
var huskAffliction = Prefab as AfflictionPrefabHusk;
huskAppendage = AttachHuskAppendage(character, huskAffliction, GetHuskedSpeciesName(character.Params, huskAffliction));
}
if (Prefab is AfflictionPrefabHusk { NeedsAir: false })
@@ -287,7 +299,7 @@ namespace Barotrauma
Entity.Spawner.AddEntityToRemoveQueue(character);
UnsubscribeFromDeathEvent();
Identifier huskedSpeciesName = GetHuskedSpeciesName(character.SpeciesName, Prefab as AfflictionPrefabHusk);
Identifier huskedSpeciesName = GetHuskedSpeciesName(character.Params, Prefab as AfflictionPrefabHusk);
CharacterPrefab prefab = CharacterPrefab.FindBySpeciesName(huskedSpeciesName);
if (prefab == null)
@@ -309,11 +321,16 @@ namespace Barotrauma
}
var husk = Character.Create(huskedSpeciesName, character.WorldPosition, ToolBox.RandomSeed(8), huskCharacterInfo, isRemotePlayer: false, hasAi: true);
if (character.HasAbilityFlag(AbilityFlags.IgnoredByEnemyAI))
{
husk.AddAbilityFlag(AbilityFlags.IgnoredByEnemyAI);
}
if (husk.Info != null)
{
husk.Info.Character = husk;
husk.Info.TeamID = CharacterTeamType.None;
}
husk.AllowPlayDead = character.AllowPlayDead;
if (Prefab is AfflictionPrefabHusk huskPrefab)
{
@@ -379,17 +396,15 @@ namespace Barotrauma
yield return CoroutineStatus.Success;
}
public static List<Limb> AttachHuskAppendage(Character character, AfflictionPrefabHusk matchingAffliction, ContentXElement appendageDefinition = null, Ragdoll ragdoll = null)
public static List<Limb> AttachHuskAppendage(Character character, AfflictionPrefabHusk matchingAffliction, Identifier huskedSpeciesName, ContentXElement appendageDefinition = null, Ragdoll ragdoll = null)
{
var appendage = new List<Limb>();
Identifier nonhuskedSpeciesName = GetNonHuskedSpeciesName(character.SpeciesName, matchingAffliction);
Identifier huskedSpeciesName = GetHuskedSpeciesName(nonhuskedSpeciesName, matchingAffliction);
var appendageLimbs = new List<Limb>();
CharacterPrefab huskPrefab = CharacterPrefab.FindBySpeciesName(huskedSpeciesName);
if (huskPrefab?.ConfigElement == null)
{
DebugConsole.ThrowError($"Failed to find the config file for the husk infected species with the species name '{huskedSpeciesName}'!",
contentPackage: matchingAffliction.ContentPackage);
return appendage;
return appendageLimbs;
}
var mainElement = huskPrefab.ConfigElement;
var element = appendageDefinition;
@@ -401,28 +416,25 @@ namespace Barotrauma
{
DebugConsole.ThrowError($"Error in '{huskPrefab.FilePath}': Failed to find a huskappendage that matches the affliction with an identifier '{matchingAffliction.Identifier}'!",
contentPackage: matchingAffliction.ContentPackage);
return appendage;
return appendageLimbs;
}
ContentPath pathToAppendage = element.GetAttributeContentPath("path") ?? ContentPath.Empty;
XDocument doc = XMLExtensions.TryLoadXml(pathToAppendage);
if (doc == null) { return appendage; }
if (ragdoll == null)
{
ragdoll = character.AnimController;
}
if (doc == null) { return appendageLimbs; }
ragdoll ??= character.AnimController;
if (ragdoll.Dir < 1.0f)
{
ragdoll.Flip();
}
var root = doc.Root.FromPackage(pathToAppendage.ContentPackage);
var limbElements = root.GetChildElements("limb").ToDictionary(e => e.GetAttributeString("id", null), e => e);
var limbElements = root.GetChildElements("limb").ToDictionary(e => e.GetAttributeInt("id", -1), e => e);
//the IDs may need to be offset if the character has other extra appendages (e.g. from gene splicing)
//that take up the IDs of this appendage
int idOffset = 0;
int? idOffset = null;
foreach (var jointElement in root.GetChildElements("joint"))
{
if (!limbElements.TryGetValue(jointElement.GetAttributeString("limb2", null), out ContentXElement limbElement)) { continue; }
if (!limbElements.TryGetValue(jointElement.GetAttributeInt("limb2", -1), out ContentXElement limbElement)) { continue; }
var jointParams = new RagdollParams.JointParams(jointElement, ragdoll.RagdollParams);
Limb attachLimb = null;
@@ -444,38 +456,54 @@ namespace Barotrauma
}
if (attachLimb != null)
{
jointParams.Limb1 = attachLimb.Params.ID;
//the joint attaches to a limb outside the character's normal limb count = to another part of the appendage
// -> if the appendage's IDs have been offset, we need to take that into account to attach to the correct limb
if (jointParams.Limb1 >= ragdoll.RagdollParams.Limbs.Count)
{
jointParams.Limb1 += idOffset;
}
var appendageLimbParams = new RagdollParams.LimbParams(limbElement, ragdoll.RagdollParams);
if (idOffset == 0)
idOffset ??= ragdoll.Limbs.Length - appendageLimbParams.ID;
jointParams.Limb1 = attachLimb.Params.ID;
//the joint attaches to one of the limbs we're creating = to another part of the appendage
// -> if the appendage's IDs have been offset, we need to take that into account to attach to the correct limb
if (limbElements.ContainsKey(jointParams.Limb1))
{
idOffset = ragdoll.Limbs.Length - appendageLimbParams.ID;
jointParams.Limb1 += idOffset.Value;
}
jointParams.Limb2 = appendageLimbParams.ID = ragdoll.Limbs.Length;
Limb huskAppendage = new Limb(ragdoll, character, appendageLimbParams);
if (limbElements.ContainsKey(jointParams.Limb2))
{
jointParams.Limb2 += idOffset.Value;
}
Limb huskAppendage =
//check if this joint is supposed to attach to a limb we already created
appendageLimbs.Find(limb => limb.Params.ID == appendageLimbParams.ID) ??
//if not, create a new limb
new Limb(ragdoll, character, appendageLimbParams);
huskAppendage.body.Submarine = character.Submarine;
huskAppendage.body.SetTransform(attachLimb.SimPosition, attachLimb.Rotation);
ragdoll.AddLimb(huskAppendage);
ragdoll.AddJoint(jointParams);
appendage.Add(huskAppendage);
}
appendageLimbs.Add(huskAppendage);
}
}
return appendage;
return appendageLimbs;
}
public static Identifier GetHuskedSpeciesName(Identifier speciesName, AfflictionPrefabHusk prefab)
public static Identifier GetHuskedSpeciesName(CharacterParams character, AfflictionPrefabHusk prefab)
{
return new Identifier(speciesName.Value + prefab.HuskedSpeciesName.Value);
Identifier huskedSpecies = character.HuskedSpecies;
if (huskedSpecies.IsEmpty)
{
// Default pattern: Crawler -> Crawlerhusk, Human -> Humanhusk
return new Identifier(character.SpeciesName.Value + prefab.HuskedSpeciesName.Value);
}
return huskedSpecies;
}
public static Identifier GetNonHuskedSpeciesName(Identifier huskedSpeciesName, AfflictionPrefabHusk prefab)
public static Identifier GetNonHuskedSpeciesName(CharacterParams character, AfflictionPrefabHusk prefab)
{
return huskedSpeciesName.Remove(prefab.HuskedSpeciesName);
Identifier nonHuskedSpecies = character.NonHuskedSpecies;
if (nonHuskedSpecies.IsEmpty)
{
// Default pattern: Crawlerhusk -> Crawler, Humanhusk -> Human
return character.SpeciesName.Remove(prefab.HuskedSpeciesName);
}
return nonHuskedSpecies;
}
}
}