- camera follows the closest sub

- WIP "respawn shuttle"
- submarine size affects its mass
- electricity fixes
This commit is contained in:
Regalis
2016-06-18 14:46:40 +03:00
parent cf822cfae6
commit dc7956274c
23 changed files with 413 additions and 99 deletions
+2
View File
@@ -10,6 +10,8 @@ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
*.suo
#performance reports & sessions #performance reports & sessions
*.vsp *.vsp
*.psess *.psess
+1
View File
@@ -152,6 +152,7 @@
<Compile Include="Source\Networking\NetConfig.cs" /> <Compile Include="Source\Networking\NetConfig.cs" />
<Compile Include="Source\Networking\NetStats.cs" /> <Compile Include="Source\Networking\NetStats.cs" />
<Compile Include="Source\Networking\ReliableSender.cs" /> <Compile Include="Source\Networking\ReliableSender.cs" />
<Compile Include="Source\Networking\RespawnManager.cs" />
<Compile Include="Source\Networking\ServerLog.cs" /> <Compile Include="Source\Networking\ServerLog.cs" />
<Compile Include="Source\Particles\ParticleEmitter.cs" /> <Compile Include="Source\Particles\ParticleEmitter.cs" />
<Compile Include="Source\Networking\GameServerSettings.cs" /> <Compile Include="Source\Networking\GameServerSettings.cs" />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 90 KiB

