Merge branch 'master' into animcontroller-overhaul

Conflicts:
	Subsurface/Content/Characters/Crawler/crawler.xml
	Subsurface/Source/Characters/AICharacter.cs
	Subsurface/Source/Characters/Animation/FishAnimController.cs
	Subsurface/Source/Characters/Animation/Ragdoll.cs
	Subsurface/Source/Characters/Character.cs
	Subsurface/Source/Map/Submarine.cs
	Subsurface/Source/Map/SubmarineBody.cs
	Subsurface/Source/Networking/GameClient.cs
	Subsurface/Source/Networking/GameServer.cs
	Subsurface/Source/Physics/PhysicsBody.cs
This commit is contained in:
Regalis
2016-10-25 20:09:25 +03:00
17 changed files with 243 additions and 261 deletions
@@ -8,7 +8,7 @@
<ragdoll headposition="50" headangle="-70" <ragdoll headposition="50" headangle="-70"
waveamplitude="2.0" wavelength="5000" waveamplitude="2.0" wavelength="5000"
swimspeed="2.0" walkspeed="2.0" swimspeed="3.0" walkspeed="2.0"
stepsize ="15.0,20.0" stepsize ="15.0,20.0"
legtorque="10" legtorque="10"
flip="true"> flip="true">
@@ -5,7 +5,7 @@
<sound file="Content/Characters/Endworm/endwormattack1.ogg" state="Attack" range="8000" /> <sound file="Content/Characters/Endworm/endwormattack1.ogg" state="Attack" range="8000" />
<sound file="Content/Characters/Endworm/endwormattack2.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"/> <collider radius="300"/>
@@ -6,7 +6,7 @@
<sound file="Content/Characters/Moloch/idle1.ogg" state="None" range="3000"/> <sound file="Content/Characters/Moloch/idle1.ogg" state="None" range="3000"/>
<sound file="Content/Characters/Moloch/idle2.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"/> <collider radius ="230"/>
@@ -195,6 +195,8 @@ namespace Barotrauma
for (int i = 0; i < Limbs.Count(); i++) 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; 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); Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
@@ -64,14 +64,14 @@ namespace Barotrauma
var wayPoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine==null); var wayPoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine==null);
if (wayPoints.Any()) if (wayPoints.Any())
{ {
WayPoint wp = wayPoints[Rand.Int(wayPoints.Count)]; WayPoint wp = wayPoints[Rand.Int(wayPoints.Count, false)];
pos = new Vector2(wp.Rect.X, wp.Rect.Y); pos = new Vector2(wp.Rect.X, wp.Rect.Y);
pos += Rand.Vector(200.0f); pos += Rand.Vector(200.0f, false);
} }
else else
{ {
pos = Rand.Vector(2000.0f); pos = Rand.Vector(2000.0f, false);
} }
} }
else else
@@ -80,9 +80,9 @@ namespace Barotrauma
} }
var prefab = prefabs[Rand.Int(prefabs.Count)]; var prefab = prefabs[Rand.Int(prefabs.Count, false)];
int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax); int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax, false);
List<BackgroundCreature> swarmMembers = new List<BackgroundCreature>(); List<BackgroundCreature> swarmMembers = new List<BackgroundCreature>();
for (int n = 0; n < amount; n++) for (int n = 0; n < amount; n++)
-27
View File
@@ -14,33 +14,6 @@ using System.Xml.Linq;
namespace Barotrauma 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, IClientSerializable, IServerSerializable class Character : Entity, IDamageable, IPropertyObject, IClientSerializable, IServerSerializable
{ {
public static List<Character> CharacterList = new List<Character>(); public static List<Character> CharacterList = new List<Character>();
@@ -53,7 +53,7 @@ namespace Barotrauma
return; return;
} }
WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub); WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, true);
if (cargoSpawnPos==null) if (cargoSpawnPos==null)
{ {
DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found"); DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found");
@@ -214,7 +214,7 @@ namespace Barotrauma.Items.Components
if (useWeldJoint) if (useWeldJoint)
{ {
joint = JointFactory.CreateWeldJoint(GameMain.World, 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); ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
((WeldJoint)joint).FrequencyHz = 1.0f; ((WeldJoint)joint).FrequencyHz = 1.0f;
@@ -222,7 +222,7 @@ namespace Barotrauma.Items.Components
else else
{ {
var distanceJoint = JointFactory.CreateDistanceJoint(GameMain.World, 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); ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
distanceJoint.Length = 0.01f; distanceJoint.Length = 0.01f;
+1 -1
View File
@@ -201,7 +201,7 @@ namespace Barotrauma
{ {
rect = rectangle; rect = rectangle;
OxygenPercentage = Rand.Range(90.0f, 100.0f, false); OxygenPercentage = 100.0f;
fireSources = new List<FireSource>(); fireSources = new List<FireSource>();
+13 -13
View File
@@ -328,22 +328,22 @@ namespace Barotrauma.Lights
hullAmbientLight.Add(hull, currColor); hullAmbientLight.Add(hull, currColor);
} }
Color nextHullLight = currColor * AmbientLightFalloff;
//light getting too dark to notice -> no need to spread further
if (nextHullLight.A < 20) return hullAmbientLight;
//use hashset to make sure that each hull is only included once
HashSet<Hull> hulls = new HashSet<Hull>();
foreach (Gap g in hull.ConnectedGaps) foreach (Gap g in hull.ConnectedGaps)
{ {
for (int i = 0; i < g.linkedTo.Count;i++ ) if (!g.IsRoomToRoom || !g.PassAmbientLight || g.Open < 0.5f) continue;
{
if (g.linkedTo[i] is Hull) hulls.Add((g.linkedTo[0] == hull ? g.linkedTo[1] : g.linkedTo[0]) as Hull);
{ }
if (g.linkedTo[i] == hull) continue;
Color nextHullLight = currColor * AmbientLightFalloff; foreach (Hull h in hulls)
if (!g.PassAmbientLight) nextHullLight *= g.Open; {
hullAmbientLight = AmbientLightHulls(h, hullAmbientLight, nextHullLight);
if (nextHullLight.A < 10) continue;
hullAmbientLight = AmbientLightHulls((Hull)g.linkedTo[i], hullAmbientLight, nextHullLight);
}
}
} }
return hullAmbientLight; return hullAmbientLight;
+57 -13
View File
@@ -76,7 +76,7 @@ namespace Barotrauma
private Vector2 prevPosition; private Vector2 prevPosition;
private float lastNetworkUpdate, networkUpdateTimer; private float networkUpdateTimer;
private EntityGrid entityGrid = null; private EntityGrid entityGrid = null;
@@ -150,6 +150,11 @@ namespace Barotrauma
get { return subBody; } get { return subBody; }
} }
public PhysicsBody PhysicsBody
{
get { return subBody.Body; }
}
public Rectangle Borders public Rectangle Borders
{ {
get get
@@ -299,6 +304,7 @@ namespace Barotrauma
{ {
MapEntity.mapEntityList[i].Draw(spriteBatch, editing); MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
} }
} }
public static void DrawFront(SpriteBatch spriteBatch, bool editing = false) public static void DrawFront(SpriteBatch spriteBatch, bool editing = false)
@@ -308,6 +314,32 @@ namespace Barotrauma
if (MapEntity.mapEntityList[i].DrawOverWater) if (MapEntity.mapEntityList[i].DrawOverWater)
MapEntity.mapEntityList[i].Draw(spriteBatch, editing, false); 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) public static void DrawDamageable(SpriteBatch spriteBatch, Effect damageEffect, bool editing = false)
@@ -540,9 +572,8 @@ namespace Barotrauma
} }
Vector2 pos = new Vector2(subBody.Position.X, subBody.Position.Y); Vector2 pos = new Vector2(subBody.Position.X, subBody.Position.Y);
SubmarineBody newSubBody = new SubmarineBody(this); subBody.Body.Remove();
GameMain.World.RemoveBody(subBody.Body); subBody = new SubmarineBody(this);
subBody = newSubBody;
SetPosition(pos); SetPosition(pos);
if (entityGrid != null) if (entityGrid != null)
@@ -590,7 +621,7 @@ namespace Barotrauma
if (this != MainSub && MainSub.DockedTo.Contains(this)) return; if (this != MainSub && MainSub.DockedTo.Contains(this)) return;
//send updates more frequently if moving fast //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) if (networkUpdateTimer < 0.0f)
{ {
@@ -655,7 +686,7 @@ namespace Barotrauma
return closest; return closest;
} }
//saving/loading ---------------------------------------------------- //saving/loading ----------------------------------------------------
public bool Save() public bool Save()
@@ -1080,17 +1111,30 @@ namespace Barotrauma
public void ServerWrite(NetOutgoingMessage msg, Client c) public void ServerWrite(NetOutgoingMessage msg, Client c)
{ {
msg.Write(subBody.Position.X); msg.Write(PhysicsBody.SimPosition.X);
msg.Write(subBody.Position.Y); msg.Write(PhysicsBody.SimPosition.Y);
msg.Write(Velocity.X);
msg.Write(Velocity.Y);
} }
public void ClientRead(NetIncomingMessage msg, float sendingTime) public void ClientRead(NetIncomingMessage msg, float sendingTime)
{ {
subBody.TargetPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle()); var newTargetPosition = new Vector2(
subBody.Velocity = new Vector2(msg.ReadSingle(), msg.ReadSingle()); msg.ReadFloat(),
msg.ReadFloat());
//already interpolating with more up-to-date data -> ignore
if (subBody.MemPos.Count > 1 && subBody.MemPos[0].Timestamp > sendingTime)
{
return;
}
int index = 0;
while (index < subBody.MemPos.Count && sendingTime > subBody.MemPos[index].Timestamp)
{
index++;
}
subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.Right, sendingTime));
} }
} }
+93 -152
View File
@@ -32,10 +32,10 @@ namespace Barotrauma
private float depthDamageTimer; private float depthDamageTimer;
private readonly Submarine submarine; private readonly Submarine submarine;
public readonly Body Body;
private Vector2? targetPosition; public readonly PhysicsBody Body;
List<PosInfo> memPos = new List<PosInfo>();
public Rectangle Borders public Rectangle Borders
{ {
@@ -53,19 +53,14 @@ namespace Barotrauma
} }
} }
public Vector2 TargetPosition
{
//get { return targetPosition.Value; }
set
{
if (!MathUtils.IsValid(value)) return;
targetPosition = value;
}
}
public Vector2 Position 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 public bool AtDamageDepth
@@ -77,10 +72,12 @@ namespace Barotrauma
{ {
this.submarine = sub; this.submarine = sub;
Body farseerBody = null;
if (!Hull.hullList.Any()) if (!Hull.hullList.Any())
{ {
Body = new PhysicsBody(1,1,1,1);
Body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f); farseerBody = Body.FarseerBody;
DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed."); DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed.");
} }
else else
@@ -106,21 +103,20 @@ namespace Barotrauma
(int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f), (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f),
(int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f)); (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f));
//var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit); farseerBody = BodyFactory.CreateBody(GameMain.World, this);
Body = BodyFactory.CreateBody(GameMain.World, this);
foreach (Structure wall in Structure.WallList) foreach (Structure wall in Structure.WallList)
{ {
if (wall.Submarine != submarine) continue; if (wall.Submarine != submarine) continue;
Rectangle rect = wall.Rect; Rectangle rect = wall.Rect;
FixtureFactory.AttachRectangle( FixtureFactory.AttachRectangle(
ConvertUnits.ToSimUnits(rect.Width), ConvertUnits.ToSimUnits(rect.Width),
ConvertUnits.ToSimUnits(rect.Height), ConvertUnits.ToSimUnits(rect.Height),
50.0f, 50.0f,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)), ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
Body, this); farseerBody, this);
} }
foreach (Hull hull in Hull.hullList) foreach (Hull hull in Hull.hullList)
@@ -133,30 +129,32 @@ namespace Barotrauma
ConvertUnits.ToSimUnits(rect.Height), ConvertUnits.ToSimUnits(rect.Height),
5.0f, 5.0f,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)), ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
Body, this); farseerBody, this);
} }
} }
Body.BodyType = BodyType.Dynamic; farseerBody.BodyType = BodyType.Dynamic;
Body.CollisionCategories = Physics.CollisionWall; farseerBody.CollisionCategories = Physics.CollisionWall;
Body.CollidesWith = farseerBody.CollidesWith =
Physics.CollisionItem | Physics.CollisionItem |
Physics.CollisionLevel | Physics.CollisionLevel |
Physics.CollisionCharacter | Physics.CollisionCharacter |
Physics.CollisionProjectile | Physics.CollisionProjectile |
Physics.CollisionWall; Physics.CollisionWall;
Body.Restitution = Restitution; farseerBody.Restitution = Restitution;
Body.Friction = Friction; farseerBody.Friction = Friction;
Body.FixedRotation = true; farseerBody.FixedRotation = true;
//mass = Body.Mass; //mass = Body.Mass;
Body.Awake = true; farseerBody.Awake = true;
Body.SleepingAllowed = false; farseerBody.SleepingAllowed = false;
Body.IgnoreGravity = true; farseerBody.IgnoreGravity = true;
Body.OnCollision += OnCollision; farseerBody.OnCollision += OnCollision;
Body.UserData = submarine; farseerBody.UserData = submarine;
Body = new PhysicsBody(farseerBody);
} }
@@ -185,59 +183,66 @@ namespace Barotrauma
} }
public void Update(float deltaTime) 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); closestSub= Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter);
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);
}
} }
else 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(); Vector2 totalForce = CalculateBuoyancy();
@@ -256,51 +261,22 @@ namespace Barotrauma
UpdateDepthDamage(deltaTime); UpdateDepthDamage(deltaTime);
} }
/// <summary> /// <summary>
/// Immediately translates the position of the physics body, gamescreen camera and Character.Controlled.CursorPosition /// Moves away any character that is inside the bounding box of the sub (but not inside the sub)
/// </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)
/// </summary> /// </summary>
/// <param name="subTranslation">The translation that was applied to the sub before doing the displacement /// <param name="subTranslation">The translation that was applied to the sub before doing the displacement
/// (used for determining where to push the characters)</param> /// (used for determining where to push the characters)</param>
private void DisplaceCharacters(Vector2 subTranslation) private void DisplaceCharacters(Vector2 subTranslation)
{ {
Rectangle worldBorders = Borders; Rectangle worldBorders = Borders;
worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.Position).ToPoint(); worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.SimPosition).ToPoint();
Vector2 translateDir = Vector2.Normalize(subTranslation); Vector2 translateDir = Vector2.Normalize(subTranslation);
foreach (Character c in Character.CharacterList) 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) foreach (Limb limb in c.AnimController.Limbs)
{ {
@@ -315,7 +291,7 @@ namespace Barotrauma
//should never be null when casting a line out from inside the bounding box //should never be null when casting a line out from inside the bounding box
Debug.Assert(intersection != null); 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); c.AnimController.SetPosition(ConvertUnits.ToSimUnits(c.WorldPosition + ((Vector2)intersection - limb.WorldPosition)) + translateDir);
return; return;
@@ -340,8 +316,6 @@ namespace Barotrauma
float neutralPercentage = 0.07f; float neutralPercentage = 0.07f;
Body.IgnoreGravity = true;
float buoyancy = neutralPercentage - waterPercentage; float buoyancy = neutralPercentage - waterPercentage;
if (buoyancy > 0.0f) buoyancy *= 2.0f; if (buoyancy > 0.0f) buoyancy *= 2.0f;
@@ -365,58 +339,25 @@ namespace Barotrauma
float depth = DamageDepth - Position.Y; float depth = DamageDepth - Position.Y;
// float prevTimer = depthDamageTimer;
depthDamageTimer -= deltaTime; depthDamageTimer -= deltaTime;
//if (prevTimer>5.0f && depthDamageTimer<=5.0f)
//{
// SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f,);
//}
if (depthDamageTimer > 0.0f) return; if (depthDamageTimer > 0.0f) return;
foreach (Structure wall in Structure.WallList) foreach (Structure wall in Structure.WallList)
{ {
if (wall.Submarine != submarine) continue; 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) 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; depthDamageTimer = 10.0f;
} }
@@ -430,7 +371,7 @@ namespace Barotrauma
if (collision && limb.Mass > 100.0f) 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; float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f;
@@ -443,7 +384,7 @@ namespace Barotrauma
VoronoiCell cell = f2.Body.UserData as VoronoiCell; VoronoiCell cell = f2.Body.UserData as VoronoiCell;
if (cell != null) 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); float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
@@ -472,7 +413,7 @@ namespace Barotrauma
Vector2 normal; Vector2 normal;
FixedArray2<Vector2> points; FixedArray2<Vector2> points;
contact.GetWorldManifold(out normal, out points); contact.GetWorldManifold(out normal, out points);
if (contact.FixtureA.Body == sub.SubBody.Body) if (contact.FixtureA.Body == sub.SubBody.Body.FarseerBody)
{ {
normal = -normal; normal = -normal;
} }
+2 -2
View File
@@ -636,7 +636,7 @@ namespace Barotrauma
if (!wayPoint2.linkedTo.Contains(this)) wayPoint2.linkedTo.Add(this); if (!wayPoint2.linkedTo.Contains(this)) wayPoint2.linkedTo.Add(this);
} }
public static WayPoint GetRandom(SpawnType spawnType = SpawnType.Human, Job assignedJob = null, Submarine sub = null) public static WayPoint GetRandom(SpawnType spawnType = SpawnType.Human, Job assignedJob = null, Submarine sub = null, bool useSyncedRand = false)
{ {
List<WayPoint> wayPoints = new List<WayPoint>(); List<WayPoint> wayPoints = new List<WayPoint>();
@@ -651,7 +651,7 @@ namespace Barotrauma
if (!wayPoints.Any()) return null; if (!wayPoints.Any()) return null;
return wayPoints[Rand.Int(wayPoints.Count(), false)]; return wayPoints[Rand.Int(wayPoints.Count, !useSyncedRand)];
} }
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine) public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine)
+1 -1
View File
@@ -431,7 +431,7 @@ namespace Barotrauma.Networking
if (!(c is AICharacter) || c.IsDead) continue; if (!(c is AICharacter) || c.IsDead) continue;
if (Character.CharacterList.Any( if (Character.CharacterList.Any(
c2 => c2.IsNetworkPlayer && c2 => c2.IsRemotePlayer &&
Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance)) Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance))
{ {
@@ -229,8 +229,8 @@ namespace Barotrauma.Networking
if (updateReturnTimer > 10.0f) if (updateReturnTimer > 10.0f)
{ {
updateReturnTimer = 0.0f; updateReturnTimer = 0.0f;
respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBody); respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.ShaftBody);
shuttleSteering.AutoPilot = true; shuttleSteering.AutoPilot = true;
shuttleSteering.MaintainPos = false; shuttleSteering.MaintainPos = false;
@@ -298,7 +298,7 @@ namespace Barotrauma.Networking
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed) 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) while (Math.Abs(position.Y - respawnShuttle.WorldPosition.Y) > 100.0f)
{ {
@@ -309,7 +309,7 @@ namespace Barotrauma.Networking
if (respawnShuttle.SubBody == null) yield return CoroutineStatus.Success; 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; yield return CoroutineStatus.Success;
} }
@@ -374,7 +374,7 @@ namespace Barotrauma.Networking
respawnShuttle.Velocity = Vector2.Zero; respawnShuttle.Velocity = Vector2.Zero;
respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBody); respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.ShaftBody);
} }
+54 -34
View File
@@ -11,9 +11,35 @@ using System;
namespace Barotrauma 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 class PhysicsBody
{ {
public enum Shape public enum Shape
{ {
Circle, Rectangle, Capsule Circle, Rectangle, Capsule
@@ -70,18 +96,7 @@ namespace Barotrauma
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f); 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 public float TargetRotation
{ {
get { return 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 public Vector2 DrawPosition
{ {
get { return Submarine == null ? drawPosition : drawPosition + Submarine.DrawPosition; } get { return Submarine == null ? drawPosition : drawPosition + Submarine.DrawPosition; }
@@ -225,6 +230,16 @@ namespace Barotrauma
list.Add(this); 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) public PhysicsBody(XElement element, Vector2 position, float scale=1.0f)
{ {
float radius = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "radius", 0.0f)) * scale; float radius = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "radius", 0.0f)) * scale;
@@ -466,14 +481,23 @@ namespace Barotrauma
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity) public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity)
{ {
newVelocity = Vector2.Zero; Vector2 newPosition = SimPosition;
if (positionBuffer.Count < 2) return; 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 prev = positionBuffer[0];
PosInfo next = positionBuffer[1]; PosInfo next = positionBuffer[1];
Vector2 currPos = SimPosition;
//interpolate the position of the collider from the first position in the buffer towards the second //interpolate the position of the collider from the first position in the buffer towards the second
if (prev.Timestamp < next.Timestamp) if (prev.Timestamp < next.Timestamp)
{ {
@@ -482,28 +506,24 @@ namespace Barotrauma
float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f); float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f);
netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp); 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 //override the targetMovement to make the character play the walking/running animation
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp); newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
} }
else else
{ {
currPos = next.Position; newPosition = next.Position;
netInterpolationState = 1.0f; netInterpolationState = 1.0f;
} }
SetTransform(currPos, Rotation);
if (netInterpolationState >= 1.0f) if (netInterpolationState >= 1.0f)
{ {
netInterpolationState = 0.0f; netInterpolationState = 0.0f;
positionBuffer.RemoveAt(0); positionBuffer.RemoveAt(0);
} }
} }
/// <summary> /// <summary>
/// rotate the body towards the target rotation in the "shortest direction" /// rotate the body towards the target rotation in the "shortest direction"
/// </summary> /// </summary>
+4 -2
View File
@@ -97,7 +97,8 @@ namespace Barotrauma
{ {
#if DEBUG #if DEBUG
if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null) if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
!DebugConsole.IsOpen)
{ {
var closestSub = Submarine.GetClosest(cam.WorldViewCenter); var closestSub = Submarine.GetClosest(cam.WorldViewCenter);
if (closestSub == null) closestSub = GameMain.GameSession.Submarine; if (closestSub == null) closestSub = GameMain.GameSession.Submarine;
@@ -338,7 +339,7 @@ namespace Barotrauma
Submarine.DrawDamageable(spriteBatch, null); Submarine.DrawDamageable(spriteBatch, null);
spriteBatch.End(); spriteBatch.End();
GameMain.LightManager.DrawLightMap(spriteBatch, lightBlur.Effect); //GameMain.LightManager.DrawLightMap(spriteBatch, lightBlur.Effect);
GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect, true); GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect, true);
} }
@@ -402,6 +403,7 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Immediate, spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend); BlendState.AlphaBlend);
float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f); float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
Color.Lerp(new Color(0.1f, 0.1f, 0.1f), Color.Red, r)); Color.Lerp(new Color(0.1f, 0.1f, 0.1f), Color.Red, r));