7dbfbfd4eb
commit cd504791ebda32f7e9d79ec2ac726058e83b5bf1 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 20:03:46 2019 +0200 Additional server logging for steam auth & desync kicks commit 6efece5e42502c1cdba89d4f4cc91398402f2b25 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 19:46:51 2019 +0200 Fixed server failing to sync clients who join the server after a character has been removed during the round (e.g. eaten, turned into a husk). commit 482c9f87ec715119ad9ad420f25003ac92e666b9 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 19:37:00 2019 +0200 Fixed server-side error messages when clients attempt to use a fabricator. Happened because the server tried to set the required time -text on the fabricator interface based on the controlled character instead of the character using the fabricator. commit 0a21304ee43935364de131d8aba09da8f51e6a47 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 17:30:39 2019 +0200 Fixed AI crew occasionally going outside to fix leaks commit 78fa9382490f3b8d63c2ced9b31551fddf937703 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 16:47:09 2019 +0200 Changed coilgun ammo box category from Machine to Equipment (no machine tab in the store menu, caused errors when trying to find a tab button style) commit 73f4374938a69bbeb9e5c0177bcd2b632fc33c8f Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 16:14:56 2019 +0200 Fixed humanhusk not spawning when a husk-infected human dies. commit 080b04d6d046a3c7659942a0a72a3f1a0aa33f4d Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 15:57:18 2019 +0200 Made coilgun ammo boxes fabricable and purchaseable, coilgun bolts can't be crafted, alien flares can't be purchased. Closes #1027 commit edd46655a853880e03c2f9a32abd92b6429a6c8e Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 15:48:39 2019 +0200 Removed auxiliorizine from the chemical shipment mission (auxiliorizine doesn't exist anymore). commit c19620e1f507b2bda398ab4b8ab8cd7d3ea5af23 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Feb 3 15:46:26 2019 +0200 Removed duplicate line from loading screen tips. Closes #1032 commit e7df25130bfc76c16a08e86d3d42b16eab7cb21d Author: ezjamsen <ezjames.fi@gmail.com> Date: Sun Feb 3 13:01:19 2019 +0200 Halved moloch speeds temporarily until a full balance of enemies is done.
259 lines
9.2 KiB
C#
259 lines
9.2 KiB
C#
#if CLIENT
|
|
using Microsoft.Xna.Framework;
|
|
#endif
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml.Linq;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
partial class AfflictionHusk : Affliction
|
|
{
|
|
public enum InfectionState
|
|
{
|
|
Dormant, Transition, Active
|
|
}
|
|
|
|
private bool subscribedToDeathEvent;
|
|
|
|
private InfectionState state;
|
|
|
|
private Limb huskAppendage;
|
|
|
|
public InfectionState State
|
|
{
|
|
get { return state; }
|
|
}
|
|
|
|
public AfflictionHusk(AfflictionPrefab prefab, float strength) :
|
|
base(prefab, strength)
|
|
{
|
|
}
|
|
|
|
public override void Update(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
|
|
{
|
|
float prevStrength = Strength;
|
|
base.Update(characterHealth, targetLimb, deltaTime);
|
|
|
|
if (!subscribedToDeathEvent)
|
|
{
|
|
characterHealth.Character.OnDeath += CharacterDead;
|
|
subscribedToDeathEvent = true;
|
|
}
|
|
|
|
if (characterHealth.Character == Character.Controlled) UpdateMessages(prevStrength, characterHealth.Character);
|
|
if (Strength < Prefab.MaxStrength * 0.5f)
|
|
{
|
|
UpdateDormantState(deltaTime, characterHealth.Character);
|
|
}
|
|
else if (Strength < Prefab.MaxStrength)
|
|
{
|
|
characterHealth.Character.SpeechImpediment = 100.0f;
|
|
UpdateTransitionState(deltaTime, characterHealth.Character);
|
|
}
|
|
else
|
|
{
|
|
characterHealth.Character.SpeechImpediment = 100.0f;
|
|
UpdateActiveState(deltaTime, characterHealth.Character);
|
|
}
|
|
}
|
|
|
|
private void UpdateMessages(float prevStrength, Character character)
|
|
{
|
|
#if CLIENT
|
|
if (Strength < Prefab.MaxStrength * 0.5f)
|
|
{
|
|
if (prevStrength % 10.0f > 0.05f && Strength % 10.0f < 0.05f)
|
|
{
|
|
GUI.AddMessage(TextManager.Get("HuskDormant"), Color.Red);
|
|
}
|
|
}
|
|
else if (Strength < Prefab.MaxStrength)
|
|
{
|
|
if (state == InfectionState.Dormant && Character.Controlled == character)
|
|
{
|
|
GUI.AddMessage(TextManager.Get("HuskCantSpeak"), Color.Red);
|
|
}
|
|
}
|
|
else if (state != InfectionState.Active && Character.Controlled == character)
|
|
{
|
|
GUI.AddMessage(TextManager.Get("HuskActivate").Replace("[Attack]", GameMain.Config.KeyBind(InputType.Attack).ToString()),
|
|
Color.Red);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private void UpdateDormantState(float deltaTime, Character character)
|
|
{
|
|
if (state != InfectionState.Dormant)
|
|
{
|
|
DeactivateHusk(character);
|
|
}
|
|
|
|
state = InfectionState.Dormant;
|
|
}
|
|
|
|
private void UpdateTransitionState(float deltaTime, Character character)
|
|
{
|
|
if (state != InfectionState.Transition)
|
|
{
|
|
DeactivateHusk(character);
|
|
}
|
|
|
|
state = InfectionState.Transition;
|
|
}
|
|
|
|
private void UpdateActiveState(float deltaTime, Character character)
|
|
{
|
|
if (state != InfectionState.Active)
|
|
{
|
|
ActivateHusk(character);
|
|
state = InfectionState.Active;
|
|
}
|
|
|
|
foreach (Limb limb in character.AnimController.Limbs)
|
|
{
|
|
character.LastDamageSource = null;
|
|
character.DamageLimb(
|
|
limb.WorldPosition, limb,
|
|
new List<Affliction>() { AfflictionPrefab.InternalDamage.Instantiate(0.5f * deltaTime / character.AnimController.Limbs.Length) },
|
|
0.0f, false, 0.0f);
|
|
}
|
|
}
|
|
|
|
private void ActivateHusk(Character character)
|
|
{
|
|
character.NeedsAir = false;
|
|
AttachHuskAppendage(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"));
|
|
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.SetStun(0.5f);
|
|
if (character.AnimController.Dir < 1.0f)
|
|
{
|
|
character.AnimController.Flip();
|
|
}
|
|
|
|
var torso = character.AnimController.GetLimb(LimbType.Torso);
|
|
|
|
huskAppendage = new Limb(character.AnimController, character, new LimbParams(limbElement, character.AnimController.RagdollParams));
|
|
huskAppendage.body.Submarine = character.Submarine;
|
|
huskAppendage.body.SetTransform(torso.SimPosition, torso.Rotation);
|
|
|
|
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)
|
|
{
|
|
DeactivateHusk(character);
|
|
if (character != null) character.OnDeath -= CharacterDead;
|
|
subscribedToDeathEvent = false;
|
|
}
|
|
|
|
private void CharacterDead(Character character, CauseOfDeath causeOfDeath)
|
|
{
|
|
if (GameMain.Client != null) { return; }
|
|
if (Strength < Prefab.MaxStrength * 0.5f || character.Removed) { return; }
|
|
|
|
//don't turn the character into a husk if any of its limbs are severed
|
|
if (character.AnimController?.LimbJoints != null)
|
|
{
|
|
foreach (var limbJoint in character.AnimController.LimbJoints)
|
|
{
|
|
if (limbJoint.IsSevered) return;
|
|
}
|
|
}
|
|
|
|
//create the AI husk in a coroutine to ensure that we don't modify the character list while enumerating it
|
|
CoroutineManager.StartCoroutine(CreateAIHusk(character));
|
|
}
|
|
|
|
private IEnumerable<object> CreateAIHusk(Character character)
|
|
{
|
|
character.Enabled = false;
|
|
Entity.Spawner.AddToRemoveQueue(character);
|
|
|
|
var characterFiles = GameMain.Instance.GetFilesOfType(ContentType.Character);
|
|
var configFile = characterFiles.FirstOrDefault(f => Path.GetFileNameWithoutExtension(f)?.ToLowerInvariant() == "humanhusk");
|
|
|
|
if (string.IsNullOrEmpty(configFile))
|
|
{
|
|
DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - humanhusk config file not found.");
|
|
yield return CoroutineStatus.Success;
|
|
}
|
|
|
|
XDocument doc = XMLExtensions.TryLoadXml(configFile);
|
|
if (doc?.Root == null)
|
|
{
|
|
DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - humanhusk config file ("+configFile+") could not be read.");
|
|
yield return CoroutineStatus.Success;
|
|
}
|
|
|
|
character.Info.Ragdoll = null;
|
|
character.Info.SourceElement = doc.Root;
|
|
var husk = Character.Create(configFile, character.WorldPosition, character.Info.Name, 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);
|
|
if (matchingLimb?.body != null)
|
|
{
|
|
limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation);
|
|
limb.body.LinearVelocity = matchingLimb.LinearVelocity;
|
|
limb.body.AngularVelocity = matchingLimb.body.AngularVelocity;
|
|
}
|
|
}
|
|
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, true, false, null);
|
|
}
|
|
|
|
yield return CoroutineStatus.Success;
|
|
}
|
|
}
|
|
}
|