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

This commit is contained in:
Joonas Rikkonen
2018-02-21 11:12:49 +02:00
parent d414e8e103
commit 24cb7a3659
4 changed files with 79 additions and 18 deletions
@@ -367,7 +367,7 @@
<Body width="8" height="16" density="10"/> <Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10"> <Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" HuskInfectionState="-0.2" setvalue="true"> <StatusEffect type="OnUse" target="Character" HuskInfectionState="-0.2">
<Conditional HuskInfectionState="lt 1.0"/> <Conditional HuskInfectionState="lt 1.0"/>
<RequiredItem name="Medical Syringe" type="Container"/> <RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect> </StatusEffect>
@@ -426,6 +426,46 @@ namespace Barotrauma
Mass += limb.Mass; Mass += limb.Mass;
if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb); 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) public bool OnLimbCollision(Fixture f1, Fixture f2, Contact contact)
{ {
@@ -393,13 +393,11 @@ namespace Barotrauma
set set
{ {
if (ConfigPath != humanConfigFile) return; if (ConfigPath != humanConfigFile) return;
if (value <= 0.0f) if (value <= 0.0f)
{ {
if (huskInfection != null) if (huskInfection != null)
{ {
//already active, can't cure anymore
if (huskInfection.State == HuskInfection.InfectionState.Active) return;
huskInfection.Remove(this); huskInfection.Remove(this);
huskInfection = null; huskInfection = null;
} }
@@ -1,5 +1,4 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Xml.Linq; using System.Xml.Linq;
@@ -17,6 +16,8 @@ namespace Barotrauma
private InfectionState state; private InfectionState state;
private Limb huskAppendage;
private float incubationTimer; private float incubationTimer;
public float IncubationTimer public float IncubationTimer
{ {
@@ -64,19 +65,24 @@ namespace Barotrauma
private void UpdateDormantState(float deltaTime, Character character) private void UpdateDormantState(float deltaTime, Character character)
{ {
if (state != InfectionState.Dormant)
{
DeactivateHusk(character);
}
float prevTimer = IncubationTimer; float prevTimer = IncubationTimer;
state = InfectionState.Dormant; state = InfectionState.Dormant;
IncubationTimer += deltaTime / IncubationDuration; IncubationTimer += deltaTime / IncubationDuration;
if (Character.Controlled != character) return;
} }
private void UpdateTransitionState(float deltaTime, Character character) private void UpdateTransitionState(float deltaTime, Character character)
{ {
IncubationTimer += deltaTime / IncubationDuration; if (state != InfectionState.Transition)
{
DeactivateHusk(character);
}
IncubationTimer += deltaTime / IncubationDuration;
state = InfectionState.Transition; state = InfectionState.Transition;
} }
@@ -91,7 +97,6 @@ namespace Barotrauma
character.AddDamage(CauseOfDeath.Husk, 0.5f * deltaTime, null); character.AddDamage(CauseOfDeath.Husk, 0.5f * deltaTime, null);
} }
private void ActivateHusk(Character character) private void ActivateHusk(Character character)
{ {
character.NeedsAir = false; character.NeedsAir = false;
@@ -100,6 +105,9 @@ namespace Barotrauma
private void AttachHuskAppendage(Character character) 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")); XDocument doc = XMLExtensions.TryLoadXml(Path.Combine("Content", "Characters", "Human", "huskappendage.xml"));
if (doc == null || doc.Root == null) return; if (doc == null || doc.Root == null) return;
@@ -125,18 +133,33 @@ namespace Barotrauma
var torso = character.AnimController.GetLimb(LimbType.Torso); var torso = character.AnimController.GetLimb(LimbType.Torso);
var newLimb = new Limb(character, limbElement); huskAppendage = new Limb(character, limbElement);
newLimb.body.Submarine = character.Submarine; huskAppendage.body.Submarine = character.Submarine;
newLimb.body.SetTransform(torso.SimPosition, torso.Rotation); huskAppendage.body.SetTransform(torso.SimPosition, torso.Rotation);
character.AnimController.AddLimb(newLimb); character.AnimController.AddLimb(huskAppendage);
character.AnimController.AddJoint(jointElement); 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) public void Remove(Character character)
{ {
if (character != null) DeactivateHusk(character);
character.OnDeath -= CharacterDead;
if (character != null) character.OnDeath -= CharacterDead;
} }
private void CharacterDead(Character character, CauseOfDeath causeOfDeath) private void CharacterDead(Character character, CauseOfDeath causeOfDeath)