diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 633791f28..bb1f7e392 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -93,6 +93,7 @@
+
@@ -391,6 +392,14 @@
PreserveNewest
+
+ Designer
+ PreserveNewest
+
+
+ Designer
+ PreserveNewest
+
PreserveNewest
@@ -482,6 +491,7 @@
PreserveNewest
+ Designer
PreserveNewest
diff --git a/Subsurface/Content/Characters/Human/humanhusk.xml b/Subsurface/Content/Characters/Human/humanhusk.xml
new file mode 100644
index 000000000..6e8779705
--- /dev/null
+++ b/Subsurface/Content/Characters/Human/humanhusk.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Subsurface/Content/Characters/Human/huskappendage.xml b/Subsurface/Content/Characters/Human/huskappendage.xml
new file mode 100644
index 000000000..4a8a23841
--- /dev/null
+++ b/Subsurface/Content/Characters/Human/huskappendage.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Subsurface/Content/Characters/Husk/DivingSuit.png b/Subsurface/Content/Characters/Husk/DivingSuit.png
index f95c2e62e..076b6f7e8 100644
Binary files a/Subsurface/Content/Characters/Husk/DivingSuit.png and b/Subsurface/Content/Characters/Husk/DivingSuit.png differ
diff --git a/Subsurface/Content/Characters/Husk/husk.xml b/Subsurface/Content/Characters/Husk/husk.xml
index 043704787..e3cbf0e71 100644
--- a/Subsurface/Content/Characters/Husk/husk.xml
+++ b/Subsurface/Content/Characters/Husk/husk.xml
@@ -23,7 +23,7 @@
-
+
diff --git a/Subsurface/Content/InfoTexts.xml b/Subsurface/Content/InfoTexts.xml
index 9e8e83c1a..f854b81e5 100644
--- a/Subsurface/Content/InfoTexts.xml
+++ b/Subsurface/Content/InfoTexts.xml
@@ -21,4 +21,15 @@
You have burned to death.
You have been disconnected from the server.
+ Your throat feels sore
+ Your feel feverish
+ It feels as if something was stuck in your throat
+ Your muscles are aching
+
+ You feel something moving in your throat. You try to scream but no sound comes out.
+
+
+ A strange chitinous appendage bursts out from your mouth. Use it to inject eggs into a living body by pressing [Attack]!
+
+
\ No newline at end of file
diff --git a/Subsurface/Source/Characters/AI/AIController.cs b/Subsurface/Source/Characters/AI/AIController.cs
index 8e6cfd932..165579fff 100644
--- a/Subsurface/Source/Characters/AI/AIController.cs
+++ b/Subsurface/Source/Characters/AI/AIController.cs
@@ -10,6 +10,8 @@ namespace Barotrauma
public enum AiState { None, Attack, GoTo, Escape }
public enum SteeringState { Wander, Seek, Escape }
+ public bool Enabled;
+
public readonly Character Character;
protected AiState state;
@@ -51,6 +53,8 @@ namespace Barotrauma
public AIController (Character c)
{
Character = c;
+
+ Enabled = true;
}
public virtual void DebugDraw(SpriteBatch spriteBatch) { }
diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs
index 4e9ecb0bb..1997289d1 100644
--- a/Subsurface/Source/Characters/AICharacter.cs
+++ b/Subsurface/Source/Characters/AICharacter.cs
@@ -49,7 +49,7 @@ namespace Barotrauma
if (isDead || health <= 0.0f) return;
- if (Controlled == this) return;
+ if (Controlled == this || !aiController.Enabled) return;
if (soundTimer > 0)
{
@@ -117,6 +117,12 @@ namespace Barotrauma
aiController.FillNetworkData(message);
return true;
case NetworkEventType.EntityUpdate:
+ message.Write(Controlled == this);
+
+ if (Controlled == this)
+ {
+ return base.FillNetworkData(type, message, data);
+ }
message.Write(AnimController.Dir > 0.0f);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -1.0f, 1.0f), -1.0f, 1.0f, 4);
@@ -215,6 +221,15 @@ namespace Barotrauma
case NetworkEventType.EntityUpdate:
if (sendingTime <= LastNetworkUpdate) return false;
+ bool playerControlled = message.ReadBoolean();
+ if (playerControlled)
+ {
+ aiController.Enabled = false;
+ return base.ReadNetworkData(type, message, sendingTime, out data);
+ }
+
+ aiController.Enabled = true;
+
Vector2 targetMovement = Vector2.Zero, pos = Vector2.Zero;
bool targetDir = false,inSub = false;
diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs
index 938838203..9420c33de 100644
--- a/Subsurface/Source/Characters/Animation/Ragdoll.cs
+++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs
@@ -30,8 +30,8 @@ namespace Barotrauma
protected float strongestImpact;
- float headPosition, headAngle;
- float torsoPosition, torsoAngle;
+ public float headPosition, headAngle;
+ public float torsoPosition, torsoAngle;
protected double onFloorTimer;
@@ -231,8 +231,7 @@ namespace Barotrauma
byte ID = Convert.ToByte(subElement.Attribute("id").Value);
Limb limb = new Limb(character, subElement, scale);
-
-
+
limb.body.FarseerBody.OnCollision += OnLimbCollision;
Limbs[ID] = limb;
@@ -240,38 +239,7 @@ namespace Barotrauma
if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb);
break;
case "joint":
- Byte limb1ID = Convert.ToByte(subElement.Attribute("limb1").Value);
- Byte limb2ID = Convert.ToByte(subElement.Attribute("limb2").Value);
-
- Vector2 limb1Pos = ToolBox.GetAttributeVector2(subElement, "limb1anchor", Vector2.Zero) * scale;
- limb1Pos = ConvertUnits.ToSimUnits(limb1Pos);
-
- Vector2 limb2Pos = ToolBox.GetAttributeVector2(subElement, "limb2anchor", Vector2.Zero) * scale;
- limb2Pos = ConvertUnits.ToSimUnits(limb2Pos);
-
- RevoluteJoint joint = new RevoluteJoint(Limbs[limb1ID].body.FarseerBody, Limbs[limb2ID].body.FarseerBody, limb1Pos, limb2Pos);
-
- joint.CollideConnected = false;
-
- if (subElement.Attribute("lowerlimit")!=null)
- {
- joint.LimitEnabled = true;
- joint.LowerLimit = float.Parse(subElement.Attribute("lowerlimit").Value) * ((float)Math.PI / 180.0f);
- joint.UpperLimit = float.Parse(subElement.Attribute("upperlimit").Value) * ((float)Math.PI / 180.0f);
- }
-
- joint.MotorEnabled = true;
- joint.MaxMotorTorque = 0.25f;
-
- GameMain.World.AddJoint(joint);
-
- for (int i = 0; i < limbJoints.Length; i++ )
- {
- if (limbJoints[i] != null) continue;
-
- limbJoints[i] = joint;
- break;
- }
+ AddJoint(subElement, scale);
break;
}
@@ -308,6 +276,58 @@ namespace Barotrauma
FindLowestLimb();
}
+
+ public void AddJoint(XElement subElement, float scale = 1.0f)
+ {
+ byte limb1ID = Convert.ToByte(subElement.Attribute("limb1").Value);
+ byte limb2ID = Convert.ToByte(subElement.Attribute("limb2").Value);
+
+ Vector2 limb1Pos = ToolBox.GetAttributeVector2(subElement, "limb1anchor", Vector2.Zero) * scale;
+ limb1Pos = ConvertUnits.ToSimUnits(limb1Pos);
+
+ Vector2 limb2Pos = ToolBox.GetAttributeVector2(subElement, "limb2anchor", Vector2.Zero) * scale;
+ limb2Pos = ConvertUnits.ToSimUnits(limb2Pos);
+
+ RevoluteJoint joint = new RevoluteJoint(Limbs[limb1ID].body.FarseerBody, Limbs[limb2ID].body.FarseerBody, limb1Pos, limb2Pos);
+
+ joint.CollideConnected = false;
+
+ if (subElement.Attribute("lowerlimit") != null)
+ {
+ joint.LimitEnabled = true;
+ joint.LowerLimit = float.Parse(subElement.Attribute("lowerlimit").Value) * ((float)Math.PI / 180.0f);
+ joint.UpperLimit = float.Parse(subElement.Attribute("upperlimit").Value) * ((float)Math.PI / 180.0f);
+ }
+
+ joint.MotorEnabled = true;
+ joint.MaxMotorTorque = 0.25f;
+
+ GameMain.World.AddJoint(joint);
+
+ for (int i = 0; i < limbJoints.Length; i++)
+ {
+ if (limbJoints[i] != null) continue;
+
+ limbJoints[i] = joint;
+ return;
+ }
+
+ Array.Resize(ref limbJoints, limbJoints.Length + 1);
+ limbJoints[limbJoints.Length - 1] = joint;
+
+ }
+
+ public void AddLimb(Limb limb)
+ {
+ limb.body.FarseerBody.OnCollision += OnLimbCollision;
+
+ Array.Resize(ref Limbs, Limbs.Length + 1);
+
+ Limbs[Limbs.Length-1] = limb;
+
+ Mass += limb.Mass;
+ if (!limbDictionary.ContainsKey(limb.type)) limbDictionary.Add(limb.type, limb);
+ }
public bool OnLimbCollision(Fixture f1, Fixture f2, Contact contact)
{
diff --git a/Subsurface/Source/Characters/Attack.cs b/Subsurface/Source/Characters/Attack.cs
index df02b6d1e..226c91c8e 100644
--- a/Subsurface/Source/Characters/Attack.cs
+++ b/Subsurface/Source/Characters/Attack.cs
@@ -136,22 +136,24 @@ namespace Barotrauma
{
sound.Play(1.0f, 500.0f, worldPosition);
}
+
+ var attackResult = target.AddDamage(attacker, worldPosition, this, deltaTime, playSound);
+
+ var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure;
foreach (StatusEffect effect in statusEffects)
{
if (effect.Targets.HasFlag(StatusEffect.TargetType.This) && attacker is Character)
{
- effect.Apply(ActionType.OnUse, deltaTime, (Character)attacker, (Character)attacker);
+ effect.Apply(effectType, deltaTime, (Character)attacker, (Character)attacker);
}
if (effect.Targets.HasFlag(StatusEffect.TargetType.Character) && target is Character)
{
- effect.Apply(ActionType.OnUse, deltaTime, (Character)target, (Character)target);
- }
+ effect.Apply(effectType, deltaTime, (Character)target, (Character)target);
+ }
}
-
-
- return target.AddDamage(attacker, worldPosition, this, deltaTime, playSound);
+ return attackResult;
}
}
}
diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs
index fc748ec24..3cffae273 100644
--- a/Subsurface/Source/Characters/Character.cs
+++ b/Subsurface/Source/Characters/Character.cs
@@ -112,6 +112,8 @@ namespace Barotrauma
//which AIstate each sound is for
private AIController.AiState[] soundStates;
+ private float attackCoolDown;
+
public Entity ViewTarget
{
get;
@@ -248,6 +250,7 @@ namespace Barotrauma
public bool NeedsAir
{
get { return needsAir; }
+ set { needsAir = value; }
}
public float Oxygen
@@ -298,6 +301,38 @@ namespace Barotrauma
}
}
+ public HuskInfection huskInfection;
+ public float HuskInfectionState
+ {
+ get
+ {
+ return huskInfection == null ? 0.0f : huskInfection.IncubationTimer;
+ }
+ set
+ {
+ if (ConfigPath != humanConfigFile) return;
+
+ if (value <= 0.0f)
+ {
+ if (huskInfection != null && huskInfection.State == HuskInfection.InfectionState.Active) return;
+ huskInfection = null;
+ }
+ else
+ {
+ if (huskInfection == null) huskInfection = new HuskInfection(this);
+ huskInfection.IncubationTimer = MathHelper.Clamp(value, 0.0f, 1.0f);
+ }
+ }
+ }
+
+ public bool CanSpeak
+ {
+ get
+ {
+ return !IsUnconscious && Stun <= 0.0f && (huskInfection == null || huskInfection.CanSpeak);
+ }
+ }
+
public bool DoesBleed
{
get;
@@ -310,7 +345,6 @@ namespace Barotrauma
private set;
}
-
public float PressureTimer
{
get;
@@ -474,13 +508,17 @@ namespace Barotrauma
Properties = ObjectProperty.GetProperties(this);
- if (file == humanConfigFile)
+ if (file == humanConfigFile && characterInfo == null)
{
- Info = characterInfo == null ? new CharacterInfo(file) : characterInfo;
+ Info = new CharacterInfo(file);
}
+ Info = characterInfo;
+
XDocument doc = ToolBox.TryLoadXml(file);
if (doc == null || doc.Root == null) return;
+
+
SpeciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown");
@@ -696,6 +734,49 @@ namespace Barotrauma
}
}
+ if (attackCoolDown >0.0f)
+ {
+ attackCoolDown -= deltaTime;
+ }
+ else if (IsKeyDown(InputType.Attack))
+ {
+ var attackLimb = AnimController.Limbs.FirstOrDefault(l => l.attack != null);
+
+ if (attackLimb != null)
+ {
+ Vector2 attackPos =
+ attackLimb.SimPosition + Vector2.Normalize(cursorPosition - attackLimb.Position) * ConvertUnits.ToSimUnits(attackLimb.attack.Range);
+
+ var body = Submarine.PickBody(
+ attackLimb.SimPosition,
+ attackPos,
+ AnimController.Limbs.Select(l => l.body.FarseerBody).ToList(),
+ Physics.CollisionCharacter | Physics.CollisionWall);
+
+ IDamageable attackTarget = null;
+ if (body != null)
+ {
+ if (body.UserData is IDamageable)
+ {
+ attackTarget = (IDamageable)body.UserData;
+ }
+ else if (body.UserData is Limb)
+ {
+ attackTarget = ((Limb)body.UserData).character;
+ }
+ attackPos = Submarine.LastPickedPosition;
+ }
+
+ attackLimb.UpdateAttack(deltaTime, attackPos, attackTarget);
+
+ if (attackLimb.AttackTimer > attackLimb.attack.Duration)
+ {
+ attackLimb.AttackTimer = 0.0f;
+ attackCoolDown = 1.0f;
+ }
+ }
+ }
+
for (int i = 0; i < selectedItems.Length; i++ )
{
if (selectedItems[i] == null) continue;
@@ -859,7 +940,7 @@ namespace Barotrauma
foreach (Limb limb in selectedCharacter.AnimController.Limbs)
{
- limb.pullJoint.Enabled = false;
+ if (limb.pullJoint != null) limb.pullJoint.Enabled = false;
}
selectedCharacter = null;
@@ -923,7 +1004,6 @@ namespace Barotrauma
}
}
-
if (!LockHands)
{
//find the closest item if selectkey has been hit, or if the Character is being
@@ -1014,9 +1094,9 @@ namespace Barotrauma
// new Character(NewCharacterQueue.Dequeue(), Vector2.Zero);
//}
- foreach (Character c in CharacterList)
+ for (int i = 0; i 0.0f)
- //{
- // message.Write(Math.Max((byte)((health / maxHealth) * 255.0f), (byte)1));
- //}
- //else
- //{
- // message.Write((byte)0);
- // message.WriteRangedInteger(0, Enum.GetValues(typeof(CauseOfDeath)).Length-1, (int)lastAttackCauseOfDeath);
- //}
-
if (AnimController.StunTimer <= 0.0f && bleeding <= 0.0f && oxygen > 99.0f)
{
message.Write(true);
@@ -1519,6 +1603,12 @@ namespace Barotrauma
bleeding = MathHelper.Clamp(bleeding, 0.0f, 5.0f);
message.WriteRangedSingle(bleeding, 0.0f, 5.0f, 8);
+
+ message.Write(huskInfection != null);
+ if (huskInfection!=null)
+ {
+ message.WriteRangedSingle(HuskInfectionState, 0.0f, 1.0f, 4);
+ }
}
return true;
@@ -1536,8 +1626,15 @@ namespace Barotrauma
message.Write(keys[(int)InputType.Run].Held);
- message.Write(((HumanoidAnimController)AnimController).Crouching);
+ if (AnimController.Limbs.Any(l => l.attack != null))
+ {
+ message.Write(keys[(int)InputType.Attack].Held);
+ }
+ if (AnimController is HumanoidAnimController)
+ {
+ message.Write(((HumanoidAnimController)AnimController).Crouching);
+ }
if (secondaryHeld)
{
@@ -1587,7 +1684,6 @@ namespace Barotrauma
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
- Enabled = true;
data = null;
if (GameMain.Server != null && type != NetworkEventType.InventoryUpdate)
@@ -1729,13 +1825,20 @@ namespace Barotrauma
Oxygen = message.ReadRangedSingle(-100.0f,100.0f, 8);
Bleeding = message.ReadRangedSingle(0.0f, 5.0f, 8);
+ if (message.ReadBoolean())
+ {
+ HuskInfectionState = message.ReadRangedSingle(0.0f, 1.0f, 4);
+ }
+
break;
case NetworkEventType.EntityUpdate:
+ Enabled = true;
+
Vector2 relativeCursorPos = Vector2.Zero;
bool actionKeyState, secondaryKeyState;
bool leftKeyState, rightKeyState, upKeyState, downKeyState;
- bool runState, crouchState;
+ bool runState, crouchState = false, attackState = false;
try
{
@@ -1750,7 +1853,16 @@ namespace Barotrauma
downKeyState = message.ReadBoolean();
runState = message.ReadBoolean();
- crouchState = message.ReadBoolean();
+
+ if (AnimController.Limbs.Any(l => l.attack != null))
+ {
+ attackState = message.ReadBoolean();
+ }
+
+ if (AnimController is HumanoidAnimController)
+ {
+ crouchState = message.ReadBoolean();
+ }
}
catch (Exception e)
@@ -1769,6 +1881,9 @@ namespace Barotrauma
keys[(int)InputType.Aim].Held = secondaryKeyState;
keys[(int)InputType.Aim].SetState(false, secondaryKeyState);
+ keys[(int)InputType.Attack].Held = attackState;
+ keys[(int)InputType.Attack].SetState(false, attackState);
+
if (sendingTime <= LastNetworkUpdate) return false;
keys[(int)InputType.Left].Held = leftKeyState;
diff --git a/Subsurface/Source/Characters/CharacterHUD.cs b/Subsurface/Source/Characters/CharacterHUD.cs
index b4ae4ed91..2f8eb43c2 100644
--- a/Subsurface/Source/Characters/CharacterHUD.cs
+++ b/Subsurface/Source/Characters/CharacterHUD.cs
@@ -197,6 +197,7 @@ namespace Barotrauma
if (Character.Controlled != null)
{
Character.Controlled.Kill(Character.Controlled.CauseOfDeath);
+ Character.Controlled = null;
}
return true;
};
diff --git a/Subsurface/Source/Characters/HuskInfection.cs b/Subsurface/Source/Characters/HuskInfection.cs
new file mode 100644
index 000000000..b370efaad
--- /dev/null
+++ b/Subsurface/Source/Characters/HuskInfection.cs
@@ -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;
+ }
+ }
+}
diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs
index 4ebd2a76e..242846285 100644
--- a/Subsurface/Source/Characters/Limb.cs
+++ b/Subsurface/Source/Characters/Limb.cs
@@ -499,12 +499,10 @@ namespace Barotrauma
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition));
AttackTimer += deltaTime;
+ body.ApplyTorque(Mass * character.AnimController.Dir * attack.Torque);
if (dist < attack.Range * 0.5f)
{
- AttackTimer += deltaTime;
- body.ApplyTorque(Mass * character.AnimController.Dir * attack.Torque);
-
if (AttackTimer >= attack.Duration && damageTarget != null)
{
attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, (soundTimer <= 0.0f));
@@ -520,7 +518,6 @@ namespace Barotrauma
body.ApplyLinearImpulse(Mass * attack.Force *
Vector2.Normalize(attackPosition - SimPosition), pos);
}
-
}
public void Draw(SpriteBatch spriteBatch)
diff --git a/Subsurface/Source/GameSession/InfoTextManager.cs b/Subsurface/Source/GameSession/InfoTextManager.cs
index 78bca7b25..cd3a1167c 100644
--- a/Subsurface/Source/GameSession/InfoTextManager.cs
+++ b/Subsurface/Source/GameSession/InfoTextManager.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
@@ -51,6 +52,11 @@ namespace Barotrauma
string text = infoList[Rand.Int(infoList.Count)];
+ foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
+ {
+ text = text.Replace("[" + inputType.ToString() + "]", GameMain.Config.KeyBind(inputType).ToString());
+ }
+
if (Submarine.MainSub != null) text = text.Replace("[sub]", Submarine.MainSub.Name);
if (GameMain.GameSession != null && GameMain.GameSession.Map != null)
{
diff --git a/Subsurface/Source/GameSettings.cs b/Subsurface/Source/GameSettings.cs
index b965a7e8e..0316a206d 100644
--- a/Subsurface/Source/GameSettings.cs
+++ b/Subsurface/Source/GameSettings.cs
@@ -383,6 +383,12 @@ namespace Barotrauma
{
new GUITextBlock(new Rectangle(x, y, 100, 20), inputNames[i]+": ", GUI.Style, settingsFrame);
var keyBox = new GUITextBox(new Rectangle(x + 100, y, 120, 15), GUI.Style, settingsFrame);
+
+ if (keyMapping[i]==null)
+ {
+ keyMapping[i] = new KeyOrMouse(Keys.D1);
+ }
+
keyBox.Text = keyMapping[i].ToString();
keyBox.UserData = i;
keyBox.OnSelected += KeyBoxSelected;
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index 873cf8d62..fc705291f 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -1623,7 +1623,7 @@ namespace Barotrauma.Networking
public void SendCharacterSpawnMessage(Character character, List recipients = null)
{
- if (recipients == null || !recipients.Any()) return;
+ if (recipients != null && !recipients.Any()) return;
NetOutgoingMessage message = server.CreateMessage();
message.Write((byte)PacketTypes.NewCharacter);
diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs
index 9b6ac1dad..55cb4ff48 100644
--- a/Subsurface/Source/Networking/NetworkMember.cs
+++ b/Subsurface/Source/Networking/NetworkMember.cs
@@ -340,15 +340,12 @@ namespace Barotrauma.Networking
{
if (gameStarted && Screen.Selected == GameMain.GameScreen)
{
- chatMsgBox.Visible = Character.Controlled == null ||
- (!Character.Controlled.IsUnconscious && Character.Controlled.Stun <= 0.0f);
+ chatMsgBox.Visible = Character.Controlled == null || Character.Controlled.CanSpeak;
inGameHUD.Update(deltaTime);
GameMain.GameSession.CrewManager.Update(deltaTime);
-
- //if (crewFrameOpen) crewFrame.Update(deltaTime);
-
+
if (Character.Controlled == null || Character.Controlled.IsDead)
{
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
diff --git a/Subsurface/Source/PlayerInput.cs b/Subsurface/Source/PlayerInput.cs
index 8ce5e59c0..99d54c936 100644
--- a/Subsurface/Source/PlayerInput.cs
+++ b/Subsurface/Source/PlayerInput.cs
@@ -10,6 +10,7 @@ namespace Barotrauma
Use,
Aim,
Up, Down, Left, Right,
+ Attack,
Run, Crouch,
Chat, CrewOrders
}