Husk infections, manually attacking when controlling a creature
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class HuskInfection
|
||||
{
|
||||
public enum InfectionState
|
||||
{
|
||||
Dormant, Transition, Active
|
||||
}
|
||||
|
||||
const float IncubationDuration = 300.0f;
|
||||
|
||||
private InfectionState state;
|
||||
|
||||
private float incubationTimer;
|
||||
public float IncubationTimer
|
||||
{
|
||||
get { return incubationTimer; }
|
||||
set
|
||||
{
|
||||
incubationTimer = MathHelper.Clamp(value, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public InfectionState State
|
||||
{
|
||||
get { return state; }
|
||||
}
|
||||
|
||||
public bool CanSpeak
|
||||
{
|
||||
get { return IncubationTimer < 0.5f; }
|
||||
}
|
||||
|
||||
public HuskInfection(Character character)
|
||||
{
|
||||
character.OnDeath += CharacterDead;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime, Character character)
|
||||
{
|
||||
if (IncubationTimer < 0.5f)
|
||||
{
|
||||
UpdateDormantState(deltaTime, character);
|
||||
}
|
||||
else if (IncubationTimer < 1.0f)
|
||||
{
|
||||
UpdateTransitionState(deltaTime, character);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateActiveState(deltaTime, character);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDormantState(float deltaTime, Character character)
|
||||
{
|
||||
float prevTimer = IncubationTimer;
|
||||
|
||||
state = InfectionState.Dormant;
|
||||
|
||||
IncubationTimer += 100* deltaTime / IncubationDuration;
|
||||
|
||||
if (Character.Controlled != character) return;
|
||||
|
||||
if (prevTimer % 0.1f > 0.05f && IncubationTimer % 0.1f < 0.05f)
|
||||
{
|
||||
GUI.AddMessage(InfoTextManager.GetInfoText("HuskDormant"), Color.Red, 4.0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTransitionState(float deltaTime, Character character)
|
||||
{
|
||||
IncubationTimer += deltaTime*10.0f/ IncubationDuration;
|
||||
|
||||
if (state == InfectionState.Dormant && Character.Controlled == character)
|
||||
{
|
||||
new GUIMessageBox("", InfoTextManager.GetInfoText("HuskCantSpeak"));
|
||||
}
|
||||
|
||||
state = InfectionState.Transition;
|
||||
}
|
||||
|
||||
private void UpdateActiveState(float deltaTime, Character character)
|
||||
{
|
||||
if (state != InfectionState.Active)
|
||||
{
|
||||
if (Character.Controlled==character) new GUIMessageBox("", InfoTextManager.GetInfoText("HuskActivate"));
|
||||
ActivateHusk(character);
|
||||
state = InfectionState.Active;
|
||||
}
|
||||
|
||||
character.AddDamage(CauseOfDeath.Damage, 0.5f*deltaTime, null);
|
||||
|
||||
if (character.AnimController.limbJoints[0].LimitEnabled &&
|
||||
(character.AnimController.CurrentHull == null ||
|
||||
character.AnimController.CurrentHull.LethalPressure > 50.0f))
|
||||
{
|
||||
character.BreakJoints();
|
||||
character.AnimController.limbJoints.Last().LimitEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ActivateHusk(Character character)
|
||||
{
|
||||
character.NeedsAir = false;
|
||||
AttachHuskAppendage(character);
|
||||
}
|
||||
|
||||
private void AttachHuskAppendage(Character character)
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(Path.Combine("Content", "Characters", "Human", "huskappendage.xml"));
|
||||
if (doc == null || doc.Root == null) return;
|
||||
|
||||
var limbElement = doc.Root.Element("limb");
|
||||
if (limbElement == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in huskappendage.xml - limb element not found");
|
||||
return;
|
||||
}
|
||||
|
||||
var jointElement = doc.Root.Element("joint");
|
||||
if (jointElement == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in huskappendage.xml - joint element not found");
|
||||
return;
|
||||
}
|
||||
|
||||
character.StartStun(0.5f);
|
||||
if (character.AnimController.Dir < 1.0f)
|
||||
{
|
||||
character.AnimController.Flip();
|
||||
}
|
||||
|
||||
var torso = character.AnimController.GetLimb(LimbType.Torso);
|
||||
torso.body.SetTransform(torso.SimPosition, 0.0f);
|
||||
|
||||
var newLimb = new Limb(character, limbElement);
|
||||
newLimb.body.Submarine = character.Submarine;
|
||||
newLimb.body.SetTransform(torso.SimPosition, 0.0f);
|
||||
|
||||
character.AnimController.AddLimb(newLimb);
|
||||
character.AnimController.AddJoint(jointElement);
|
||||
}
|
||||
|
||||
private void CharacterDead(Character character, CauseOfDeath causeOfDeath)
|
||||
{
|
||||
var husk = Character.Create(
|
||||
Path.Combine("Content", "Characters", "Human", "humanhusk.xml"),
|
||||
character.WorldPosition,
|
||||
character.Info,
|
||||
false, true);
|
||||
|
||||
foreach (Limb limb in husk.AnimController.Limbs)
|
||||
{
|
||||
if (limb.type == LimbType.None)
|
||||
{
|
||||
limb.body.SetTransform(character.SimPosition, 0.0f);
|
||||
continue;
|
||||
}
|
||||
|
||||
var matchingLimb = character.AnimController.GetLimb(limb.type);
|
||||
limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation);
|
||||
}
|
||||
|
||||
for (int i = 0; i < character.Inventory.Items.Length; i++)
|
||||
{
|
||||
if (character.Inventory.Items[i] == null) continue;
|
||||
husk.Inventory.TryPutItem(character.Inventory.Items[i], i, false, true);
|
||||
}
|
||||
|
||||
character.Enabled = false;
|
||||
|
||||
husk.SpawnedMidRound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user