From a46c1955329028f6ddaa56dce7321cacf7f46f17 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 1 Apr 2019 22:51:07 +0300 Subject: [PATCH] (2a183f60c) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev --- .../Source/Characters/Animation/Ragdoll.cs | 64 ++++++++++++------- .../Source/Characters/CharacterNetworking.cs | 27 +++++--- Barotrauma/BarotraumaClient/Source/GUI/GUI.cs | 7 -- .../Source/Physics/PhysicsBody.cs | 3 + .../Source/Characters/CharacterNetworking.cs | 9 ++- .../Source/Physics/PhysicsBody.cs | 14 ++-- .../Source/Characters/AI/EnemyAIController.cs | 41 ++++++++++++ .../Source/Characters/CharacterNetworking.cs | 10 +-- .../Source/Items/ItemPrefab.cs | 33 ++++++++++ .../Source/Networking/NetConfig.cs | 18 ++++++ 10 files changed, 171 insertions(+), 55 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index c6f95eda7..da396dad7 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -44,25 +44,29 @@ namespace Barotrauma return; } - if (character.MemState[0].Interact == null || character.MemState[0].Interact.Removed) + if (character.MemState[0].SelectedCharacter == null || character.MemState[0].SelectedCharacter.Removed) { character.DeselectCharacter(); + } + else if (character.MemState[0].SelectedCharacter != null) + { + character.SelectCharacter(character.MemState[0].SelectedCharacter); + } + + if (character.MemState[0].SelectedItem == null || character.MemState[0].SelectedItem.Removed) + { character.SelectedConstruction = null; } - else if (character.MemState[0].Interact is Character) + else { - character.SelectCharacter((Character)character.MemState[0].Interact); - } - else if (character.MemState[0].Interact is Item newSelectedConstruction) - { - if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction) + if (character.SelectedConstruction != character.MemState[0].SelectedItem) { - foreach (var ic in newSelectedConstruction.Components) + foreach (var ic in character.MemState[0].SelectedItem.Components) { if (ic.CanBeSelected) ic.Select(character); } } - character.SelectedConstruction = newSelectedConstruction; + character.SelectedConstruction = character.MemState[0].SelectedItem; } if (character.MemState[0].Animation == AnimController.Animation.CPR) @@ -88,13 +92,13 @@ namespace Barotrauma Collider.AngularVelocity = newAngularVelocity; float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition); - float errorTolerance = character.AllowInput ? 0.01f : 0.1f; + float errorTolerance = character.AllowInput ? 0.01f : 0.2f; if (distSqrd > errorTolerance) { if (distSqrd > 10.0f || !character.AllowInput) { Collider.TargetRotation = newRotation; - SetPosition(newPosition, lerp: distSqrd < 1.0f); + SetPosition(newPosition, lerp: distSqrd < 5.0f); } else { @@ -108,8 +112,15 @@ namespace Barotrauma // -> we need to correct it manually if (!character.AllowInput) { - MainLimb.PullJointWorldAnchorB = Collider.SimPosition; - MainLimb.PullJointEnabled = true; + float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition); + float mainLimbErrorTolerance = 0.1f; + //if the main limb is roughly at the correct position and the collider isn't moving (much at least), + //don't attempt to correct the position. + if (mainLimbDistSqrd > mainLimbErrorTolerance || Collider.LinearVelocity.LengthSquared() > 0.05f) + { + MainLimb.PullJointWorldAnchorB = Collider.SimPosition; + MainLimb.PullJointEnabled = true; + } } } character.MemLocalState.Clear(); @@ -162,25 +173,30 @@ namespace Barotrauma CharacterStateInfo localPos = character.MemLocalState[localPosIndex]; //the entity we're interacting with doesn't match the server's - if (localPos.Interact != serverPos.Interact) + if (localPos.SelectedCharacter != serverPos.SelectedCharacter) { - if (serverPos.Interact == null || serverPos.Interact.Removed) + if (serverPos.SelectedCharacter == null || serverPos.SelectedCharacter.Removed) { character.DeselectCharacter(); + } + else if (serverPos.SelectedCharacter != null) + { + character.SelectCharacter(serverPos.SelectedCharacter); + } + } + if (localPos.SelectedItem != serverPos.SelectedItem) + { + if (serverPos.SelectedItem == null || serverPos.SelectedItem.Removed) + { character.SelectedConstruction = null; } - else if (serverPos.Interact is Character) + else if (serverPos.SelectedItem != null) { - character.SelectCharacter((Character)serverPos.Interact); - } - else - { - var newSelectedConstruction = (Item)serverPos.Interact; - if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction) + if (character.SelectedConstruction != serverPos.SelectedItem) { - newSelectedConstruction.TryInteract(character, true, true); + serverPos.SelectedItem.TryInteract(character, true, true); } - character.SelectedConstruction = newSelectedConstruction; + character.SelectedConstruction = serverPos.SelectedItem; } } diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs index 955c0d516..9569a07c5 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs @@ -30,12 +30,13 @@ namespace Barotrauma else { var posInfo = new CharacterStateInfo( - SimPosition, - AnimController.Collider.Rotation, - LastNetworkUpdateID, - AnimController.TargetDir, - SelectedCharacter == null ? (Entity)SelectedConstruction : (Entity)SelectedCharacter, - AnimController.Anim); + SimPosition, + AnimController.Collider.Rotation, + LastNetworkUpdateID, + AnimController.TargetDir, + SelectedCharacter, + SelectedConstruction, + AnimController.Anim); memLocalState.Add(posInfo); @@ -214,6 +215,7 @@ namespace Barotrauma Vector2 linearVelocity = new Vector2( msg.ReadRangedSingle(-MaxVel, MaxVel, 12), msg.ReadRangedSingle(-MaxVel, MaxVel, 12)); + linearVelocity = NetConfig.Quantize(linearVelocity, -MaxVel, MaxVel, 12); bool fixedRotation = msg.ReadBoolean(); float? rotation = null; @@ -223,6 +225,7 @@ namespace Barotrauma rotation = msg.ReadFloat(); float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; angularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8); + angularVelocity = NetConfig.Quantize(angularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8); } bool readStatus = msg.ReadBoolean(); @@ -236,7 +239,11 @@ namespace Barotrauma int index = 0; if (GameMain.Client.Character == this && AllowInput) { - var posInfo = new CharacterStateInfo(pos, rotation, networkUpdateID, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation); + var posInfo = new CharacterStateInfo( + pos, rotation, + networkUpdateID, + facingRight ? Direction.Right : Direction.Left, + selectedCharacter, selectedItem, animation); while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID)) index++; @@ -244,7 +251,11 @@ namespace Barotrauma } else { - var posInfo = new CharacterStateInfo(pos, rotation, linearVelocity, angularVelocity, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation); + var posInfo = new CharacterStateInfo( + pos, rotation, + linearVelocity, angularVelocity, + sendingTime, facingRight ? Direction.Right : Direction.Left, + selectedCharacter, selectedItem, animation); while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp) index++; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs index cbb751f50..ec5b88851 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs @@ -656,13 +656,6 @@ namespace Barotrauma msg.Timer -= deltaTime; msg.Pos += msg.Velocity * deltaTime; } - - foreach (GUIMessage msg in messages) - { - if (!msg.WorldSpace) continue; - msg.Timer -= deltaTime; - msg.Pos += msg.Velocity * deltaTime; - } } messages.RemoveAll(m => m.Timer <= 0.0f); diff --git a/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs index f231c83a0..88e1011e8 100644 --- a/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaClient/Source/Physics/PhysicsBody.cs @@ -171,9 +171,12 @@ namespace Barotrauma newVelocity = new Vector2( msg.ReadRangedSingle(-MaxVel, MaxVel, 12), msg.ReadRangedSingle(-MaxVel, MaxVel, 12)); + newVelocity = NetConfig.Quantize(newVelocity, -MaxVel, MaxVel, 12); + if (!fixedRotation) { newAngularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8); + newAngularVelocity = NetConfig.Quantize(newAngularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8); } } msg.ReadPadBits(); diff --git a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs index d9831f872..9845cb86c 100644 --- a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs @@ -362,7 +362,8 @@ namespace Barotrauma if (SelectedCharacter != null || SelectedConstruction != null) { tempBuffer.Write(true); - tempBuffer.Write(SelectedCharacter != null ? SelectedCharacter.ID : SelectedConstruction.ID); + tempBuffer.Write(SelectedCharacter != null ? SelectedCharacter.ID : NullEntityID); + tempBuffer.Write(SelectedConstruction != null ? SelectedConstruction.ID : NullEntityID); if (SelectedCharacter != null) { tempBuffer.Write(AnimController.Anim == AnimController.Animation.CPR); @@ -376,8 +377,9 @@ namespace Barotrauma tempBuffer.Write(SimPosition.X); tempBuffer.Write(SimPosition.Y); float MaxVel = NetConfig.MaxPhysicsBodyVelocity; - tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel), -MaxVel, MaxVel, 12); - tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel), -MaxVel, MaxVel, 12); + AnimController.Collider.LinearVelocity = NetConfig.Quantize(AnimController.Collider.LinearVelocity, -MaxVel, MaxVel, 12); + tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12); + tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12); bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation; tempBuffer.Write(fixedRotation); @@ -385,6 +387,7 @@ namespace Barotrauma { tempBuffer.Write(AnimController.Collider.Rotation); float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; + AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8); tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8); } diff --git a/Barotrauma/BarotraumaServer/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaServer/Source/Physics/PhysicsBody.cs index b2276c7f5..10580b11e 100644 --- a/Barotrauma/BarotraumaServer/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaServer/Source/Physics/PhysicsBody.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Barotrauma.Networking; +using Barotrauma.Networking; using Lidgren.Network; using Microsoft.Xna.Framework; +using System; namespace Barotrauma { @@ -37,10 +33,12 @@ namespace Barotrauma if (FarseerBody.Awake) { body.Enabled = true; - msg.WriteRangedSingle(MathHelper.Clamp(body.LinearVelocity.X, -MaxVel, MaxVel), -MaxVel, MaxVel, 12); - msg.WriteRangedSingle(MathHelper.Clamp(body.LinearVelocity.Y, -MaxVel, MaxVel), -MaxVel, MaxVel, 12); + body.LinearVelocity = NetConfig.Quantize(body.LinearVelocity, -MaxVel, MaxVel, 12); + msg.WriteRangedSingle(body.LinearVelocity.X, -MaxVel, MaxVel, 12); + msg.WriteRangedSingle(body.LinearVelocity.Y, -MaxVel, MaxVel, 12); if (!FarseerBody.FixedRotation) { + body.AngularVelocity = NetConfig.Quantize(body.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8); msg.WriteRangedSingle(MathHelper.Clamp(body.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index 42567d00b..2dafda0cc 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -1216,6 +1216,43 @@ namespace Barotrauma targetingTag = "room"; } if (door != null) + { + // If there's not a more specific tag for the door + if (string.IsNullOrEmpty(targetingTag) || targetingTag == "room") + { + targetingTag = "door"; + } + bool isOutdoor = door.LinkedGap?.FlowTargetHull != null && !door.LinkedGap.IsRoomToRoom; + bool isOpen = door.IsOpen || door.Item.Condition <= 0.0f; + //increase priority if the character is outside and an aggressive boarder, and the door is from outside to inside + if (aggressiveBoarding) + { + if (character.CurrentHull == null) + { + valueModifier = isOutdoor ? 1 : 0; + valueModifier *= isOpen ? 5 : 1; + } + } + else + { + // Ignore disabled walls + bool isDisabled = true; + for (int i = 0; i < s.Sections.Length; i++) + { + valueModifier = isOutdoor ? 0 : 1; + valueModifier *= isOpen ? 0 : 1; + } + if (isDisabled) + { + valueModifier = 0; + } + } + } + else + { + targetingTag = "room"; + } + if (door != null) { // If there's not a more specific tag for the door if (string.IsNullOrEmpty(targetingTag) || targetingTag == "room") @@ -1242,6 +1279,10 @@ namespace Barotrauma { continue; } + else if (isOpen) //ignore broken and open doors + { + continue; + } } else if (target.Entity is IDamageable targetDamageable && targetDamageable.Health <= 0.0f) { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs index b7e551095..ac52f3b2b 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs @@ -14,17 +14,17 @@ namespace Barotrauma public readonly AnimController.Animation Animation; - public CharacterStateInfo(Vector2 pos, float? rotation, Vector2 velocity, float? angularVelocity, float time, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) - : this(pos, rotation, velocity, angularVelocity, 0, time, dir, interact, animation) + public CharacterStateInfo(Vector2 pos, float? rotation, Vector2 velocity, float? angularVelocity, float time, Direction dir, Character selectedCharacter, Item selectedItem, AnimController.Animation animation = AnimController.Animation.None) + : this(pos, rotation, velocity, angularVelocity, 0, time, dir, selectedCharacter, selectedItem, animation) { } - public CharacterStateInfo(Vector2 pos, float? rotation, UInt16 ID, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) - : this(pos, rotation, Vector2.Zero, 0.0f, ID, 0.0f, dir, interact, animation) + public CharacterStateInfo(Vector2 pos, float? rotation, UInt16 ID, Direction dir, Character selectedCharacter, Item selectedItem, AnimController.Animation animation = AnimController.Animation.None) + : this(pos, rotation, Vector2.Zero, 0.0f, ID, 0.0f, dir, selectedCharacter, selectedItem, animation) { } - protected CharacterStateInfo(Vector2 pos, float? rotation, Vector2 velocity, float? angularVelocity, UInt16 ID, float time, Direction dir, Entity interact, AnimController.Animation animation = AnimController.Animation.None) + protected CharacterStateInfo(Vector2 pos, float? rotation, Vector2 velocity, float? angularVelocity, UInt16 ID, float time, Direction dir, Character selectedCharacter, Item selectedItem, AnimController.Animation animation = AnimController.Animation.None) : base(pos, rotation, velocity, angularVelocity, ID, time) { Direction = dir; diff --git a/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs index 6cfd8de05..95820fd6b 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs @@ -1082,6 +1082,39 @@ namespace Barotrauma AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList(); + if (sprite == null) + { + DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!"); +#if SERVER + sprite = new Sprite("", Vector2.Zero); + sprite.SourceRect = new Rectangle(0, 0, 32, 32); +#else + sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null) + { + Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2 + }; +#endif + size = sprite.size; + sprite.EntityID = identifier; + } + + if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier)) + { + DebugConsole.ThrowError( + "Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading."); + } + if (!string.IsNullOrEmpty(identifier)) + { + MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier); + if (existingPrefab != null) + { + DebugConsole.ThrowError( + "Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!"); + } + } + + AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList(); + List.Add(this); } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs b/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs index 74b6afcb2..5c7bfa0f0 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/NetConfig.cs @@ -74,5 +74,23 @@ namespace Barotrauma.Networking if (lengthSqr > 1000.0f) { return Vector2.Zero; } return cursorPositionError *= 0.7f; } + + public static Vector2 Quantize(Vector2 value, float min, float max, int numberOfBits) + { + return new Vector2( + Quantize(value.X, min, max, numberOfBits), + Quantize(value.Y, min, max, numberOfBits)); + } + + public static float Quantize(float value, float min, float max, int numberOfBits) + { + float step = (max - min) / (1 << (numberOfBits + 1)); + if (Math.Abs(value) < step + 0.00001f) + { + return 0.0f; + } + + return MathUtils.RoundTowardsClosest(MathHelper.Clamp(value, min, max), step); + } } }