Remove items in dummycharacter inventory in editmapscreen, important character updates a separate networkeventtype

This commit is contained in:
Regalis
2015-10-23 19:28:21 +03:00
parent b3462b24b4
commit 6736f1dd82
17 changed files with 545 additions and 475 deletions
+2 -2
View File
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.3.0")] [assembly: AssemblyVersion("0.2.3.1")]
[assembly: AssemblyFileVersion("0.2.3.0")] [assembly: AssemblyFileVersion("0.2.3.1")]
+99 -130
View File
@@ -85,50 +85,43 @@ namespace Barotrauma
public override bool FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data) public override bool FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data)
{ {
if (type == NetworkEventType.KillCharacter) switch (type)
{ {
return true; case NetworkEventType.KillCharacter:
return true;
case NetworkEventType.ImportantEntityUpdate:
int i = 0;
foreach (Limb limb in AnimController.Limbs)
{
if (limb.ignoreCollisions) continue;
message.Write(limb.body.SimPosition.X);
message.Write(limb.body.SimPosition.Y);
message.Write(limb.body.Rotation);
i++;
}
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8);
message.Write((byte)((health / maxHealth) * 255.0f));
aiController.FillNetworkData(message);
return true;
case NetworkEventType.EntityUpdate:
message.Write((float)NetTime.Now);
message.Write(AnimController.TargetDir == Direction.Right);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 16);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 16);
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
message.Write(AnimController.RefLimb.LinearVelocity.X);
message.Write(AnimController.RefLimb.LinearVelocity.Y);
return true;
} }
message.Write((float)NetTime.Now);
message.Write(LargeUpdateTimer <= 0);
message.Write(AnimController.TargetDir == Direction.Right);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 16);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 16);
if (LargeUpdateTimer <= 0)
{
int i = 0;
foreach (Limb limb in AnimController.Limbs)
{
message.Write(limb.body.SimPosition.X);
message.Write(limb.body.SimPosition.Y);
message.Write(limb.body.Rotation);
i++;
}
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8);
message.Write((byte)((health / maxHealth) * 255.0f));
aiController.FillNetworkData(message);
LargeUpdateTimer = 50;
}
else
{
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
message.Write(AnimController.RefLimb.LinearVelocity.X);
message.Write(AnimController.RefLimb.LinearVelocity.Y);
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer - 1);
}
return true; return true;
} }
@@ -136,115 +129,91 @@ namespace Barotrauma
{ {
Enabled = true; Enabled = true;
if (type == NetworkEventType.KillCharacter) switch (type)
{ {
Kill(true); case NetworkEventType.KillCharacter:
return; Kill(CauseOfDeath.Damage, true);
} return;
case NetworkEventType.ImportantEntityUpdate:
foreach (Limb limb in AnimController.Limbs)
{
if (limb.ignoreCollisions) continue;
float sendingTime = 0.0f; Vector2 limbPos = limb.SimPosition;
Vector2 targetMovement = Vector2.Zero; float rotation = limb.Rotation;
bool targetDir = false;
bool isLargeUpdate; try
{
limbPos.X = message.ReadFloat();
limbPos.Y = message.ReadFloat();
rotation = message.ReadFloat();
}
catch
{
return;
}
try if (limb.body != null)
{ {
sendingTime = message.ReadFloat(); limb.body.TargetVelocity = limb.body.LinearVelocity;
isLargeUpdate = message.ReadBoolean(); limb.body.TargetPosition = limbPos;// +vel * (float)(deltaTime / 60.0);
} limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
limb.body.TargetAngularVelocity = limb.body.AngularVelocity;
}
}
catch float newStunTimer = 0.0f, newHealth = 0.0f;
{
return;
}
if (sendingTime <= LastNetworkUpdate) return;
try
{
targetDir = message.ReadBoolean();
targetMovement.X = message.ReadRangedSingle(-10.0f, 10.0f, 16);
targetMovement.Y = message.ReadRangedSingle(-10.0f, 10.0f, 16);
}
catch
{
return;
}
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
AnimController.TargetMovement = targetMovement;
if (isLargeUpdate)
{
foreach (Limb limb in AnimController.Limbs)
{
Vector2 pos = Vector2.Zero, vel = Vector2.Zero;
float rotation = 0.0f;
try try
{ {
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
newHealth = (message.ReadByte() / 255.0f) * maxHealth;
}
catch { return; }
AnimController.StunTimer = newStunTimer;
health = newHealth;
aiController.ReadNetworkData(message);
return;
case NetworkEventType.EntityUpdate:
float sendingTime = 0.0f;
Vector2 targetMovement = Vector2.Zero;
bool targetDir = false;
sendingTime = message.ReadFloat();
if (sendingTime <= LastNetworkUpdate) return;
Vector2 pos = Vector2.Zero, vel = Vector2.Zero;
try
{
targetDir = message.ReadBoolean();
targetMovement.X = message.ReadRangedSingle(-10.0f, 10.0f, 16);
targetMovement.Y = message.ReadRangedSingle(-10.0f, 10.0f, 16);
pos.X = message.ReadFloat(); pos.X = message.ReadFloat();
pos.Y = message.ReadFloat(); pos.Y = message.ReadFloat();
rotation = message.ReadFloat(); vel.X = message.ReadFloat();
vel.Y = message.ReadFloat();
} }
catch catch (Exception e)
{ {
return; return;
} }
if (limb.body != null) AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
{ AnimController.TargetMovement = targetMovement;
limb.body.TargetVelocity = limb.body.LinearVelocity;
limb.body.TargetPosition = pos;// +vel * (float)(deltaTime / 60.0);
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
limb.body.TargetAngularVelocity = limb.body.AngularVelocity;
}
}
float newStunTimer = 0.0f, newHealth = 0.0f; AnimController.RefLimb.body.TargetPosition = pos;
AnimController.RefLimb.body.TargetVelocity = vel;
try LastNetworkUpdate = sendingTime;
{ return;
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
newHealth = (message.ReadByte() / 255.0f) * maxHealth;
}
catch { return; }
AnimController.StunTimer = newStunTimer;
Health = newHealth;
LargeUpdateTimer = 1;
aiController.ReadNetworkData(message);
} }
else
{
Vector2 pos = Vector2.Zero, vel = Vector2.Zero;
try
{
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
vel.X = message.ReadFloat();
vel.Y = message.ReadFloat();
}
catch { return; }
//error
AnimController.RefLimb.body.TargetPosition = pos;
AnimController.RefLimb.body.TargetVelocity = vel;
LargeUpdateTimer = 0;
}
LastNetworkUpdate = sendingTime;
} }
+4
View File
@@ -6,6 +6,10 @@ using System.Xml.Linq;
namespace Barotrauma namespace Barotrauma
{ {
enum CauseOfDeath
{
Damage, Bloodloss, Pressure, Suffocation, Drowning
}
public enum DamageType { None, Blunt, Slash } public enum DamageType { None, Blunt, Slash }
+345 -322
View File
@@ -18,6 +18,8 @@ namespace Barotrauma
class Character : Entity, IDamageable, IPropertyObject class Character : Entity, IDamageable, IPropertyObject
{ {
public static string[] DeathMsg = new string[Enum.GetNames(typeof(CauseOfDeath)).Length];
public static List<Character> CharacterList = new List<Character>(); public static List<Character> CharacterList = new List<Character>();
public static Queue<CharacterInfo> NewCharacterQueue = new Queue<CharacterInfo>(); public static Queue<CharacterInfo> NewCharacterQueue = new Queue<CharacterInfo>();
@@ -40,12 +42,13 @@ namespace Barotrauma
} }
public readonly bool IsNetworkPlayer; public readonly bool IsNetworkPlayer;
private int importantUpdateTimer;
private CharacterInventory inventory; private CharacterInventory inventory;
public float LastNetworkUpdate; public float LastNetworkUpdate;
public int LargeUpdateTimer; //public int LargeUpdateTimer;
public readonly Dictionary<string, ObjectProperty> Properties; public readonly Dictionary<string, ObjectProperty> Properties;
public Dictionary<string, ObjectProperty> ObjectProperties public Dictionary<string, ObjectProperty> ObjectProperties
@@ -173,7 +176,7 @@ namespace Barotrauma
set set
{ {
oxygen = MathHelper.Clamp(value, 0.0f, 100.0f); oxygen = MathHelper.Clamp(value, 0.0f, 100.0f);
if (oxygen == 0.0f) Kill(); if (oxygen == 0.0f) Kill(CauseOfDeath.Suffocation);
} }
} }
@@ -185,14 +188,11 @@ namespace Barotrauma
public float Health public float Health
{ {
get get { return health; }
{
return health;
}
set set
{ {
health = MathHelper.Clamp(value, 0.0f, maxHealth); health = MathHelper.Clamp(value, 0.0f, maxHealth);
if (health == 0.0f) Kill(); if (health <= 0.0f) Kill(CauseOfDeath.Damage);
} }
} }
@@ -222,47 +222,6 @@ namespace Barotrauma
get { return selectedItems; } get { return selectedItems; }
} }
public bool HasSelectedItem(Item item)
{
return selectedItems.Contains(item);
}
public bool TrySelectItem(Item item)
{
bool rightHand = ((CharacterInventory)inventory).IsInLimbSlot(item, LimbSlot.RightHand);
bool leftHand = ((CharacterInventory)inventory).IsInLimbSlot(item, LimbSlot.LeftHand);
bool selected = false;
if (rightHand && SelectedItems[0] == null)
{
selectedItems[0] = item;
selected = true;
}
if (leftHand && SelectedItems[1] == null)
{
selectedItems[1] = item;
selected = true;
}
return selected;
}
public bool TrySelectItem(Item item, int index)
{
if (selectedItems[index] != null) return false;
selectedItems[index] = item;
return true;
}
public void DeselectItem(Item item)
{
for (int i = 0; i < selectedItems.Length; i++)
{
if (selectedItems[i] == item) selectedItems[i] = null;
}
}
public Item SelectedConstruction public Item SelectedConstruction
{ {
get { return selectedConstruction; } get { return selectedConstruction; }
@@ -294,6 +253,15 @@ namespace Barotrauma
get { return ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition); } get { return ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition); }
} }
static Character()
{
DeathMsg[(int)CauseOfDeath.Damage] = "died";
DeathMsg[(int)CauseOfDeath.Bloodloss] = "bled out";
DeathMsg[(int)CauseOfDeath.Drowning] = "drowned";
DeathMsg[(int)CauseOfDeath.Suffocation] = "suffocated";
DeathMsg[(int)CauseOfDeath.Pressure] = "been crushed by water pressure";
}
public Character(string file) : this(file, Vector2.Zero, null) public Character(string file) : this(file, Vector2.Zero, null)
{ {
} }
@@ -559,7 +527,7 @@ namespace Barotrauma
if (selectedConstruction != null) if (selectedConstruction != null)
{ {
if (GetInputState(InputType.ActionHeld)) selectedConstruction.Use(deltaTime, this); if (GetInputState(InputType.ActionHeld)) selectedConstruction.Use(deltaTime, this);
if (GetInputState(InputType.SecondaryHeld)) selectedConstruction.SecondaryUse(deltaTime, this); if (selectedConstruction != null && GetInputState(InputType.SecondaryHeld)) selectedConstruction.SecondaryUse(deltaTime, this);
} }
if (IsNetworkPlayer) if (IsNetworkPlayer)
@@ -571,6 +539,56 @@ namespace Barotrauma
} }
} }
public void CreateUpdateNetworkEvent(bool isClient)
{
new NetworkEvent(importantUpdateTimer <= 0 ? NetworkEventType.ImportantEntityUpdate : NetworkEventType.EntityUpdate, ID, isClient);
importantUpdateTimer -= 1;
if (importantUpdateTimer < 0) importantUpdateTimer = (this is AICharacter) ? 40 : 25;
}
public bool HasSelectedItem(Item item)
{
return selectedItems.Contains(item);
}
public bool TrySelectItem(Item item)
{
bool rightHand = ((CharacterInventory)inventory).IsInLimbSlot(item, LimbSlot.RightHand);
bool leftHand = ((CharacterInventory)inventory).IsInLimbSlot(item, LimbSlot.LeftHand);
bool selected = false;
if (rightHand && SelectedItems[0] == null)
{
selectedItems[0] = item;
selected = true;
}
if (leftHand && SelectedItems[1] == null)
{
selectedItems[1] = item;
selected = true;
}
return selected;
}
public bool TrySelectItem(Item item, int index)
{
if (selectedItems[index] != null) return false;
selectedItems[index] = item;
return true;
}
public void DeselectItem(Item item)
{
for (int i = 0; i < selectedItems.Length; i++)
{
if (selectedItems[i] == item) selectedItems[i] = null;
}
}
private Item FindClosestItem(Vector2 mouseSimPos) private Item FindClosestItem(Vector2 mouseSimPos)
{ {
Limb torso = AnimController.GetLimb(LimbType.Torso); Limb torso = AnimController.GetLimb(LimbType.Torso);
@@ -824,6 +842,7 @@ namespace Barotrauma
} }
Health = health - bleeding * deltaTime; Health = health - bleeding * deltaTime;
if (health <= 0.0f) Kill(CauseOfDeath.Bloodloss, false);
} }
@@ -960,8 +979,14 @@ namespace Barotrauma
selectedConstruction = null; selectedConstruction = null;
} }
private void Implode() private void Implode(bool isNetworkMessage = false)
{ {
if (!isNetworkMessage)
{
//if the game is run by a client, characters are only killed when the server says so
if (GameMain.Client != null && GameMain.Server == null) return;
}
Vector2 centerOfMass = AnimController.GetCenterOfMass(); Vector2 centerOfMass = AnimController.GetCenterOfMass();
health = 0.0f; health = 0.0f;
@@ -992,7 +1017,7 @@ namespace Barotrauma
{ {
joint.LimitEnabled = false; joint.LimitEnabled = false;
} }
Kill(); Kill(CauseOfDeath.Pressure, isNetworkMessage);
} }
private IEnumerable<object> DeathAnim(Camera cam) private IEnumerable<object> DeathAnim(Camera cam)
@@ -1040,7 +1065,7 @@ namespace Barotrauma
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
public void Kill(bool networkMessage = false) public void Kill(CauseOfDeath causeOfDeath, bool networkMessage = false)
{ {
if (isDead) return; if (isDead) return;
@@ -1077,7 +1102,7 @@ namespace Barotrauma
if (GameMain.Server != null) if (GameMain.Server != null)
{ {
new NetworkEvent(NetworkEventType.KillCharacter, ID, false, true); new NetworkEvent(NetworkEventType.KillCharacter, ID, false, causeOfDeath);
} }
if (GameMain.GameSession != null) if (GameMain.GameSession != null)
@@ -1088,313 +1113,311 @@ namespace Barotrauma
public override bool FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data) public override bool FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data)
{ {
if (type == NetworkEventType.PickItem) switch (type)
{ {
int[] pickData = (int[])data; case NetworkEventType.PickItem:
if (pickData.Length != 3) return false; int[] pickData = (int[])data;
if (pickData.Length != 3) return false;
message.Write((ushort)pickData[0]); message.Write((ushort)pickData[0]);
message.Write((int)pickData[1] == 1); message.Write((int)pickData[1] == 1);
message.Write((int)pickData[2] == 1); message.Write((int)pickData[2] == 1);
message.WritePadBits(); message.WritePadBits();
return true; return true;
case NetworkEventType.SelectCharacter:
message.Write((ushort)data);
return true;
case NetworkEventType.KillCharacter:
CauseOfDeath causeOfDeath = CauseOfDeath.Damage;
try
{
causeOfDeath = (CauseOfDeath)data;
}
catch
{
causeOfDeath = CauseOfDeath.Damage;
}
message.Write((byte)causeOfDeath);
return true;
case NetworkEventType.InventoryUpdate:
if (inventory == null) return false;
return inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
case NetworkEventType.ImportantEntityUpdate:
int i = 0;
foreach (Limb limb in AnimController.Limbs)
{
message.Write(limb.body.SimPosition.X);
message.Write(limb.body.SimPosition.Y);
//message.Write(limb.body.LinearVelocity.X);
//message.Write(limb.body.LinearVelocity.Y);
message.Write(limb.body.Rotation);
//message.WriteRangedSingle(MathHelper.Clamp(limb.body.AngularVelocity, -10.0f, 10.0f), -10.0f, 10.0f, 8);
i++;
}
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer,0.0f,60.0f), 0.0f, 60.0f, 8);
message.Write((byte)((health/maxHealth)*255.0f));
message.Write((byte)(MathHelper.Clamp(oxygen * 2.55f, 0.0f, 255.0f)));
return true;
case NetworkEventType.EntityUpdate:
var hasInputs =
GetInputState(InputType.Left) ||
GetInputState(InputType.Right) ||
GetInputState(InputType.Up) ||
GetInputState(InputType.Down) ||
GetInputState(InputType.ActionHeld) ||
GetInputState(InputType.SecondaryHeld);
message.Write(hasInputs);
message.Write((float)NetTime.Now);
if (!hasInputs) return true;
message.Write(keys[(int)InputType.ActionHeld].Dequeue);
bool secondaryHeld = keys[(int)InputType.SecondaryHeld].Dequeue;
message.Write(secondaryHeld);
message.Write(keys[(int)InputType.Left].Dequeue);
message.Write(keys[(int)InputType.Right].Dequeue);
message.Write(keys[(int)InputType.Up].Dequeue);
message.Write(keys[(int)InputType.Down].Dequeue);
message.Write(keys[(int)InputType.Run].Dequeue);
if (secondaryHeld)
{
message.Write(cursorPosition.X);
message.Write(cursorPosition.Y);
}
else
{
message.Write(AnimController.Dir > 0.0f);
}
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
return true;
default:
#if DEBUG
DebugConsole.ThrowError("Character "+this+" tried to fill a networkevent of the wrong type: "+type);
#endif
return false;
} }
else if (type == NetworkEventType.SelectCharacter)
{
message.Write((ushort)data);
return true;
}
else if (type == NetworkEventType.KillCharacter)
{
return true;
}
else if (type == NetworkEventType.InventoryUpdate)
{
if (inventory == null) return false;
return inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
}
var hasInputs =
(GetInputState(InputType.Left) ||
GetInputState(InputType.Right) ||
GetInputState(InputType.Up) ||
GetInputState(InputType.Down) ||
GetInputState(InputType.ActionHeld) ||
GetInputState(InputType.SecondaryHeld)) || LargeUpdateTimer <= 0;
message.Write(hasInputs);
message.Write((float)NetTime.Now);
if (!hasInputs) return true;
// Write byte = move direction
//message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 8);
//message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 8);
message.Write(keys[(int)InputType.ActionHeld].Dequeue);
bool secondaryHeld = keys[(int)InputType.SecondaryHeld].Dequeue;
message.Write(secondaryHeld);
message.Write(keys[(int)InputType.Left].Dequeue);
message.Write(keys[(int)InputType.Right].Dequeue);
message.Write(keys[(int)InputType.Up].Dequeue);
message.Write(keys[(int)InputType.Down].Dequeue);
message.Write(keys[(int)InputType.Run].Dequeue);
if (secondaryHeld)
{
message.Write(cursorPosition.X);
message.Write(cursorPosition.Y);
}
else
{
message.Write(AnimController.Dir > 0.0f);
}
message.Write(LargeUpdateTimer <= 0);
if (LargeUpdateTimer<=0)
{
int i = 0;
foreach (Limb limb in AnimController.Limbs)
{
message.Write(limb.body.SimPosition.X);
message.Write(limb.body.SimPosition.Y);
//message.Write(limb.body.LinearVelocity.X);
//message.Write(limb.body.LinearVelocity.Y);
message.Write(limb.body.Rotation);
//message.WriteRangedSingle(MathHelper.Clamp(limb.body.AngularVelocity, -10.0f, 10.0f), -10.0f, 10.0f, 8);
i++;
}
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer,0.0f,60.0f), 0.0f, 60.0f, 8);
message.Write((byte)((health/maxHealth)*255.0f));
LargeUpdateTimer = 30;
}
else
{
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
LargeUpdateTimer = Math.Max(0, LargeUpdateTimer-1);
}
return true;
} }
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
{ {
Enabled = true; Enabled = true;
if (type == NetworkEventType.PickItem) switch (type)
{ {
System.Diagnostics.Debug.WriteLine("**************** PickItem networkevent received"); case NetworkEventType.PickItem:
System.Diagnostics.Debug.WriteLine("**************** PickItem networkevent received");
ushort itemId = 0; ushort itemId = message.ReadUInt16();
itemId = message.ReadUInt16(); bool pickHit = message.ReadBoolean();
bool actionHit = message.ReadBoolean();
bool pickHit = message.ReadBoolean(); System.Diagnostics.Debug.WriteLine("item id: "+itemId);
bool actionHit = message.ReadBoolean();
System.Diagnostics.Debug.WriteLine("item id: "+itemId); Item item = FindEntityByID(itemId) as Item;
if (item != null) item.Pick(this, false, pickHit, actionHit);
Item item = FindEntityByID(itemId) as Item;
if (item != null)
{
item.Pick(this, false, pickHit, actionHit);
}
return;
}
else if (type == NetworkEventType.SelectCharacter)
{
ushort characterId = message.ReadUInt16();
if (characterId==0)
{
DeselectCharacter(false);
}
else
{
Character character = FindEntityByID(characterId) as Character;
if (character != null) SelectCharacter(character, false);
}
return;
}
else if (type == NetworkEventType.KillCharacter)
{
Kill(true);
if (GameMain.NetworkMember != null && controlled == this)
{
GameMain.NetworkMember.AddChatMessage("YOU HAVE DIED. Your chat messages will only be visible to other dead players.", ChatMessageType.Dead);
GameMain.LightManager.LosEnabled = false;
}
return;
}
else if (type == NetworkEventType.InventoryUpdate)
{
if (inventory == null) return;
inventory.ReadNetworkData(NetworkEventType.InventoryUpdate, message);
return;
}
bool actionKeyState = false;
bool secondaryKeyState = false;
float sendingTime = 0.0f;
Vector2 cursorPos = Vector2.Zero;
bool leftKeyState = false, rightKeyState = false;
bool upKeyState = false, downKeyState = false;
bool runState = false;
try
{
bool hasInputs = message.ReadBoolean();
sendingTime = message.ReadFloat();
if (!hasInputs)
{
if (sendingTime > LastNetworkUpdate) ClearInputs();
return; return;
} case NetworkEventType.SelectCharacter:
ushort characterId = message.ReadUInt16();
if (characterId==0)
{
DeselectCharacter(false);
}
else
{
Character character = FindEntityByID(characterId) as Character;
if (character != null) SelectCharacter(character, false);
}
return;
case NetworkEventType.KillCharacter:
CauseOfDeath causeOfDeath = CauseOfDeath.Damage;
try
{
byte causeOfDeathByte = message.ReadByte();
causeOfDeath = (CauseOfDeath)causeOfDeathByte;
}
catch
{
causeOfDeath = CauseOfDeath.Damage;
}
actionKeyState = message.ReadBoolean(); if (causeOfDeath==CauseOfDeath.Pressure)
secondaryKeyState = message.ReadBoolean(); {
Implode(true);
}
else
{
Kill(causeOfDeath, true);
}
leftKeyState = message.ReadBoolean(); if (GameMain.NetworkMember != null && controlled == this)
rightKeyState = message.ReadBoolean(); {
upKeyState = message.ReadBoolean(); GameMain.NetworkMember.AddChatMessage("You have "+DeathMsg[(int)causeOfDeath]+". Your chat messages will only be visible to other dead players.", ChatMessageType.Dead);
downKeyState = message.ReadBoolean(); GameMain.LightManager.LosEnabled = false;
}
return;
case NetworkEventType.InventoryUpdate:
if (inventory == null) return;
inventory.ReadNetworkData(NetworkEventType.InventoryUpdate, message);
return;
case NetworkEventType.ImportantEntityUpdate:
foreach (Limb limb in AnimController.Limbs)
{
Vector2 limbPos = limb.SimPosition, vel = Vector2.Zero;
float rotation = limb.Rotation;
runState = message.ReadBoolean(); try
} {
limbPos.X = message.ReadFloat();
limbPos.Y = message.ReadFloat();
catch (Exception e) rotation = message.ReadFloat();
{ }
return; catch
} {
return;
}
AnimController.IsStanding = true; if (limb.body != null)
{
limb.body.TargetVelocity = limb.body.LinearVelocity;
limb.body.TargetPosition = limbPos;// +vel * (float)(deltaTime / 60.0);
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0);
limb.body.TargetAngularVelocity = limb.body.AngularVelocity;
}
keys[(int)InputType.ActionHeld].State = actionKeyState; }
keys[(int)InputType.SecondaryHeld].State = secondaryKeyState;
if (sendingTime <= LastNetworkUpdate) return; float newStunTimer = 0.0f, newHealth = 0.0f, newOxygen = 0.0f;
keys[(int)InputType.Left].State = leftKeyState;
keys[(int)InputType.Right].State = rightKeyState;
keys[(int)InputType.Up].State = upKeyState;
keys[(int)InputType.Down].State = downKeyState;
keys[(int)InputType.Run].State = runState;
float dir = 1.0f;
bool isLargeUpdate;
try
{
if (secondaryKeyState)
{
cursorPos = new Vector2(
message.ReadFloat(),
message.ReadFloat());
}
else
{
dir = message.ReadBoolean() ? 1.0f : -1.0f;
}
isLargeUpdate = message.ReadBoolean();
}
catch
{
return;
}
if (secondaryKeyState)
{
cursorPosition = MathUtils.IsValid(cursorPos) ? cursorPos : Vector2.Zero;
}
else
{
cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir;
}
if (isLargeUpdate)
{
foreach (Limb limb in AnimController.Limbs)
{
Vector2 pos = Vector2.Zero, vel = Vector2.Zero;
float rotation = 0.0f;
try try
{ {
pos.X = message.ReadFloat(); newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
pos.Y = message.ReadFloat(); newHealth = (message.ReadByte() / 255.0f) * maxHealth;
newOxygen = (message.ReadByte() / 2.55f);
//vel.X = message.ReadFloat();
//vel.Y = message.ReadFloat();
rotation = message.ReadFloat();
//angularVel = message.ReadFloat();
} }
catch catch { return; }
StartStun(newStunTimer);
Health = newHealth;
oxygen = newOxygen;
return;
case NetworkEventType.EntityUpdate:
float sendingTime = 0.0f;
Vector2 cursorPos = Vector2.Zero;
bool actionKeyState, secondaryKeyState;
bool leftKeyState, rightKeyState, upKeyState, downKeyState;
bool runState;
try
{
bool hasInputs = message.ReadBoolean();
sendingTime = message.ReadFloat();
if (!hasInputs)
{
if (sendingTime > LastNetworkUpdate) ClearInputs();
return;
}
actionKeyState = message.ReadBoolean();
secondaryKeyState = message.ReadBoolean();
leftKeyState = message.ReadBoolean();
rightKeyState = message.ReadBoolean();
upKeyState = message.ReadBoolean();
downKeyState = message.ReadBoolean();
runState = message.ReadBoolean();
}
catch (Exception e)
{ {
return; return;
} }
if (limb.body != null) AnimController.IsStanding = true;
keys[(int)InputType.ActionHeld].State = actionKeyState;
keys[(int)InputType.SecondaryHeld].State = secondaryKeyState;
if (sendingTime <= LastNetworkUpdate) return;
keys[(int)InputType.Left].State = leftKeyState;
keys[(int)InputType.Right].State = rightKeyState;
keys[(int)InputType.Up].State = upKeyState;
keys[(int)InputType.Down].State = downKeyState;
keys[(int)InputType.Run].State = runState;
float dir = 1.0f;
Vector2 pos = Vector2.Zero;
try
{ {
limb.body.TargetVelocity = limb.body.LinearVelocity; if (secondaryKeyState)
limb.body.TargetPosition = pos;// +vel * (float)(deltaTime / 60.0); {
limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0); cursorPos = new Vector2(
limb.body.TargetAngularVelocity = limb.body.AngularVelocity; message.ReadFloat(),
message.ReadFloat());
}
else
{
dir = message.ReadBoolean() ? 1.0f : -1.0f;
}
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
}
catch
{
#if DEBUG
DebugConsole.ThrowError("Failed to read netowkrevent for "+this.ToString());
#endif
return;
}
if (secondaryKeyState)
{
cursorPosition = MathUtils.IsValid(cursorPos) ? cursorPos : Vector2.Zero;
}
else
{
cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir;
} }
} AnimController.RefLimb.body.TargetPosition = pos;
float newStunTimer = 0.0f, newHealth = 0.0f; LastNetworkUpdate = sendingTime;
try return;
{ default:
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8); #if DEBUG
newHealth = (message.ReadByte() / 255.0f) * maxHealth; DebugConsole.ThrowError("Character " + this + " tried to read a networkevent of the wrong type: " + type);
} #endif
catch { return; } return;
StartStun(newStunTimer);
Health = newHealth;
LargeUpdateTimer = 1;
} }
else
{
Vector2 pos = Vector2.Zero;
try
{
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
}
catch { return; }
AnimController.RefLimb.body.TargetPosition = pos;
LargeUpdateTimer = 0;
}
LastNetworkUpdate = sendingTime;
} }
public override void Remove() public override void Remove()
+14 -6
View File
@@ -667,11 +667,15 @@ namespace Barotrauma
float allowedDistance = NetConfig.AllowedRagdollDistance * ((inWater) ? 2.0f : 1.0f); float allowedDistance = NetConfig.AllowedRagdollDistance * ((inWater) ? 2.0f : 1.0f);
float dist = Vector2.Distance(refLimb.body.SimPosition, refLimb.body.TargetPosition); float dist = Vector2.Distance(refLimb.body.SimPosition, refLimb.body.TargetPosition);
bool resetAll = (dist > resetDistance && character.LargeUpdateTimer == 1); bool resetAll = dist > resetDistance;
if (resetAll)
{
if (Limbs.FirstOrDefault(limb => !limb.ignoreCollisions && limb.body.TargetPosition == Vector2.Zero) != null) resetAll = false;
}
Vector2 newMovement = (refLimb.body.TargetPosition - refLimb.body.SimPosition); Vector2 diff = (refLimb.body.TargetPosition - refLimb.body.SimPosition);
if (newMovement == Vector2.Zero || newMovement.Length() < allowedDistance) if (diff == Vector2.Zero || diff.Length() < allowedDistance)
{ {
refLimb.body.TargetPosition = Vector2.Zero; refLimb.body.TargetPosition = Vector2.Zero;
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
@@ -694,12 +698,12 @@ namespace Barotrauma
} }
correctionMovement = correctionMovement =
Vector2.Lerp(targetMovement, Vector2.Normalize(newMovement) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f), 0.2f); Vector2.Lerp(targetMovement, Vector2.Normalize(diff) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f), 0.2f);
} }
else else
{ {
correctionMovement = correctionMovement =
Vector2.Lerp(targetMovement, Vector2.Normalize(newMovement) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f), 0.2f); Vector2.Lerp(targetMovement, Vector2.Normalize(diff) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f), 0.2f);
if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f; if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f;
} }
@@ -711,7 +715,11 @@ namespace Barotrauma
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
{ {
if (limb.body.TargetPosition == Vector2.Zero) continue; if (limb.body.TargetPosition == Vector2.Zero)
{
limb.body.SetTransform(limb.body.SimPosition + diff, limb.body.Rotation);
continue;
}
limb.body.LinearVelocity = limb.body.TargetVelocity; limb.body.LinearVelocity = limb.body.TargetVelocity;
limb.body.AngularVelocity = limb.body.TargetAngularVelocity; limb.body.AngularVelocity = limb.body.TargetAngularVelocity;
+8 -2
View File
@@ -43,7 +43,7 @@ namespace Barotrauma
public static void Init(GameWindow window) public static void Init(GameWindow window)
{ {
textBox = new GUITextBox(new Rectangle(30, 480,780, 30), Color.Black, Color.White, Alignment.Left, Alignment.Left); textBox = new GUITextBox(new Rectangle(30, 480,780, 30), Color.Black, Color.White, Alignment.Left, Alignment.Left);
NewMessage("Press F3 to open/close the debug console", Color.Green); NewMessage("Press F3 to open/close the debug console", Color.Cyan);
} }
public static void Update(GameMain game, float deltaTime) public static void Update(GameMain game, float deltaTime)
@@ -212,8 +212,14 @@ namespace Barotrauma
case "editchar": case "editchar":
GameMain.EditCharacterScreen.Select(); GameMain.EditCharacterScreen.Select();
break; break;
case "controlcharacter":
case "control":
if (commands.Length < 2) break;
commands[1] = commands[1].ToLower();
Character.Controlled = Character.CharacterList.Find(c => c.Name.ToLower() == commands[1]);
break;
case "heal": case "heal":
if (Character.Controlled!=null) if (Character.Controlled != null)
{ {
Character.Controlled.Health = Character.Controlled.MaxHealth; Character.Controlled.Health = Character.Controlled.MaxHealth;
Character.Controlled.Bleeding = 0.0f; Character.Controlled.Bleeding = 0.0f;
@@ -239,6 +239,17 @@ namespace Barotrauma.Items.Components
itemIds = null; itemIds = null;
} }
public override void Remove()
{
base.Remove();
foreach (Item item in inventory.items)
{
if (item == null) continue;
item.Remove();
}
}
public override void Load(XElement componentElement) public override void Load(XElement componentElement)
{ {
base.Load(componentElement); base.Load(componentElement);
-1
View File
@@ -308,7 +308,6 @@ namespace Barotrauma
Color.Red*((100.0f-OxygenPercentage)/400.0f), true); Color.Red*((100.0f-OxygenPercentage)/400.0f), true);
spriteBatch.DrawString(GUI.Font, "Pressure: " + ((int)pressure - rect.Y).ToString() + spriteBatch.DrawString(GUI.Font, "Pressure: " + ((int)pressure - rect.Y).ToString() +
" - Lethality: " + lethalPressure +
" - Oxygen: "+((int)OxygenPercentage), new Vector2(rect.X+10, -rect.Y+10), Color.Black); " - Oxygen: "+((int)OxygenPercentage), new Vector2(rect.X+10, -rect.Y+10), Color.Black);
spriteBatch.DrawString(GUI.Font, volume +" / "+ FullVolume, new Vector2(rect.X+10, -rect.Y+30), Color.Black); spriteBatch.DrawString(GUI.Font, volume +" / "+ FullVolume, new Vector2(rect.X+10, -rect.Y+30), Color.Black);
+8 -2
View File
@@ -506,7 +506,7 @@ namespace Barotrauma
/// Has to be done after all the entities have been loaded (an entity can't /// Has to be done after all the entities have been loaded (an entity can't
/// be linked to some other entity that hasn't been loaded yet) /// be linked to some other entity that hasn't been loaded yet)
/// </summary> /// </summary>
public static void OnMapLoaded() public static void MapLoaded()
{ {
foreach (MapEntity e in mapEntityList) foreach (MapEntity e in mapEntityList)
{ {
@@ -524,14 +524,20 @@ namespace Barotrauma
} }
} }
foreach (MapEntity e in mapEntityList)
{
e.OnMapLoaded();
}
//mapEntityList.Sort((x, y) => //mapEntityList.Sort((x, y) =>
//{ //{
// return x.Name.CompareTo(y.Name); // return x.Name.CompareTo(y.Name);
//}); //});
} }
public virtual void OnMapLoaded() { }
public void RemoveLinked(MapEntity e) public void RemoveLinked(MapEntity e)
{ {
+1 -1
View File
@@ -623,7 +623,7 @@ namespace Barotrauma
subBody = new SubmarineBody(this); subBody = new SubmarineBody(this);
MapEntity.OnMapLoaded(); MapEntity.MapLoaded();
foreach (Item item in Item.itemList) foreach (Item item in Item.itemList)
{ {
+3 -2
View File
@@ -266,8 +266,9 @@ namespace Barotrauma.Networking
} }
} }
catch catch (Exception e)
{ {
DebugConsole.ThrowError("Error while connecting to server", e);
break; break;
} }
} }
@@ -354,7 +355,7 @@ namespace Barotrauma.Networking
} }
else if (gameStarted) else if (gameStarted)
{ {
new NetworkEvent(myCharacter.ID, true); myCharacter.CreateUpdateNetworkEvent(true);
} }
} }
+4 -5
View File
@@ -302,16 +302,15 @@ namespace Barotrauma.Networking
{ {
if (gameStarted) if (gameStarted)
{ {
if (myCharacter != null) new NetworkEvent(myCharacter.ID, true); if (myCharacter != null) myCharacter.CreateUpdateNetworkEvent(false);
foreach (Character c in Character.CharacterList) foreach (Character c in Character.CharacterList)
{ {
if (c as AICharacter == null) continue; if (c as AICharacter == null) continue;
if (c.SimPosition == Vector2.Zero || c.SimPosition.Length() < 100.0f) if (c.SimPosition.Length() > 100.0f) continue;
{
new NetworkEvent(c.ID, false); c.CreateUpdateNetworkEvent(false);
}
} }
} }
@@ -21,6 +21,8 @@ namespace Barotrauma.Networking
//if the ragdoll is closer than this, don't try to correct its position //if the ragdoll is closer than this, don't try to correct its position
public const float AllowedRagdollDistance = 0.1f; public const float AllowedRagdollDistance = 0.1f;
public const float LargeCharacterUpdateInterval = 5.0f;
public const float DeleteDisconnectedTime = 10.0f; public const float DeleteDisconnectedTime = 10.0f;
public const float AckInterval = 0.2f; public const float AckInterval = 0.2f;
@@ -19,7 +19,6 @@ namespace Barotrauma.Networking
DropItem = 7, DropItem = 7,
InventoryUpdate = 8, InventoryUpdate = 8,
UpdateProperty = 9, UpdateProperty = 9,
WallDamage = 10, WallDamage = 10,
@@ -176,6 +176,13 @@ namespace Barotrauma
} }
else if (dummyCharacter != null) else if (dummyCharacter != null)
{ {
foreach (Item item in dummyCharacter.Inventory.items)
{
if (item == null) continue;
item.Remove();
}
dummyCharacter.Remove(); dummyCharacter.Remove();
dummyCharacter = null; dummyCharacter = null;
} }
+36
View File
@@ -1,3 +1,39 @@
---------------------------------------------------------------------------------------------------------
v0.2.3.1
---------------------------------------------------------------------------------------------------------
- fixed some broken items in Aegir Mark II which caused inventories to get messed up
- fixed the gap at observation deck which vents water out from the lower level of the room
---------------------------------------------------------------------------------------------------------
v0.2.3
---------------------------------------------------------------------------------------------------------
Multiplayer:
- major changes to the way the game handles sending reliable messages through UDP, should get rid of
the occasional massive lag spikes
- fixed multiple issues in inventory syncing
- fixed attachable items occasionally crashing the game
- players can be banned from servers
- fixed not being able to kick players while a round is running
- misc optimization
Items:
- screwdrivers and wrenches are used by left clicking now, so it's possible to start rewiring a
button without activating it for example
- the inventory slots are "combined" when equipping an item that takes up more than one slot
- door shadows aren't visible if the door is open when loading a map
- fixed projectiles crashing the game if they're stuck to a wall while a hole appears on it
- wrenches can be used as an ineffective melee weapon
Submarine:
- another minimap and a sonar monitor at the "observation deck" on Aegir
- changed one of the cabins to a holding cell on Aegir
Misc:
- fixed a bug in UI listboxes that may have caused crashes in the server list screen
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
v0.2.2 v0.2.2
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
Binary file not shown.