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)