Unstable 1.8.4.0
This commit is contained in:
+74
-46
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user