+29 -1
View File
@@ -8,7 +8,7 @@
pickthroughwalls="true" pickthroughwalls="true"
pickdistance="150"> pickdistance="150">
<Sprite texture ="engine.png" depth="0.8"/> <Sprite texture ="engine.png" depth="0.8" sourcerect="0,0,373,113"/>
<fixrequirement name="Mechanical repairs"> <fixrequirement name="Mechanical repairs">
<skill name="Construction" level="40"/> <skill name="Construction" level="40"/>
@@ -29,6 +29,34 @@
</ConnectionPanel> </ConnectionPanel>
</Item> </Item>
<Item
name="Shuttle Engine"
linkable="true"
category="Machine"
pickthroughwalls="true"
pickdistance="150">
<Sprite texture ="engine.png" depth="0.8" sourcerect="0,115,224,73"/>
<fixrequirement name="Mechanical repairs">
<skill name="Construction" level="30"/>
<item name="Welding Tool"/>
<item name="Wrench"/>
</fixrequirement>
<Engine minvoltage="0.5" powerconsumption="500.0" maxforce="500" canbeselected = "true">
<StatusEffect type="InWater" target="This" condition="-2.0"/>
<GuiFrame rect="0,0,350,160" alignment="Center" color="0.0,0.0,0.0,0.6"/>
<sound file="engine.ogg" type="OnActive" range="3000.0" volume="CurrentVolume" loop="true"/>
</Engine>
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
<requireditem name="Screwdriver" type="Equipped"/>
<input name="power_in"/>
<input name="set_force"/>
</ConnectionPanel>
</Item>
<Item <Item
name="Navigation Terminal" name="Navigation Terminal"
linkable="true" linkable="true"
+14 -6
View File
@@ -125,11 +125,17 @@ namespace Barotrauma
public void Translate(Vector2 amount) public void Translate(Vector2 amount)
{ {
position += amount; position += amount;
//UpdateTransform();
} }
public void UpdateTransform(bool interpolate = true) public void UpdateTransform(bool interpolate = true, bool clampPos = false)
{ {
if (clampPos && Level.Loaded != null)
{
position.Y -= Math.Max(worldView.Y - Level.Loaded.Size.Y, 0.0f);
}
Vector2 interpolatedPosition = interpolate ? Physics.Interpolate(prevPosition, position) : position; Vector2 interpolatedPosition = interpolate ? Physics.Interpolate(prevPosition, position) : position;
float interpolatedZoom = interpolate ? Physics.Interpolate(prevZoom, zoom) : zoom; float interpolatedZoom = interpolate ? Physics.Interpolate(prevZoom, zoom) : zoom;
@@ -179,11 +185,13 @@ namespace Barotrauma
if (GameMain.Config.KeyBind(InputType.Up).IsDown()) moveCam.Y += moveSpeed; if (GameMain.Config.KeyBind(InputType.Up).IsDown()) moveCam.Y += moveSpeed;
} }
if (Submarine.MainSub != null && Screen.Selected == GameMain.GameScreen) if (Screen.Selected == GameMain.GameScreen)
{ {
var closestSub = Submarine.GetClosest(WorldViewCenter);
if (closestSub != null)
moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(Submarine.MainSub.Velocity*deltaTime); {
moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime);
}
} }
moveCam = moveCam * deltaTime * 60.0f; moveCam = moveCam * deltaTime * 60.0f;
@@ -109,10 +109,10 @@ namespace Barotrauma
{ {
Vector2 pos2 = host.SimPosition; Vector2 pos2 = host.SimPosition;
if (character != null && character.Submarine == null) if (character != null && character.Submarine == null && CurrentPath.Nodes.Last().Submarine != null)
{ {
//todo: take multiple subs into account //todo: take multiple subs into account
pos2 -= Submarine.MainSub.SimPosition; pos2 -= CurrentPath.Nodes.Last().Submarine.SimPosition;
} }
return currentTarget-pos2; return currentTarget-pos2;
} }
@@ -123,10 +123,11 @@ namespace Barotrauma
if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f; if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f;
Vector2 pos = host.SimPosition; Vector2 pos = host.SimPosition;
if (character != null && character.Submarine == null) if (character != null && character.Submarine == null &&
CurrentPath.CurrentNode != null && CurrentPath.CurrentNode.Submarine != null)
{ {
//todo: take multiple subs into account //todo: take multiple subs into account
pos -= Submarine.MainSub.SimPosition; pos -= CurrentPath.CurrentNode.Submarine.SimPosition;
} }
if (currentPath.CurrentNode!= null && currentPath.CurrentNode.Ladders!=null) if (currentPath.CurrentNode!= null && currentPath.CurrentNode.Ladders!=null)
+1 -2
View File
@@ -83,13 +83,12 @@ namespace Barotrauma
if (state == ComponentState.Hover) currColor = hoverColor; if (state == ComponentState.Hover) currColor = hoverColor;
if (state == ComponentState.Selected) currColor = selectedColor; if (state == ComponentState.Selected) currColor = selectedColor;
if (sprite!=null) if (sprite != null && sprite.Texture != null)
{ {
spriteBatch.Draw(sprite.Texture, new Vector2(rect.X, rect.Y), sourceRect, currColor * (currColor.A / 255.0f), 0.0f, Vector2.Zero, spriteBatch.Draw(sprite.Texture, new Vector2(rect.X, rect.Y), sourceRect, currColor * (currColor.A / 255.0f), 0.0f, Vector2.Zero,
Scale, SpriteEffects.None, 0.0f); Scale, SpriteEffects.None, 0.0f);
} }
DrawChildren(spriteBatch); DrawChildren(spriteBatch);
} }
} }
+1 -1
View File
@@ -277,7 +277,7 @@ namespace Barotrauma
listBox.ClearChildren(); listBox.ClearChildren();
characters.Clear(); characters.Clear();
WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos); WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
for (int i = 0; i < waypoints.Length; i++) for (int i = 0; i < waypoints.Length; i++)
{ {
@@ -34,7 +34,9 @@ namespace Barotrauma.Items.Components
private float neutralBallastLevel; private float neutralBallastLevel;
bool AutoPilot public Vector2? TargetPosition;
public bool AutoPilot
{ {
get { return autoPilot; } get { return autoPilot; }
set set
@@ -52,7 +54,7 @@ namespace Barotrauma.Items.Components
if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false); if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false);
steeringPath = pathFinder.FindPath( steeringPath = pathFinder.FindPath(
ConvertUnits.ToSimUnits(item.WorldPosition), ConvertUnits.ToSimUnits(item.WorldPosition),
ConvertUnits.ToSimUnits(Level.Loaded.EndPosition)); TargetPosition == null ? ConvertUnits.ToSimUnits(Level.Loaded.EndPosition) : (Vector2)TargetPosition);
} }
else else
{ {
@@ -62,6 +64,12 @@ namespace Barotrauma.Items.Components
} }
} }
public bool MaintainPos
{
get { return maintainPosTickBox.Selected; }
set { maintainPosTickBox.Selected = value; }
}
[Editable, HasDefaultValue(0.5f, true)] [Editable, HasDefaultValue(0.5f, true)]
public float NeutralBallastLevel public float NeutralBallastLevel
@@ -128,7 +136,7 @@ namespace Barotrauma.Items.Components
} }
} }
if (voltage < minVoltage) return; if (voltage < minVoltage && powerConsumption > 0.0f) return;
if (autoPilot) if (autoPilot)
{ {
@@ -158,7 +166,7 @@ namespace Barotrauma.Items.Components
GuiFrame.Update(1.0f / 60.0f); GuiFrame.Update(1.0f / 60.0f);
GuiFrame.Draw(spriteBatch); GuiFrame.Draw(spriteBatch);
if (voltage < minVoltage) return; if (voltage < minVoltage && powerConsumption > 0.0f) return;
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40); Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
//GUI.DrawRectangle(spriteBatch, velRect, Color.White, false); //GUI.DrawRectangle(spriteBatch, velRect, Color.White, false);
@@ -113,7 +113,7 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam) public override void Update(float deltaTime, Camera cam)
{ {
float chargeRate = (float)(Math.Sqrt(charge / capacity)); float chargeRate = (float)(Math.Sqrt(charge / capacity));
//float gridPower = 0.0f; float gridPower = 0.0f;
float gridLoad = 0.0f; float gridLoad = 0.0f;
//if (item.linkedTo.Count == 0) return; //if (item.linkedTo.Count == 0) return;
@@ -127,6 +127,7 @@ namespace Barotrauma.Items.Components
if (pt == null || !pt.IsActive) continue; if (pt == null || !pt.IsActive) continue;
gridLoad += pt.PowerLoad; gridLoad += pt.PowerLoad;
gridPower -= pt.CurrPowerConsumption;
} }
} }
@@ -171,27 +172,21 @@ namespace Barotrauma.Items.Components
// -maxOutput * chargeRate, // -maxOutput * chargeRate,
// 0.1f); // 0.1f);
if (outputVoltage < 1.0f) if (gridPower < gridLoad)
{ {
// CurrPowerOutput = MathHelper.Lerp(
//CurrPowerOutput, Math.Min(maxOutput * chargeRate, gridLoad), 0.05f);
CurrPowerOutput = MathHelper.Lerp( CurrPowerOutput = MathHelper.Lerp(
CurrPowerOutput, Math.Min(maxOutput * chargeRate, gridLoad), 0.05f); CurrPowerOutput,
Math.Min(maxOutput * chargeRate, gridLoad - (gridLoad * outputVoltage)),
0.05f);
} }
else else
{ {
CurrPowerOutput = MathHelper.Lerp(CurrPowerOutput, 0.0f, 0.05f); CurrPowerOutput = MathHelper.Lerp(CurrPowerOutput, 0.0f, 0.05f);
} }
CurrPowerOutput = MathHelper.Lerp(
CurrPowerOutput,
Math.Min(maxOutput * chargeRate, gridLoad - (gridLoad * outputVoltage)),
0.05f);
//powerConsumption = MathHelper.Lerp(
// powerConsumption,
// -Math.Min(maxOutput * chargeRate, gridLoad - (power)),
// 0.1f);
//powerConsumption = Math.Min(powerConsumption, 0.0f); //powerConsumption = Math.Min(powerConsumption, 0.0f);
Charge -= CurrPowerOutput / 3600.0f; Charge -= CurrPowerOutput / 3600.0f;
@@ -62,6 +62,7 @@ namespace Barotrauma.Items.Components
pt.powerLoad += (fullLoad - pt.powerLoad) / inertia; pt.powerLoad += (fullLoad - pt.powerLoad) / inertia;
pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia; pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;
pt.Item.SendSignal(0, "", "power", fullPower / Math.Max(fullLoad, 1.0f)); pt.Item.SendSignal(0, "", "power", fullPower / Math.Max(fullLoad, 1.0f));
pt.Item.SendSignal(0, "", "power_out", fullPower / Math.Max(fullLoad, 1.0f));
//damage the item if voltage is too high //damage the item if voltage is too high
//(except if running as a client) //(except if running as a client)
@@ -117,7 +118,6 @@ namespace Barotrauma.Items.Components
{ {
if (!c.IsPower) continue; if (!c.IsPower) continue;
var recipients = c.Recipients; var recipients = c.Recipients;
foreach (Connection recipient in recipients) foreach (Connection recipient in recipients)
@@ -138,7 +138,7 @@ namespace Barotrauma.Items.Components
PowerContainer powerContainer = powered as PowerContainer; PowerContainer powerContainer = powered as PowerContainer;
if (powerTransfer != null) if (powerTransfer != null)
{ {
if (powerTransfer.updateTimer>0) continue; //if (powerTransfer.updateTimer>0) continue;
powerTransfer.CheckJunctions(deltaTime); powerTransfer.CheckJunctions(deltaTime);
} }
else if (powerContainer != null) else if (powerContainer != null)
@@ -109,6 +109,8 @@ namespace Barotrauma.Items.Components
} }
} }
item.Submarine = newConnection.Item.Submarine;
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (connections[i] != null) continue; if (connections[i] != null) continue;
@@ -117,16 +119,18 @@ namespace Barotrauma.Items.Components
if (!addNode) break; if (!addNode) break;
if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - item.Submarine.HiddenSubPosition) break; if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break;
if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - item.Submarine.HiddenSubPosition) break; if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break;
if (i == 0) if (i == 0)
{ {
Nodes.Insert(0, newConnection.Item.Position - item.Submarine.HiddenSubPosition); Nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
} }
else else
{ {
Nodes.Add(newConnection.Item.Position - item.Submarine.HiddenSubPosition); Nodes.Add(newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
} }
@@ -184,7 +188,7 @@ namespace Barotrauma.Items.Components
{ {
if (Nodes.Count == 0) return; if (Nodes.Count == 0) return;
item.FindHull(); //item.FindHull();
//Vector2 position = item.Position; //Vector2 position = item.Position;
@@ -200,7 +204,11 @@ namespace Barotrauma.Items.Components
// position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height; // position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height;
//} //}
newNodePos = RoundNode(item.Position, item.CurrentHull) - item.Submarine.HiddenSubPosition; Submarine sub = null;
if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine;
if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine;
newNodePos = RoundNode(item.Position, item.CurrentHull) - sub.HiddenSubPosition;
//if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10) //if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10)
//{ //{
@@ -407,7 +415,12 @@ namespace Barotrauma.Items.Components
MapEntity.DisableSelect = true; MapEntity.DisableSelect = true;
//Nodes[(int)selectedNodeIndex] = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition)-Submarine.HiddenSubPosition+Submarine.Loaded.Position; //Nodes[(int)selectedNodeIndex] = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition)-Submarine.HiddenSubPosition+Submarine.Loaded.Position;
Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - item.Submarine.HiddenSubPosition - item.Submarine.Position;// Nodes[(int)selectedNodeIndex];
Submarine sub = null;
if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine;
if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine;
Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - sub.HiddenSubPosition - sub.Position;// Nodes[(int)selectedNodeIndex];
nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f); nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f);
nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f); nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
+1 -1
View File
@@ -523,7 +523,7 @@ namespace Barotrauma
} }
CurrentHull = Hull.FindHull(WorldPosition, CurrentHull); CurrentHull = Hull.FindHull(WorldPosition, CurrentHull);
if (body != null) if (body != null && body.Enabled)
{ {
Submarine = CurrentHull == null ? null : CurrentHull.Submarine; Submarine = CurrentHull == null ? null : CurrentHull.Submarine;
body.Submarine = Submarine; body.Submarine = Submarine;
+6 -1
View File
@@ -22,7 +22,7 @@ namespace Barotrauma
{ {
public static string SavePath = "Submarines"; public static string SavePath = "Submarines";
private static readonly Vector2 HiddenSubStartPosition = new Vector2(-50000.0f, 80000.0f); public static readonly Vector2 HiddenSubStartPosition = new Vector2(-50000.0f, 80000.0f);
//position of the "actual submarine" which is rendered wherever the SubmarineBody is //position of the "actual submarine" which is rendered wherever the SubmarineBody is
//should be in an unreachable place //should be in an unreachable place
public Vector2 HiddenSubPosition public Vector2 HiddenSubPosition
@@ -113,6 +113,11 @@ namespace Barotrauma
get { return loaded; } get { return loaded; }
} }
public SubmarineBody SubBody
{
get { return subBody; }
}
public Rectangle Borders public Rectangle Borders
{ {
get get
+40 -36
View File
@@ -33,11 +33,11 @@ namespace Barotrauma
private readonly Submarine submarine; private readonly Submarine submarine;
private readonly Body body; public readonly Body Body;
private Vector2? targetPosition; private Vector2? targetPosition;
private float mass = 10000.0f; //private float mass = 10000.0f;
public Rectangle Borders public Rectangle Borders
{ {
@@ -47,11 +47,11 @@ namespace Barotrauma
public Vector2 Velocity public Vector2 Velocity
{ {
get { return body.LinearVelocity; } get { return Body.LinearVelocity; }
set set
{ {
if (!MathUtils.IsValid(value)) return; if (!MathUtils.IsValid(value)) return;
body.LinearVelocity = value; Body.LinearVelocity = value;
} }
} }
@@ -67,7 +67,7 @@ namespace Barotrauma
public Vector2 Position public Vector2 Position
{ {
get { return ConvertUnits.ToDisplayUnits(body.Position); } get { return ConvertUnits.ToDisplayUnits(Body.Position); }
} }
public bool AtDamageDepth public bool AtDamageDepth
@@ -82,7 +82,7 @@ namespace Barotrauma
if (!Hull.hullList.Any()) if (!Hull.hullList.Any())
{ {
body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f); Body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f);
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
@@ -110,7 +110,7 @@ namespace Barotrauma
//var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit); //var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit);
body = BodyFactory.CreateBody(GameMain.World, this); Body = BodyFactory.CreateBody(GameMain.World, this);
foreach (Structure wall in Structure.WallList) foreach (Structure wall in Structure.WallList)
{ {
@@ -118,9 +118,9 @@ namespace Barotrauma
FixtureFactory.AttachRectangle( FixtureFactory.AttachRectangle(
ConvertUnits.ToSimUnits(rect.Width), ConvertUnits.ToSimUnits(rect.Width),
ConvertUnits.ToSimUnits(rect.Height), ConvertUnits.ToSimUnits(rect.Height),
5.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); Body, this);
} }
//foreach (Hull hull in Hull.hullList) //foreach (Hull hull in Hull.hullList)
@@ -151,24 +151,24 @@ namespace Barotrauma
body.BodyType = BodyType.Dynamic; Body.BodyType = BodyType.Dynamic;
body.CollisionCategories = Physics.CollisionWall; Body.CollisionCategories = Physics.CollisionWall;
body.CollidesWith = Body.CollidesWith =
Physics.CollisionItem | Physics.CollisionItem |
Physics.CollisionLevel | Physics.CollisionLevel |
Physics.CollisionCharacter | Physics.CollisionCharacter |
Physics.CollisionProjectile | Physics.CollisionProjectile |
Physics.CollisionWall; Physics.CollisionWall;
body.Restitution = Restitution; Body.Restitution = Restitution;
body.Friction = Friction; Body.Friction = Friction;
body.FixedRotation = true; Body.FixedRotation = true;
body.Mass = mass; //mass = Body.Mass;
body.Awake = true; Body.Awake = true;
body.SleepingAllowed = false; Body.SleepingAllowed = false;
body.IgnoreGravity = true; Body.IgnoreGravity = true;
body.OnCollision += OnCollision; Body.OnCollision += OnCollision;
body.UserData = submarine; Body.UserData = submarine;
} }
@@ -237,7 +237,7 @@ namespace Barotrauma
if (dist > 1000.0f) //immediately snap the sub to the target position if more than 1000.0f units away if (dist > 1000.0f) //immediately snap the sub to the target position if more than 1000.0f units away
{ {
Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(body.Position); Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(Body.Position);
ForceTranslate(moveAmount); ForceTranslate(moveAmount);
@@ -270,14 +270,14 @@ namespace Barotrauma
Vector2 totalForce = CalculateBuoyancy(); Vector2 totalForce = CalculateBuoyancy();
if (body.LinearVelocity.LengthSquared() > 0.000001f) if (Body.LinearVelocity.LengthSquared() > 0.000001f)
{ {
float dragCoefficient = 0.01f; float dragCoefficient = 0.01f;
float speedLength = (body.LinearVelocity == Vector2.Zero) ? 0.0f : body.LinearVelocity.Length(); float speedLength = (Body.LinearVelocity == Vector2.Zero) ? 0.0f : Body.LinearVelocity.Length();
float drag = speedLength * speedLength * dragCoefficient * mass; float drag = speedLength * speedLength * dragCoefficient * Body.Mass;
totalForce += -Vector2.Normalize(body.LinearVelocity) * drag; totalForce += -Vector2.Normalize(Body.LinearVelocity) * drag;
} }
ApplyForce(totalForce); ApplyForce(totalForce);
@@ -292,11 +292,15 @@ namespace Barotrauma
/// <param name="amount">Amount to move in display units</param> /// <param name="amount">Amount to move in display units</param>
private void ForceTranslate(Vector2 amount) private void ForceTranslate(Vector2 amount)
{ {
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f); Body.SetTransform(Body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
if (Character.Controlled != null) Character.Controlled.CursorPosition += amount; if (Character.Controlled != null) Character.Controlled.CursorPosition += amount;
GameMain.GameScreen.Cam.Position += amount; if ((Character.Controlled != null && Character.Controlled.Submarine == submarine) ||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount; Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine)
{
GameMain.GameScreen.Cam.Position += amount;
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount;
}
} }
@@ -308,7 +312,7 @@ namespace Barotrauma
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.Position).ToPoint();
Vector2 translateDir = Vector2.Normalize(subTranslation); Vector2 translateDir = Vector2.Normalize(subTranslation);
@@ -355,19 +359,19 @@ namespace Barotrauma
float neutralPercentage = 0.07f; float neutralPercentage = 0.07f;
float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f); float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f);
buoyancy *= mass; buoyancy *= Body.Mass;
return new Vector2(0.0f, buoyancy*10.0f); return new Vector2(0.0f, buoyancy*10.0f);
} }
public void ApplyForce(Vector2 force) public void ApplyForce(Vector2 force)
{ {
body.ApplyForce(force); Body.ApplyForce(force);
} }
public void SetPosition(Vector2 position) public void SetPosition(Vector2 position)
{ {
body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f); Body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f);
} }
private void UpdateDepthDamage(float deltaTime) private void UpdateDepthDamage(float deltaTime)
@@ -423,7 +427,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.Position - limb.SimPosition);
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 5.0f); float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 5.0f);
@@ -436,7 +440,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.Position) - cell.Center);
float wallImpact = Vector2.Dot(Velocity, -collisionNormal); float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
@@ -525,7 +529,7 @@ namespace Barotrauma
foreach (Character c in Character.CharacterList) foreach (Character c in Character.CharacterList)
{ {
if (c.AnimController.CurrentHull == null) continue; if (c.Submarine != submarine) continue;
if (impact > 2.0f) c.StartStun((impact - 2.0f) * 0.1f); if (impact > 2.0f) c.StartStun((impact - 2.0f) * 0.1f);
+6 -8
View File
@@ -641,13 +641,11 @@ namespace Barotrauma
return wayPoints[Rand.Int(wayPoints.Count(), false)]; return wayPoints[Rand.Int(wayPoints.Count(), false)];
} }
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew) public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine)
{ {
List<WayPoint> unassignedWayPoints = new List<WayPoint>(); List<WayPoint> subWayPoints = WayPointList.FindAll(wp => wp.Submarine == submarine);
foreach (WayPoint wp in WayPointList)
{ List<WayPoint> unassignedWayPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human);
if (wp.spawnType == SpawnType.Human) unassignedWayPoints.Add(wp);
}
WayPoint[] assignedWayPoints = new WayPoint[crew.Count]; WayPoint[] assignedWayPoints = new WayPoint[crew.Count];
@@ -670,7 +668,7 @@ namespace Barotrauma
if (assignedWayPoints[i] != null) continue; if (assignedWayPoints[i] != null) continue;
//try to assign a spawnpoint that matches the job, even if the spawnpoint is already assigned to someone else //try to assign a spawnpoint that matches the job, even if the spawnpoint is already assigned to someone else
foreach (WayPoint wp in WayPointList) foreach (WayPoint wp in subWayPoints)
{ {
if (wp.spawnType != SpawnType.Human || wp.assignedJob != crew[i].Job.Prefab) continue; if (wp.spawnType != SpawnType.Human || wp.assignedJob != crew[i].Job.Prefab) continue;
@@ -681,7 +679,7 @@ namespace Barotrauma
if (assignedWayPoints[i] != null) continue; if (assignedWayPoints[i] != null) continue;
//try to assign a spawnpoint that isn't meant for any specific job //try to assign a spawnpoint that isn't meant for any specific job
var nonJobSpecificPoints = WayPointList.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null); var nonJobSpecificPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null);
if (nonJobSpecificPoints.Any()) if (nonJobSpecificPoints.Any())
{ {
+6 -1
View File
@@ -518,6 +518,9 @@ namespace Barotrauma.Networking
string endMessage = inc.ReadString(); string endMessage = inc.ReadString();
CoroutineManager.StartCoroutine(EndGame(endMessage)); CoroutineManager.StartCoroutine(EndGame(endMessage));
break; break;
case (byte)PacketTypes.Respawn:
if (gameStarted && respawnManager != null) respawnManager.ReadNetworkEvent(inc);
break;
case (byte)PacketTypes.PlayerJoined: case (byte)PacketTypes.PlayerJoined:
Client otherClient = new Client(inc.ReadString(), inc.ReadByte()); Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
@@ -673,6 +676,8 @@ namespace Barotrauma.Networking
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]); GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
GameMain.GameSession.StartShift(levelSeed); GameMain.GameSession.StartShift(levelSeed);
respawnManager = new RespawnManager(this);
yield return CoroutineStatus.Running; yield return CoroutineStatus.Running;
//myCharacter = ReadCharacterData(inc); //myCharacter = ReadCharacterData(inc);
@@ -1023,7 +1028,7 @@ namespace Barotrauma.Networking
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
} }
private Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter) public Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter)
{ {
string newName = inc.ReadString(); string newName = inc.ReadString();
ushort ID = inc.ReadUInt16(); ushort ID = inc.ReadUInt16();
+14 -2
View File
@@ -282,6 +282,8 @@ namespace Barotrauma.Networking
{ {
inGameHUD.Update((float)Physics.step); inGameHUD.Update((float)Physics.step);
respawnManager.Update(deltaTime);
bool isCrewDead = bool isCrewDead =
connectedClients.Find(c => c.Character != null && !c.Character.IsDead)==null && connectedClients.Find(c => c.Character != null && !c.Character.IsDead)==null &&
(myCharacter == null || myCharacter.IsDead); (myCharacter == null || myCharacter.IsDead);
@@ -949,6 +951,8 @@ namespace Barotrauma.Networking
GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan); GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan);
GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan); GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan);
respawnManager = new RespawnManager(this);
yield return CoroutineStatus.Running; yield return CoroutineStatus.Running;
List<CharacterInfo> characterInfos = new List<CharacterInfo>(); List<CharacterInfo> characterInfos = new List<CharacterInfo>();
@@ -972,7 +976,7 @@ namespace Barotrauma.Networking
characterInfos.Add(characterInfo); characterInfos.Add(characterInfo);
} }
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos); WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
for (int i = 0; i < connectedClients.Count; i++) for (int i = 0; i < connectedClients.Count; i++)
{ {
@@ -1140,6 +1144,14 @@ namespace Barotrauma.Networking
} }
public void RespawnClients()
{
NetOutgoingMessage msg = server.CreateMessage();
respawnManager.WriteNetworkEvent(msg);
SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "") private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "")
{ {
Client client = connectedClients.Find(x => x.Connection == senderConnection); Client client = connectedClients.Find(x => x.Connection == senderConnection);
@@ -1611,7 +1623,7 @@ namespace Barotrauma.Networking
} }
} }
private void WriteCharacterData(NetOutgoingMessage message, string name, Character character) public void WriteCharacterData(NetOutgoingMessage message, string name, Character character)
{ {
message.Write(name); message.Write(name);
message.Write(character.ID); message.Write(character.ID);
@@ -39,7 +39,9 @@ namespace Barotrauma.Networking
RequestFile, FileStream, RequestFile, FileStream,
SpectateRequest SpectateRequest,
Respawn
} }
enum VoteType enum VoteType
@@ -74,6 +76,9 @@ namespace Barotrauma.Networking
protected Character myCharacter; protected Character myCharacter;
protected CharacterInfo characterInfo; protected CharacterInfo characterInfo;
protected RespawnManager respawnManager;
public Voting Voting; public Voting Voting;
public Character Character public Character Character
@@ -0,0 +1,226 @@
using Barotrauma.Items.Components;
using FarseerPhysics;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Barotrauma.Networking
{
class RespawnManager
{
const int MinCharactersToRespawn = 1;
const float RespawnInterval = 20.0f;
enum State
{
Waiting,
Transporting,
Returning
}
private NetworkMember networkMember;
private State state;
private Submarine respawnShuttle;
private Steering shuttleSteering;
private List<Door> shuttleDoors;
private float respawnTimer, shuttleReturnTimer;
public RespawnManager(NetworkMember server)
{
this.networkMember = server;
respawnShuttle = new Submarine("Submarines/Shuttle Mark I.sub");
respawnShuttle.Load(false);
ResetShuttlePos();
respawnShuttle.GodMode = true;
shuttleDoors = new List<Door>();
foreach (Item item in Item.ItemList)
{
if (item.Submarine != respawnShuttle) continue;
var steering = item.GetComponent<Steering>();
if (steering != null) shuttleSteering = steering;
var door = item.GetComponent<Door>();
if (door != null) shuttleDoors.Add(door);
}
shuttleSteering.TargetPosition = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
respawnTimer = RespawnInterval;
}
private List<Client> GetClientsToRespawn()
{
return networkMember.ConnectedClients.FindAll(c => c.inGame && (c.Character == null || c.Character.IsDead));
}
public void Update(float deltaTime)
{
switch (state)
{
case State.Waiting:
UpdateWaiting(deltaTime);
break;
case State.Transporting:
UpdateTransporting(deltaTime);
break;
case State.Returning:
UpdateReturning(deltaTime);
break;
}
}
private void UpdateWaiting(float deltaTime)
{
var server = networkMember as GameServer;
if (server == null) return;
respawnShuttle.Velocity = Vector2.Zero;
shuttleSteering.AutoPilot = false;
shuttleSteering.MaintainPos = false;
if (GetClientsToRespawn().Count < MinCharactersToRespawn) return;
if (respawnTimer % 10.0f < 5.0f && (respawnTimer - deltaTime) % 10.0f > 5.0f)
{
string time = respawnTimer <= 60.0f ?
(int)respawnTimer + " seconds" :
(int)Math.Floor(respawnTimer / 60.0f) + " minutes";
server.SendChatMessage("Transportation shuttle dispatching in " + time, ChatMessageType.Server);
}
respawnTimer -= deltaTime;
if (respawnTimer <= 0.0f)
{
Respawn();
respawnTimer = RespawnInterval;
state = State.Transporting;
}
}
private void UpdateTransporting(float deltaTime)
{
if (Character.CharacterList.Any(c => c.Submarine == respawnShuttle && !c.IsDead)) return;
shuttleReturnTimer += deltaTime;
if (shuttleReturnTimer > 10.0f)
{
state = State.Returning;
shuttleReturnTimer = 0.0f;
}
}
private void UpdateReturning(float deltaTime)
{
shuttleReturnTimer += deltaTime;
if (shuttleReturnTimer > 1.0f)
{
shuttleSteering.AutoPilot = true;
shuttleSteering.MaintainPos = false;
shuttleDoors.ForEach(s => s.IsOpen = false);
if (shuttleSteering.SteeringPath != null && shuttleSteering.SteeringPath.CurrentIndex == shuttleSteering.SteeringPath.Nodes.Count-1)
{
CoroutineManager.StartCoroutine(
ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f));
state = State.Waiting;
}
shuttleReturnTimer = 0.0f;
}
}
private void Respawn()
{
var server = networkMember as GameServer;
if (server == null) return;
ResetShuttlePos();
server.SendChatMessage("Transportation shuttle dispatched");
server.RespawnClients();
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition, 100.0f));
}
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
{
respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBodies[0]);
while (Math.Abs(position.Y - respawnShuttle.WorldPosition.Y) > 100.0f)
{
Vector2 displayVel = Vector2.Normalize(position - respawnShuttle.WorldPosition) * speed;
respawnShuttle.SubBody.Body.LinearVelocity = ConvertUnits.ToSimUnits(displayVel);
yield return CoroutineStatus.Running;
}
respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBodies[0]);
}
private void ResetShuttlePos()
{
respawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f));
respawnShuttle.Velocity = Vector2.Zero;
}
public void WriteNetworkEvent(NetOutgoingMessage msg)
{
var server = networkMember as GameServer;
var clients = GetClientsToRespawn();
msg.Write((byte)PacketTypes.Respawn);
var waypoints = WayPoint.SelectCrewSpawnPoints(clients.Select(c => c.characterInfo).ToList(), respawnShuttle);
msg.Write((byte)clients.Count);
for (int i = 0; i < clients.Count; i++)
{
msg.Write((byte)clients[i].ID);
clients[i].Character = Character.Create(clients[i].characterInfo, waypoints[i].WorldPosition, true, false);
clients[i].Character.GiveJobItems(waypoints[i]);
GameMain.GameSession.CrewManager.characters.Add(clients[i].Character);
server.WriteCharacterData(msg, clients[i].Character.Name, clients[i].Character);
}
}
public void ReadNetworkEvent(NetIncomingMessage inc)
{
ResetShuttlePos();
var client = networkMember as GameClient;
int clientCount = inc.ReadByte();
for (int i = 0; i<clientCount; i++)
{
byte clientId = inc.ReadByte();
client.ReadCharacterData(inc, clientId == client.ID);
}
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition, 100.0f));
}
}
}
+5 -1
View File
@@ -239,7 +239,7 @@ namespace Barotrauma
} }
else else
{ {
cam.Position = Vector2.Zero; cam.Position = Submarine.HiddenSubStartPosition;
nameBox.Text = ""; nameBox.Text = "";
descriptionBox.Text = ""; descriptionBox.Text = "";
@@ -401,6 +401,7 @@ namespace Barotrauma
if (selectedSub == null) return false; if (selectedSub == null) return false;
Submarine.MainSub = selectedSub;
selectedSub.Load(true); selectedSub.Load(true);
nameBox.Text = selectedSub.Name; nameBox.Text = selectedSub.Name;
@@ -688,6 +689,9 @@ namespace Barotrauma
dummyCharacter.ControlLocalPlayer((float)deltaTime, cam, false); dummyCharacter.ControlLocalPlayer((float)deltaTime, cam, false);
dummyCharacter.Control((float)deltaTime, cam); dummyCharacter.Control((float)deltaTime, cam);
dummyCharacter.Submarine = Submarine.MainSub;
cam.TargetPos = Vector2.Zero; cam.TargetPos = Vector2.Zero;
} }
+2 -2
View File
@@ -155,7 +155,7 @@ namespace Barotrauma
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{ {
cam.UpdateTransform(); cam.UpdateTransform(true, true);
DrawMap(graphics, spriteBatch); DrawMap(graphics, spriteBatch);
@@ -177,7 +177,7 @@ namespace Barotrauma
if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch); if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch);
if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.MainSub); if (Character.Controlled == null && Submarine.MainSub != null) DrawSubmarineIndicator(spriteBatch, Submarine.MainSub);
GUI.Draw((float)deltaTime, spriteBatch, cam); GUI.Draw((float)deltaTime, spriteBatch, cam);
Binary file not shown.