From 24cb7a3659eee7abc9d10c9ca295a34e2ea5b4ce Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Wed, 21 Feb 2018 11:12:49 +0200 Subject: [PATCH] Husk infection state can be decreased after the infection reaches the active state (causing the husk appendage to be removed). Calyxanide still has a conditional preventing the decrease, but now it's possible for modders to revert huskification without code modifications. Closes #258 --- .../Content/Items/Medical/medical.xml | 2 +- .../Source/Characters/Animation/Ragdoll.cs | 40 +++++++++++++++ .../Source/Characters/Character.cs | 4 +- .../Source/Characters/HuskInfection.cs | 51 ++++++++++++++----- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml b/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml index 9653d6a88..3690426d6 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml @@ -367,7 +367,7 @@ - + diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs index c45cceddc..9af3cd522 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs @@ -426,6 +426,46 @@ namespace Barotrauma Mass += limb.Mass; if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb); } + + public void RemoveLimb(Limb limb) + { + if (!Limbs.Contains(limb)) return; + + Limb[] newLimbs = new Limb[Limbs.Length - 1]; + + int i = 0; + foreach (Limb existingLimb in Limbs) + { + if (existingLimb == limb) continue; + newLimbs[i] = existingLimb; + i++; + } + + Limbs = newLimbs; + if (limbDictionary.ContainsKey(limb.type)) limbDictionary.Remove(limb.type); + + //remove all joints that were attached to the removed limb + LimbJoint[] attachedJoints = Array.FindAll(LimbJoints, lj => lj.LimbA == limb || lj.LimbB == limb); + if (attachedJoints.Length > 0) + { + LimbJoint[] newJoints = new LimbJoint[LimbJoints.Length - attachedJoints.Length]; + i = 0; + foreach (LimbJoint limbJoint in LimbJoints) + { + if (attachedJoints.Contains(limbJoint)) continue; + newJoints[i] = limbJoint; + i++; + } + LimbJoints = newJoints; + } + + + limb.Remove(); + foreach (LimbJoint limbJoint in attachedJoints) + { + GameMain.World.RemoveJoint(limbJoint); + } + } public bool OnLimbCollision(Fixture f1, Fixture f2, Contact contact) { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index eb71d466d..1315cb1ef 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -393,13 +393,11 @@ namespace Barotrauma set { if (ConfigPath != humanConfigFile) return; - + if (value <= 0.0f) { if (huskInfection != null) { - //already active, can't cure anymore - if (huskInfection.State == HuskInfection.InfectionState.Active) return; huskInfection.Remove(this); huskInfection = null; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/HuskInfection.cs b/Barotrauma/BarotraumaShared/Source/Characters/HuskInfection.cs index 6e76cfa04..08efbda6c 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/HuskInfection.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/HuskInfection.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Xml.Linq; @@ -17,6 +16,8 @@ namespace Barotrauma private InfectionState state; + private Limb huskAppendage; + private float incubationTimer; public float IncubationTimer { @@ -64,19 +65,24 @@ namespace Barotrauma private void UpdateDormantState(float deltaTime, Character character) { + if (state != InfectionState.Dormant) + { + DeactivateHusk(character); + } + float prevTimer = IncubationTimer; - state = InfectionState.Dormant; - IncubationTimer += deltaTime / IncubationDuration; - - if (Character.Controlled != character) return; } private void UpdateTransitionState(float deltaTime, Character character) { - IncubationTimer += deltaTime / IncubationDuration; - + if (state != InfectionState.Transition) + { + DeactivateHusk(character); + } + + IncubationTimer += deltaTime / IncubationDuration; state = InfectionState.Transition; } @@ -91,7 +97,6 @@ namespace Barotrauma character.AddDamage(CauseOfDeath.Husk, 0.5f * deltaTime, null); } - private void ActivateHusk(Character character) { character.NeedsAir = false; @@ -100,6 +105,9 @@ namespace Barotrauma private void AttachHuskAppendage(Character character) { + //husk appendage already created, don't do anything + if (huskAppendage != null) return; + XDocument doc = XMLExtensions.TryLoadXml(Path.Combine("Content", "Characters", "Human", "huskappendage.xml")); if (doc == null || doc.Root == null) return; @@ -125,18 +133,33 @@ namespace Barotrauma var torso = character.AnimController.GetLimb(LimbType.Torso); - var newLimb = new Limb(character, limbElement); - newLimb.body.Submarine = character.Submarine; - newLimb.body.SetTransform(torso.SimPosition, torso.Rotation); + huskAppendage = new Limb(character, limbElement); + huskAppendage.body.Submarine = character.Submarine; + huskAppendage.body.SetTransform(torso.SimPosition, torso.Rotation); - character.AnimController.AddLimb(newLimb); + character.AnimController.AddLimb(huskAppendage); character.AnimController.AddJoint(jointElement); } + private void DeactivateHusk(Character character) + { + character.NeedsAir = true; + RemoveHuskAppendage(character); + } + + private void RemoveHuskAppendage(Character character) + { + if (huskAppendage == null) return; + + character.AnimController.RemoveLimb(huskAppendage); + huskAppendage = null; + } + public void Remove(Character character) { - if (character != null) - character.OnDeath -= CharacterDead; + DeactivateHusk(character); + + if (character != null) character.OnDeath -= CharacterDead; } private void CharacterDead(Character character, CauseOfDeath causeOfDeath)