Submarine position is synced using the same logic as the characters, AICharacter position syncing
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
<ragdoll headposition="50" headangle="-70"
|
||||
waveamplitude="2.0" wavelength="5000"
|
||||
swimspeed="2.0" walkspeed="2.0"
|
||||
swimspeed="3.0" walkspeed="2.0"
|
||||
stepsize ="15.0,20.0"
|
||||
legtorque="10"
|
||||
flip="true">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<sound file="Content/Characters/Endworm/endwormattack1.ogg" state="Attack" range="8000" />
|
||||
<sound file="Content/Characters/Endworm/endwormattack2.ogg" state="Attack" range="8000" />
|
||||
|
||||
<ragdoll waveamplitude="100.0" wavelength="1000" speed="1.5" scale ="2.0" flip="false" canentersubmarine="false">
|
||||
<ragdoll waveamplitude="100.0" wavelength="1000" speed="2.0" scale ="2.0" flip="false" canentersubmarine="false">
|
||||
|
||||
<collider radius="300"/>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<sound file="Content/Characters/Moloch/idle1.ogg" state="None" range="3000"/>
|
||||
<sound file="Content/Characters/Moloch/idle2.ogg" state="None" range="3000"/>
|
||||
|
||||
<ragdoll waveamplitude="0.0" swimspeed="1.0" walkspeed="0.3" mirror="true" rotatetowardsmovement="false" headangle="-90">
|
||||
<ragdoll waveamplitude="0.0" swimspeed="2.0" mirror="true" rotatetowardsmovement="false" headangle="-90" canentersubmarine="false">
|
||||
|
||||
<collider radius ="230"/>
|
||||
|
||||
|
||||
@@ -254,10 +254,7 @@ namespace Barotrauma
|
||||
|
||||
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
|
||||
AnimController.TargetMovement = targetMovement;
|
||||
|
||||
AnimController.MainLimb.body.TargetPosition = pos;
|
||||
//AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
|
||||
|
||||
|
||||
if (inSub)
|
||||
{
|
||||
Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false);
|
||||
@@ -267,7 +264,15 @@ namespace Barotrauma
|
||||
Submarine = newHull.Submarine;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int index = 0;
|
||||
while (index < memPos.Count && sendingTime > memPos[index].Timestamp)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
memPos.Insert(index, new PosInfo(pos, (targetDir) ? Direction.Right : Direction.Left, sendingTime));
|
||||
|
||||
LastNetworkUpdate = sendingTime;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -195,6 +195,8 @@ namespace Barotrauma
|
||||
|
||||
for (int i = 0; i < Limbs.Count(); i++)
|
||||
{
|
||||
if (Limbs[i].SteerForce <= 0.0f) continue;
|
||||
|
||||
Vector2 pullPos = Limbs[i].pullJoint == null ? Limbs[i].SimPosition : Limbs[i].pullJoint.WorldAnchorA;
|
||||
Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
|
||||
|
||||
|
||||
@@ -14,33 +14,6 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
struct PosInfo
|
||||
{
|
||||
public readonly Vector2 Position;
|
||||
public readonly Direction Direction;
|
||||
|
||||
public readonly float Timestamp;
|
||||
public readonly UInt32 ID;
|
||||
|
||||
public PosInfo(Vector2 pos, Direction dir, float time)
|
||||
{
|
||||
Position = pos;
|
||||
Direction = dir;
|
||||
Timestamp = time;
|
||||
|
||||
ID = 0;
|
||||
}
|
||||
|
||||
public PosInfo(Vector2 pos, Direction dir, UInt32 ID)
|
||||
{
|
||||
Position = pos;
|
||||
Direction = dir;
|
||||
this.ID = ID;
|
||||
|
||||
Timestamp = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
class Character : Entity, IDamageable, IPropertyObject
|
||||
{
|
||||
public static List<Character> CharacterList = new List<Character>();
|
||||
@@ -53,7 +26,7 @@ namespace Barotrauma
|
||||
get { return netStateID; }
|
||||
}
|
||||
|
||||
List<PosInfo> memPos = new List<PosInfo>();
|
||||
protected List<PosInfo> memPos = new List<PosInfo>();
|
||||
|
||||
private bool networkUpdateSent;
|
||||
List<PosInfo> memLocalPos = new List<PosInfo>();
|
||||
@@ -2148,14 +2121,15 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir;
|
||||
|
||||
//AnimController.TargetDir = dir < 0 ? Direction.Left : Direction.Right;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
while (index < memPos.Count && sendingTime > memPos[index].Timestamp)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
//AnimController.RefLimb.body.TargetPosition =
|
||||
// AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
|
||||
|
||||
memPos.Add(new PosInfo(pos, dir < 0 ? Direction.Left : Direction.Right, sendingTime));
|
||||
memPos.Insert(index, new PosInfo(pos, dir < 0 ? Direction.Left : Direction.Right, sendingTime));
|
||||
|
||||
LastNetworkUpdate = sendingTime;
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace Barotrauma.Items.Components
|
||||
if (useWeldJoint)
|
||||
{
|
||||
joint = JointFactory.CreateWeldJoint(GameMain.World,
|
||||
item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body,
|
||||
item.Submarine.PhysicsBody.FarseerBody, dockingTarget.item.Submarine.PhysicsBody.FarseerBody,
|
||||
ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
|
||||
|
||||
((WeldJoint)joint).FrequencyHz = 1.0f;
|
||||
@@ -222,7 +222,7 @@ namespace Barotrauma.Items.Components
|
||||
else
|
||||
{
|
||||
var distanceJoint = JointFactory.CreateDistanceJoint(GameMain.World,
|
||||
item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body,
|
||||
item.Submarine.PhysicsBody.FarseerBody, dockingTarget.item.Submarine.PhysicsBody.FarseerBody,
|
||||
ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
|
||||
|
||||
distanceJoint.Length = 0.01f;
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Barotrauma
|
||||
|
||||
private Vector2 prevPosition;
|
||||
|
||||
private float lastNetworkUpdate, networkUpdateTimer;
|
||||
private float networkUpdateTimer;
|
||||
|
||||
private EntityGrid entityGrid = null;
|
||||
|
||||
@@ -140,6 +140,11 @@ namespace Barotrauma
|
||||
get { return subBody; }
|
||||
}
|
||||
|
||||
public PhysicsBody PhysicsBody
|
||||
{
|
||||
get { return subBody.Body; }
|
||||
}
|
||||
|
||||
public Rectangle Borders
|
||||
{
|
||||
get
|
||||
@@ -289,6 +294,7 @@ namespace Barotrauma
|
||||
{
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void DrawFront(SpriteBatch spriteBatch, bool editing = false)
|
||||
@@ -298,6 +304,32 @@ namespace Barotrauma
|
||||
if (MapEntity.mapEntityList[i].DrawOverWater)
|
||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing, false);
|
||||
}
|
||||
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
if (sub.subBody.MemPos.Count < 2) continue;
|
||||
|
||||
Vector2 prevPos = ConvertUnits.ToDisplayUnits(sub.subBody.MemPos[0].Position);
|
||||
prevPos.Y = -prevPos.Y;
|
||||
|
||||
for (int i = 1; i < sub.subBody.MemPos.Count; i++)
|
||||
{
|
||||
Vector2 currPos = ConvertUnits.ToDisplayUnits(sub.subBody.MemPos[i].Position);
|
||||
currPos.Y = -currPos.Y;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)currPos.X - 10, (int)currPos.Y - 10, 20, 20), Color.Blue * 0.6f, true, 0.01f);
|
||||
GUI.DrawLine(spriteBatch, prevPos, currPos, Color.Cyan * 0.5f, 0, 5);
|
||||
|
||||
prevPos = currPos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawDamageable(SpriteBatch spriteBatch, Effect damageEffect, bool editing = false)
|
||||
@@ -530,9 +562,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
Vector2 pos = new Vector2(subBody.Position.X, subBody.Position.Y);
|
||||
SubmarineBody newSubBody = new SubmarineBody(this);
|
||||
GameMain.World.RemoveBody(subBody.Body);
|
||||
subBody = newSubBody;
|
||||
subBody.Body.Remove();
|
||||
subBody = new SubmarineBody(this);
|
||||
SetPosition(pos);
|
||||
|
||||
if (entityGrid != null)
|
||||
@@ -580,7 +611,7 @@ namespace Barotrauma
|
||||
if (this != MainSub && MainSub.DockedTo.Contains(this)) return;
|
||||
|
||||
//send updates more frequently if moving fast
|
||||
networkUpdateTimer -= MathHelper.Clamp(Velocity.Length(), 0.1f, 5.0f) * deltaTime;
|
||||
networkUpdateTimer -= MathHelper.Clamp(Velocity.Length()*10.0f, 0.1f, 5.0f) * deltaTime;
|
||||
|
||||
if (networkUpdateTimer < 0.0f)
|
||||
{
|
||||
@@ -651,12 +682,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (subBody == null) return false;
|
||||
|
||||
message.Write(subBody.Position.X);
|
||||
message.Write(subBody.Position.Y);
|
||||
|
||||
message.Write(Velocity.X);
|
||||
message.Write(Velocity.Y);
|
||||
|
||||
message.Write(PhysicsBody.SimPosition.X);
|
||||
message.Write(PhysicsBody.SimPosition.Y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -666,13 +694,13 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.Server != null) return false;
|
||||
|
||||
Vector2 newTargetPosition, newSpeed;
|
||||
|
||||
Vector2 newTargetPosition;
|
||||
try
|
||||
{
|
||||
if (sendingTime <= lastNetworkUpdate) return false;
|
||||
|
||||
newTargetPosition = new Vector2(message.ReadFloat(), message.ReadFloat());
|
||||
newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat());
|
||||
newTargetPosition = new Vector2(
|
||||
message.ReadFloat(),
|
||||
message.ReadFloat());
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
@@ -683,14 +711,21 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!newSpeed.IsValid() || !newTargetPosition.IsValid()) return false;
|
||||
if (!newTargetPosition.IsValid()) return false;
|
||||
|
||||
//newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime);
|
||||
//already interpolating with more up-to-date data -> ignore
|
||||
if (subBody.MemPos.Count > 1 && subBody.MemPos[0].Timestamp > sendingTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
subBody.TargetPosition = newTargetPosition;
|
||||
subBody.Velocity = newSpeed;
|
||||
int index = 0;
|
||||
while (index < subBody.MemPos.Count && sendingTime > subBody.MemPos[index].Timestamp)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
lastNetworkUpdate = sendingTime;
|
||||
subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.Right, sendingTime));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,12 +32,10 @@ namespace Barotrauma
|
||||
private float depthDamageTimer;
|
||||
|
||||
private readonly Submarine submarine;
|
||||
|
||||
public readonly Body Body;
|
||||
|
||||
private Vector2? targetPosition;
|
||||
public readonly PhysicsBody Body;
|
||||
|
||||
//private float mass = 10000.0f;
|
||||
List<PosInfo> memPos = new List<PosInfo>();
|
||||
|
||||
public Rectangle Borders
|
||||
{
|
||||
@@ -55,19 +53,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 TargetPosition
|
||||
{
|
||||
//get { return targetPosition.Value; }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(Body.Position); }
|
||||
get { return ConvertUnits.ToDisplayUnits(Body.SimPosition); }
|
||||
}
|
||||
|
||||
public List<PosInfo> MemPos
|
||||
{
|
||||
get { return memPos; }
|
||||
}
|
||||
|
||||
public bool AtDamageDepth
|
||||
@@ -79,10 +72,12 @@ namespace Barotrauma
|
||||
{
|
||||
this.submarine = sub;
|
||||
|
||||
Body farseerBody = null;
|
||||
|
||||
if (!Hull.hullList.Any())
|
||||
{
|
||||
|
||||
Body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f);
|
||||
Body = new PhysicsBody(1,1,1,1);
|
||||
farseerBody = Body.FarseerBody;
|
||||
DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed.");
|
||||
}
|
||||
else
|
||||
@@ -108,21 +103,20 @@ namespace Barotrauma
|
||||
(int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f),
|
||||
(int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f));
|
||||
|
||||
//var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit);
|
||||
|
||||
Body = BodyFactory.CreateBody(GameMain.World, this);
|
||||
farseerBody = BodyFactory.CreateBody(GameMain.World, this);
|
||||
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
{
|
||||
if (wall.Submarine != submarine) continue;
|
||||
|
||||
Rectangle rect = wall.Rect;
|
||||
|
||||
FixtureFactory.AttachRectangle(
|
||||
ConvertUnits.ToSimUnits(rect.Width),
|
||||
ConvertUnits.ToSimUnits(rect.Height),
|
||||
50.0f,
|
||||
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
|
||||
Body, this);
|
||||
farseerBody, this);
|
||||
}
|
||||
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
@@ -135,30 +129,32 @@ namespace Barotrauma
|
||||
ConvertUnits.ToSimUnits(rect.Height),
|
||||
5.0f,
|
||||
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
|
||||
Body, this);
|
||||
farseerBody, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Body.BodyType = BodyType.Dynamic;
|
||||
Body.CollisionCategories = Physics.CollisionWall;
|
||||
Body.CollidesWith =
|
||||
farseerBody.BodyType = BodyType.Dynamic;
|
||||
farseerBody.CollisionCategories = Physics.CollisionWall;
|
||||
farseerBody.CollidesWith =
|
||||
Physics.CollisionItem |
|
||||
Physics.CollisionLevel |
|
||||
Physics.CollisionCharacter |
|
||||
Physics.CollisionProjectile |
|
||||
Physics.CollisionWall;
|
||||
|
||||
Body.Restitution = Restitution;
|
||||
Body.Friction = Friction;
|
||||
Body.FixedRotation = true;
|
||||
farseerBody.Restitution = Restitution;
|
||||
farseerBody.Friction = Friction;
|
||||
farseerBody.FixedRotation = true;
|
||||
//mass = Body.Mass;
|
||||
Body.Awake = true;
|
||||
Body.SleepingAllowed = false;
|
||||
Body.IgnoreGravity = true;
|
||||
Body.OnCollision += OnCollision;
|
||||
Body.UserData = submarine;
|
||||
farseerBody.Awake = true;
|
||||
farseerBody.SleepingAllowed = false;
|
||||
farseerBody.IgnoreGravity = true;
|
||||
farseerBody.OnCollision += OnCollision;
|
||||
farseerBody.UserData = submarine;
|
||||
|
||||
Body = new PhysicsBody(farseerBody);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,59 +183,66 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (targetPosition != null && targetPosition != Position)
|
||||
{
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
float dist = Vector2.Distance((Vector2)targetPosition, Position);
|
||||
//if (memPos.Count > 1 && Vector2.Distance(memPos[1].Position, Body.SimPosition) > 5.0f)
|
||||
//{
|
||||
// Vector2 moveAmount = ConvertUnits.ToDisplayUnits(memPos[1].Position - Body.SimPosition);
|
||||
|
||||
// ForceTranslate(moveAmount);
|
||||
// DisplaceCharacters(moveAmount);
|
||||
|
||||
// foreach (Submarine sub in submarine.DockedTo)
|
||||
// {
|
||||
// sub.SubBody.ForceTranslate(moveAmount);
|
||||
// sub.SubBody.DisplaceCharacters(moveAmount);
|
||||
// }
|
||||
|
||||
// memPos.RemoveRange(0, 2);
|
||||
//}
|
||||
//else
|
||||
|
||||
if (dist > 500.0f) //immediately snap the sub to the target position if more than 500.0f units away
|
||||
Vector2 newVelocity = Body.LinearVelocity;
|
||||
Vector2 newPosition = Body.SimPosition;
|
||||
|
||||
Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition);
|
||||
Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition);
|
||||
|
||||
List<Submarine> subsToMove = new List<Submarine>() { this.submarine };
|
||||
subsToMove.AddRange(submarine.DockedTo);
|
||||
|
||||
Submarine closestSub = null;
|
||||
if (Character.Controlled == null)
|
||||
{
|
||||
Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(Body.Position);
|
||||
|
||||
List<SubmarineBody> dockedBodies = new List<SubmarineBody>() { this };
|
||||
submarine.DockedTo.ForEach(d => dockedBodies.Add(d.SubBody));
|
||||
|
||||
foreach (SubmarineBody dockedBody in dockedBodies)
|
||||
{
|
||||
dockedBody.ForceTranslate(moveAmount);
|
||||
|
||||
if ((Character.Controlled != null && Character.Controlled.Submarine == dockedBody.submarine) ||
|
||||
(Character.Controlled == null && Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == dockedBody.submarine))
|
||||
{
|
||||
GameMain.GameScreen.Cam.UpdateTransform(false);
|
||||
}
|
||||
|
||||
dockedBody.submarine.SetPrevTransform(dockedBody.submarine.Position);
|
||||
dockedBody.submarine.UpdateTransform();
|
||||
targetPosition = null;
|
||||
|
||||
dockedBody.DisplaceCharacters(moveAmount);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (dist > 50.0f) //lerp the position if (50 < dist < 500)
|
||||
{
|
||||
Vector2 moveAmount = Vector2.Normalize((Vector2)targetPosition - Position);
|
||||
moveAmount *= Math.Min(dist, 100.0f);
|
||||
|
||||
ForceTranslate(moveAmount * deltaTime);
|
||||
|
||||
foreach (Submarine sub in submarine.DockedTo)
|
||||
{
|
||||
sub.SubBody.ForceTranslate(moveAmount * deltaTime);
|
||||
}
|
||||
closestSub= Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetPosition = null;
|
||||
closestSub = Character.Controlled.Submarine;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetPosition = null;
|
||||
}
|
||||
|
||||
bool displace = moveAmount.Length() > 100.0f;
|
||||
|
||||
foreach (Submarine sub in subsToMove)
|
||||
{
|
||||
sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);
|
||||
sub.PhysicsBody.LinearVelocity = newVelocity;
|
||||
|
||||
if (displace) sub.SubBody.DisplaceCharacters(moveAmount);
|
||||
}
|
||||
|
||||
if (closestSub != null && subsToMove.Contains(closestSub))
|
||||
{
|
||||
GameMain.GameScreen.Cam.Position += moveAmount;
|
||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += moveAmount;
|
||||
|
||||
if (Character.Controlled!=null) Character.Controlled.CursorPosition += moveAmount;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
|
||||
Vector2 totalForce = CalculateBuoyancy();
|
||||
@@ -258,51 +261,22 @@ namespace Barotrauma
|
||||
|
||||
UpdateDepthDamage(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Immediately translates the position of the physics body, gamescreen camera and Character.Controlled.CursorPosition
|
||||
/// </summary>
|
||||
/// <param name="amount">Amount to move in display units</param>
|
||||
private void ForceTranslate(Vector2 amount)
|
||||
{
|
||||
Body.SetTransform(Body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
||||
|
||||
bool isClosestSub = false;
|
||||
if (Character.Controlled == null)
|
||||
{
|
||||
isClosestSub = Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine;
|
||||
}
|
||||
else
|
||||
{
|
||||
isClosestSub = Character.Controlled.Submarine == submarine;
|
||||
|
||||
Character.Controlled.CursorPosition += amount;
|
||||
}
|
||||
|
||||
if (isClosestSub)
|
||||
{
|
||||
GameMain.GameScreen.Cam.Position += amount;
|
||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Moves away any character that is inside the bounding box of the sub (but not inside it)
|
||||
/// Moves away any character that is inside the bounding box of the sub (but not inside the sub)
|
||||
/// </summary>
|
||||
/// <param name="subTranslation">The translation that was applied to the sub before doing the displacement
|
||||
/// (used for determining where to push the characters)</param>
|
||||
private void DisplaceCharacters(Vector2 subTranslation)
|
||||
{
|
||||
Rectangle worldBorders = Borders;
|
||||
worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.Position).ToPoint();
|
||||
worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.SimPosition).ToPoint();
|
||||
|
||||
Vector2 translateDir = Vector2.Normalize(subTranslation);
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.AnimController.CurrentHull != null) continue;
|
||||
if (c.AnimController.CurrentHull != null && c.AnimController.CanEnterSubmarine) continue;
|
||||
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
@@ -317,7 +291,7 @@ namespace Barotrauma
|
||||
//should never be null when casting a line out from inside the bounding box
|
||||
Debug.Assert(intersection != null);
|
||||
|
||||
//\"+ translatedir\" in order to move the character slightly away from the wall
|
||||
//"+ translatedir" in order to move the character slightly away from the wall
|
||||
c.AnimController.SetPosition(ConvertUnits.ToSimUnits(c.WorldPosition + ((Vector2)intersection - limb.WorldPosition)) + translateDir);
|
||||
|
||||
return;
|
||||
@@ -342,8 +316,6 @@ namespace Barotrauma
|
||||
|
||||
float neutralPercentage = 0.07f;
|
||||
|
||||
Body.IgnoreGravity = true;
|
||||
|
||||
float buoyancy = neutralPercentage - waterPercentage;
|
||||
|
||||
if (buoyancy > 0.0f) buoyancy *= 2.0f;
|
||||
@@ -367,58 +339,25 @@ namespace Barotrauma
|
||||
|
||||
float depth = DamageDepth - Position.Y;
|
||||
|
||||
// float prevTimer = depthDamageTimer;
|
||||
|
||||
depthDamageTimer -= deltaTime;
|
||||
|
||||
//if (prevTimer>5.0f && depthDamageTimer<=5.0f)
|
||||
//{
|
||||
// SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f,);
|
||||
//}
|
||||
|
||||
if (depthDamageTimer > 0.0f) return;
|
||||
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
{
|
||||
if (wall.Submarine != submarine) continue;
|
||||
//if (Rand.Int(5) < 4) continue;
|
||||
|
||||
if (wall.Health < depth*0.01f)
|
||||
if (wall.Health < depth * 0.01f)
|
||||
{
|
||||
Explosion.RangedStructureDamage(wall.WorldPosition, 100.0f, depth*0.01f);
|
||||
Explosion.RangedStructureDamage(wall.WorldPosition, 100.0f, depth * 0.01f);
|
||||
|
||||
if (Character.Controlled != null && Character.Controlled.Submarine == submarine)
|
||||
{
|
||||
GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, Math.Min(depth *0.001f, 50.0f));
|
||||
GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, Math.Min(depth * 0.001f, 50.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Vector2 damagePos = Vector2.Zero;
|
||||
//if (Rand.Int(2)==0)
|
||||
//{
|
||||
// damagePos = new Vector2(
|
||||
// (Rand.Int(2) == 0) ? Borders.X : Borders.X+Borders.Width,
|
||||
// Rand.Range(Borders.Y - Borders.Height, Borders.Y));
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// damagePos = new Vector2(
|
||||
// Rand.Range(Borders.X, Borders.X + Borders.Width),
|
||||
// (Rand.Int(2) == 0) ? Borders.Y : Borders.Y - Borders.Height);
|
||||
//}
|
||||
|
||||
//damagePos += submarine.Position + submarine.HiddenSubPosition;
|
||||
//SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f, damagePos, 10000.0f);
|
||||
|
||||
//if (Character.Controlled != null && Character.Controlled.Submarine == submarine)
|
||||
//{
|
||||
// GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f;
|
||||
//}
|
||||
|
||||
//Explosion.RangedStructureDamage(damagePos, depth * PressureDamageMultiplier * 50.0f, depth * PressureDamageMultiplier);
|
||||
//SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, Rand.Range(0.0f, 100.0f), damagePos, 5000.0f);
|
||||
|
||||
depthDamageTimer = 10.0f;
|
||||
}
|
||||
|
||||
@@ -432,7 +371,7 @@ namespace Barotrauma
|
||||
|
||||
if (collision && limb.Mass > 100.0f)
|
||||
{
|
||||
Vector2 normal = Vector2.Normalize(Body.Position - limb.SimPosition);
|
||||
Vector2 normal = Vector2.Normalize(Body.SimPosition - limb.SimPosition);
|
||||
|
||||
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f;
|
||||
|
||||
@@ -445,7 +384,7 @@ namespace Barotrauma
|
||||
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
|
||||
if (cell != null)
|
||||
{
|
||||
var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.Position) - cell.Center);
|
||||
var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center);
|
||||
|
||||
float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
|
||||
|
||||
@@ -474,7 +413,7 @@ namespace Barotrauma
|
||||
Vector2 normal;
|
||||
FixedArray2<Vector2> points;
|
||||
contact.GetWorldManifold(out normal, out points);
|
||||
if (contact.FixtureA.Body == sub.SubBody.Body)
|
||||
if (contact.FixtureA.Body == sub.SubBody.Body.FarseerBody)
|
||||
{
|
||||
normal = -normal;
|
||||
}
|
||||
|
||||
@@ -271,6 +271,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
|
||||
new GUIMessageBox("Connection timed out", "You were disconnected for too long and your character was deleted. Please wait for another round to start.");
|
||||
myCharacter = null;
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.ClearPlayers();
|
||||
|
||||
@@ -231,8 +231,8 @@ namespace Barotrauma.Networking
|
||||
if (updateReturnTimer > 10.0f)
|
||||
{
|
||||
updateReturnTimer = 0.0f;
|
||||
|
||||
respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
|
||||
respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
|
||||
shuttleSteering.AutoPilot = true;
|
||||
shuttleSteering.MaintainPos = false;
|
||||
@@ -302,7 +302,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
|
||||
{
|
||||
respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
|
||||
while (Math.Abs(position.Y - respawnShuttle.WorldPosition.Y) > 100.0f)
|
||||
{
|
||||
@@ -313,7 +313,7 @@ namespace Barotrauma.Networking
|
||||
if (respawnShuttle.SubBody == null) yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
@@ -378,7 +378,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
respawnShuttle.Velocity = Vector2.Zero;
|
||||
|
||||
respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.ShaftBody);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,35 @@ using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
struct PosInfo
|
||||
{
|
||||
public readonly Vector2 Position;
|
||||
public readonly Direction Direction;
|
||||
|
||||
public readonly float Timestamp;
|
||||
public readonly UInt32 ID;
|
||||
|
||||
public PosInfo(Vector2 pos, Direction dir, float time)
|
||||
{
|
||||
Position = pos;
|
||||
Direction = dir;
|
||||
Timestamp = time;
|
||||
|
||||
ID = 0;
|
||||
}
|
||||
|
||||
public PosInfo(Vector2 pos, Direction dir, UInt32 ID)
|
||||
{
|
||||
Position = pos;
|
||||
Direction = dir;
|
||||
this.ID = ID;
|
||||
|
||||
Timestamp = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
class PhysicsBody
|
||||
{
|
||||
|
||||
public enum Shape
|
||||
{
|
||||
Circle, Rectangle, Capsule
|
||||
@@ -70,18 +96,7 @@ namespace Barotrauma
|
||||
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
//public Vector2 TargetVelocity
|
||||
//{
|
||||
// get { return targetVelocity; }
|
||||
// set
|
||||
// {
|
||||
// if (!MathUtils.IsValid(value)) return;
|
||||
// targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||
// targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
public float TargetRotation
|
||||
{
|
||||
get { return targetRotation; }
|
||||
@@ -92,16 +107,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
//public float TargetAngularVelocity
|
||||
//{
|
||||
// get { return targetAngularVelocity; }
|
||||
// set
|
||||
// {
|
||||
// if (!MathUtils.IsValid(value)) return;
|
||||
// targetAngularVelocity = value;
|
||||
// }
|
||||
//}
|
||||
|
||||
public Vector2 DrawPosition
|
||||
{
|
||||
get { return Submarine == null ? drawPosition : drawPosition + Submarine.DrawPosition; }
|
||||
@@ -223,6 +228,16 @@ namespace Barotrauma
|
||||
list.Add(this);
|
||||
}
|
||||
|
||||
public PhysicsBody(Body farseerBody)
|
||||
{
|
||||
body = farseerBody;
|
||||
body.UserData = this;
|
||||
|
||||
LastSentPosition = body.Position;
|
||||
|
||||
list.Add(this);
|
||||
}
|
||||
|
||||
public PhysicsBody(XElement element, Vector2 position, float scale=1.0f)
|
||||
{
|
||||
float radius = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "radius", 0.0f)) * scale;
|
||||
@@ -464,35 +479,42 @@ namespace Barotrauma
|
||||
|
||||
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity)
|
||||
{
|
||||
newVelocity = Vector2.Zero;
|
||||
if (positionBuffer.Count < 2) return;
|
||||
Vector2 newPosition = SimPosition;
|
||||
CorrectPosition(positionBuffer, deltaTime, out newVelocity, out newPosition);
|
||||
|
||||
SetTransform(newPosition, Rotation);
|
||||
}
|
||||
|
||||
|
||||
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity, out Vector2 newPosition)
|
||||
{
|
||||
newVelocity = Vector2.Zero;
|
||||
newPosition = SimPosition;
|
||||
|
||||
if (positionBuffer.Count < 2) return;
|
||||
|
||||
PosInfo prev = positionBuffer[0];
|
||||
PosInfo next = positionBuffer[1];
|
||||
|
||||
Vector2 currPos = SimPosition;
|
||||
|
||||
|
||||
//interpolate the position of the collider from the first position in the buffer towards the second
|
||||
if (prev.Timestamp < next.Timestamp)
|
||||
{
|
||||
//if there are more than 2 positions in the buffer,
|
||||
//increase the interpolation speed to catch up with the server
|
||||
float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f);
|
||||
float speedMultiplier = 0.9f + (float)Math.Pow((positionBuffer.Count - 2) / 5.0f, 2.0f);
|
||||
|
||||
netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
|
||||
currPos = Vector2.Lerp(prev.Position, next.Position, netInterpolationState);
|
||||
newPosition = Vector2.Lerp(prev.Position, next.Position, netInterpolationState);
|
||||
|
||||
//override the targetMovement to make the character play the walking/running animation
|
||||
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
currPos = next.Position;
|
||||
newPosition = next.Position;
|
||||
netInterpolationState = 1.0f;
|
||||
}
|
||||
|
||||
SetTransform(currPos, Rotation);
|
||||
|
||||
if (netInterpolationState >= 1.0f)
|
||||
{
|
||||
netInterpolationState = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user