diff --git a/.gitignore b/.gitignore
index 2dcf45db7..c9a6323c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,8 @@ bld/
[Bb]in/
[Oo]bj/
+*.suo
+
#performance reports & sessions
*.vsp
*.psess
diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 68a2ac24e..23966ab7d 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -152,6 +152,7 @@
+
diff --git a/Subsurface/Content/Items/Engine/engine.png b/Subsurface/Content/Items/Engine/engine.png
index ff3ed0c09..a99150aa1 100644
Binary files a/Subsurface/Content/Items/Engine/engine.png and b/Subsurface/Content/Items/Engine/engine.png differ
diff --git a/Subsurface/Content/Items/Engine/engine.xml b/Subsurface/Content/Items/Engine/engine.xml
index 51a20b46b..0df9c95e3 100644
--- a/Subsurface/Content/Items/Engine/engine.xml
+++ b/Subsurface/Content/Items/Engine/engine.xml
@@ -8,7 +8,7 @@
pickthroughwalls="true"
pickdistance="150">
-
+
@@ -29,6 +29,34 @@
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- character.SimPosition.Y+1.0f) allowedDistance*=0.5f;
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
- pos -= Submarine.MainSub.SimPosition;
+ pos -= CurrentPath.CurrentNode.Submarine.SimPosition;
}
if (currentPath.CurrentNode!= null && currentPath.CurrentNode.Ladders!=null)
diff --git a/Subsurface/Source/GUI/GUIImage.cs b/Subsurface/Source/GUI/GUIImage.cs
index 1fb92135a..16dab4c83 100644
--- a/Subsurface/Source/GUI/GUIImage.cs
+++ b/Subsurface/Source/GUI/GUIImage.cs
@@ -83,12 +83,11 @@ namespace Barotrauma
if (state == ComponentState.Hover) currColor = hoverColor;
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,
- Scale, SpriteEffects.None, 0.0f);
- }
-
+ Scale, SpriteEffects.None, 0.0f);
+ }
DrawChildren(spriteBatch);
}
diff --git a/Subsurface/Source/GameSession/CrewManager.cs b/Subsurface/Source/GameSession/CrewManager.cs
index 35261dd84..c9e2e3235 100644
--- a/Subsurface/Source/GameSession/CrewManager.cs
+++ b/Subsurface/Source/GameSession/CrewManager.cs
@@ -277,7 +277,7 @@ namespace Barotrauma
listBox.ClearChildren();
characters.Clear();
- WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
+ WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
for (int i = 0; i < waypoints.Length; i++)
{
diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs
index 78befa10e..b0afc57d6 100644
--- a/Subsurface/Source/Items/Components/Machines/Steering.cs
+++ b/Subsurface/Source/Items/Components/Machines/Steering.cs
@@ -33,8 +33,10 @@ namespace Barotrauma.Items.Components
private float autopilotRayCastTimer;
private float neutralBallastLevel;
+
+ public Vector2? TargetPosition;
- bool AutoPilot
+ public bool AutoPilot
{
get { return autoPilot; }
set
@@ -52,7 +54,7 @@ namespace Barotrauma.Items.Components
if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false);
steeringPath = pathFinder.FindPath(
ConvertUnits.ToSimUnits(item.WorldPosition),
- ConvertUnits.ToSimUnits(Level.Loaded.EndPosition));
+ TargetPosition == null ? ConvertUnits.ToSimUnits(Level.Loaded.EndPosition) : (Vector2)TargetPosition);
}
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)]
public float NeutralBallastLevel
@@ -128,7 +136,7 @@ namespace Barotrauma.Items.Components
}
}
- if (voltage < minVoltage) return;
+ if (voltage < minVoltage && powerConsumption > 0.0f) return;
if (autoPilot)
{
@@ -158,7 +166,7 @@ namespace Barotrauma.Items.Components
GuiFrame.Update(1.0f / 60.0f);
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);
//GUI.DrawRectangle(spriteBatch, velRect, Color.White, false);
diff --git a/Subsurface/Source/Items/Components/Power/PowerContainer.cs b/Subsurface/Source/Items/Components/Power/PowerContainer.cs
index f6400c72e..1fcf4a172 100644
--- a/Subsurface/Source/Items/Components/Power/PowerContainer.cs
+++ b/Subsurface/Source/Items/Components/Power/PowerContainer.cs
@@ -113,7 +113,7 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
float chargeRate = (float)(Math.Sqrt(charge / capacity));
- //float gridPower = 0.0f;
+ float gridPower = 0.0f;
float gridLoad = 0.0f;
//if (item.linkedTo.Count == 0) return;
@@ -126,7 +126,8 @@ namespace Barotrauma.Items.Components
PowerTransfer pt = c2.Item.GetComponent();
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,
// 0.1f);
- if (outputVoltage < 1.0f)
+ if (gridPower < gridLoad)
{
+ // CurrPowerOutput = MathHelper.Lerp(
+ //CurrPowerOutput, Math.Min(maxOutput * chargeRate, gridLoad), 0.05f);
+
CurrPowerOutput = MathHelper.Lerp(
- CurrPowerOutput, Math.Min(maxOutput * chargeRate, gridLoad), 0.05f);
+ CurrPowerOutput,
+ Math.Min(maxOutput * chargeRate, gridLoad - (gridLoad * outputVoltage)),
+ 0.05f);
}
else
{
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);
Charge -= CurrPowerOutput / 3600.0f;
diff --git a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
index c443b8e1d..3dbf0d3e4 100644
--- a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
+++ b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
@@ -62,6 +62,7 @@ namespace Barotrauma.Items.Components
pt.powerLoad += (fullLoad - pt.powerLoad) / inertia;
pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;
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
//(except if running as a client)
@@ -117,7 +118,6 @@ namespace Barotrauma.Items.Components
{
if (!c.IsPower) continue;
-
var recipients = c.Recipients;
foreach (Connection recipient in recipients)
@@ -138,7 +138,7 @@ namespace Barotrauma.Items.Components
PowerContainer powerContainer = powered as PowerContainer;
if (powerTransfer != null)
{
- if (powerTransfer.updateTimer>0) continue;
+ //if (powerTransfer.updateTimer>0) continue;
powerTransfer.CheckJunctions(deltaTime);
}
else if (powerContainer != null)
diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs
index 6dcd34036..a1bbe5540 100644
--- a/Subsurface/Source/Items/Components/Signal/Wire.cs
+++ b/Subsurface/Source/Items/Components/Signal/Wire.cs
@@ -109,6 +109,8 @@ namespace Barotrauma.Items.Components
}
}
+ item.Submarine = newConnection.Item.Submarine;
+
for (int i = 0; i < 2; i++)
{
if (connections[i] != null) continue;
@@ -117,16 +119,18 @@ namespace Barotrauma.Items.Components
if (!addNode) break;
- if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - item.Submarine.HiddenSubPosition) break;
- if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == 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 - newConnection.Item.Submarine.HiddenSubPosition) break;
+
+
if (i == 0)
{
- Nodes.Insert(0, newConnection.Item.Position - item.Submarine.HiddenSubPosition);
+ Nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
}
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;
- item.FindHull();
+ //item.FindHull();
//Vector2 position = item.Position;
@@ -200,7 +204,11 @@ namespace Barotrauma.Items.Components
// 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)
//{
@@ -407,7 +415,12 @@ namespace Barotrauma.Items.Components
MapEntity.DisableSelect = true;
//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.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs
index b8e908275..2243aef2e 100644
--- a/Subsurface/Source/Items/Item.cs
+++ b/Subsurface/Source/Items/Item.cs
@@ -523,7 +523,7 @@ namespace Barotrauma
}
CurrentHull = Hull.FindHull(WorldPosition, CurrentHull);
- if (body != null)
+ if (body != null && body.Enabled)
{
Submarine = CurrentHull == null ? null : CurrentHull.Submarine;
body.Submarine = Submarine;
diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs
index d481627a5..7b7940112 100644
--- a/Subsurface/Source/Map/Submarine.cs
+++ b/Subsurface/Source/Map/Submarine.cs
@@ -22,7 +22,7 @@ namespace Barotrauma
{
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
//should be in an unreachable place
public Vector2 HiddenSubPosition
@@ -113,6 +113,11 @@ namespace Barotrauma
get { return loaded; }
}
+ public SubmarineBody SubBody
+ {
+ get { return subBody; }
+ }
+
public Rectangle Borders
{
get
diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs
index ad6dd7500..0d0b354a0 100644
--- a/Subsurface/Source/Map/SubmarineBody.cs
+++ b/Subsurface/Source/Map/SubmarineBody.cs
@@ -33,11 +33,11 @@ namespace Barotrauma
private readonly Submarine submarine;
- private readonly Body body;
+ public readonly Body Body;
private Vector2? targetPosition;
- private float mass = 10000.0f;
+ //private float mass = 10000.0f;
public Rectangle Borders
{
@@ -47,11 +47,11 @@ namespace Barotrauma
public Vector2 Velocity
{
- get { return body.LinearVelocity; }
+ get { return Body.LinearVelocity; }
set
{
if (!MathUtils.IsValid(value)) return;
- body.LinearVelocity = value;
+ Body.LinearVelocity = value;
}
}
@@ -67,7 +67,7 @@ namespace Barotrauma
public Vector2 Position
{
- get { return ConvertUnits.ToDisplayUnits(body.Position); }
+ get { return ConvertUnits.ToDisplayUnits(Body.Position); }
}
public bool AtDamageDepth
@@ -82,7 +82,7 @@ namespace Barotrauma
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.");
}
else
@@ -110,7 +110,7 @@ namespace Barotrauma
//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)
{
@@ -118,9 +118,9 @@ namespace Barotrauma
FixtureFactory.AttachRectangle(
ConvertUnits.ToSimUnits(rect.Width),
ConvertUnits.ToSimUnits(rect.Height),
- 5.0f,
+ 50.0f,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
- body, this);
+ Body, this);
}
//foreach (Hull hull in Hull.hullList)
@@ -151,24 +151,24 @@ namespace Barotrauma
- body.BodyType = BodyType.Dynamic;
- body.CollisionCategories = Physics.CollisionWall;
- body.CollidesWith =
+ Body.BodyType = BodyType.Dynamic;
+ Body.CollisionCategories = Physics.CollisionWall;
+ Body.CollidesWith =
Physics.CollisionItem |
Physics.CollisionLevel |
Physics.CollisionCharacter |
Physics.CollisionProjectile |
Physics.CollisionWall;
- body.Restitution = Restitution;
- body.Friction = Friction;
- body.FixedRotation = true;
- body.Mass = mass;
- body.Awake = true;
- body.SleepingAllowed = false;
- body.IgnoreGravity = true;
- body.OnCollision += OnCollision;
- body.UserData = submarine;
+ Body.Restitution = Restitution;
+ Body.Friction = Friction;
+ Body.FixedRotation = true;
+ //mass = Body.Mass;
+ Body.Awake = true;
+ Body.SleepingAllowed = false;
+ Body.IgnoreGravity = true;
+ Body.OnCollision += OnCollision;
+ 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
{
- Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(body.Position);
+ Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(Body.Position);
ForceTranslate(moveAmount);
@@ -270,14 +270,14 @@ namespace Barotrauma
Vector2 totalForce = CalculateBuoyancy();
- if (body.LinearVelocity.LengthSquared() > 0.000001f)
+ if (Body.LinearVelocity.LengthSquared() > 0.000001f)
{
float dragCoefficient = 0.01f;
- float speedLength = (body.LinearVelocity == Vector2.Zero) ? 0.0f : body.LinearVelocity.Length();
- float drag = speedLength * speedLength * dragCoefficient * mass;
+ float speedLength = (Body.LinearVelocity == Vector2.Zero) ? 0.0f : Body.LinearVelocity.Length();
+ float drag = speedLength * speedLength * dragCoefficient * Body.Mass;
- totalForce += -Vector2.Normalize(body.LinearVelocity) * drag;
+ totalForce += -Vector2.Normalize(Body.LinearVelocity) * drag;
}
ApplyForce(totalForce);
@@ -292,11 +292,15 @@ namespace Barotrauma
/// Amount to move in display units
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;
- GameMain.GameScreen.Cam.Position += amount;
- if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount;
+ if ((Character.Controlled != null && Character.Controlled.Submarine == submarine) ||
+ 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)
{
Rectangle worldBorders = Borders;
- worldBorders.Location += ConvertUnits.ToDisplayUnits(body.Position).ToPoint();
+ worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.Position).ToPoint();
Vector2 translateDir = Vector2.Normalize(subTranslation);
@@ -355,19 +359,19 @@ namespace Barotrauma
float neutralPercentage = 0.07f;
float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f);
- buoyancy *= mass;
+ buoyancy *= Body.Mass;
return new Vector2(0.0f, buoyancy*10.0f);
}
public void ApplyForce(Vector2 force)
{
- body.ApplyForce(force);
+ Body.ApplyForce(force);
}
public void SetPosition(Vector2 position)
{
- body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f);
+ Body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f);
}
private void UpdateDepthDamage(float deltaTime)
@@ -423,7 +427,7 @@ namespace Barotrauma
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);
@@ -436,7 +440,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.Position) - cell.Center);
float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
@@ -525,7 +529,7 @@ namespace Barotrauma
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);
diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs
index b901c0775..a5f9a49c4 100644
--- a/Subsurface/Source/Map/WayPoint.cs
+++ b/Subsurface/Source/Map/WayPoint.cs
@@ -641,13 +641,11 @@ namespace Barotrauma
return wayPoints[Rand.Int(wayPoints.Count(), false)];
}
- public static WayPoint[] SelectCrewSpawnPoints(List crew)
+ public static WayPoint[] SelectCrewSpawnPoints(List crew, Submarine submarine)
{
- List unassignedWayPoints = new List();
- foreach (WayPoint wp in WayPointList)
- {
- if (wp.spawnType == SpawnType.Human) unassignedWayPoints.Add(wp);
- }
+ List subWayPoints = WayPointList.FindAll(wp => wp.Submarine == submarine);
+
+ List unassignedWayPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human);
WayPoint[] assignedWayPoints = new WayPoint[crew.Count];
@@ -670,7 +668,7 @@ namespace Barotrauma
if (assignedWayPoints[i] != null) continue;
//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;
@@ -681,7 +679,7 @@ namespace Barotrauma
if (assignedWayPoints[i] != null) continue;
//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())
{
diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs
index 905d2e5e1..2d401dd9b 100644
--- a/Subsurface/Source/Networking/GameClient.cs
+++ b/Subsurface/Source/Networking/GameClient.cs
@@ -518,6 +518,9 @@ namespace Barotrauma.Networking
string endMessage = inc.ReadString();
CoroutineManager.StartCoroutine(EndGame(endMessage));
break;
+ case (byte)PacketTypes.Respawn:
+ if (gameStarted && respawnManager != null) respawnManager.ReadNetworkEvent(inc);
+ break;
case (byte)PacketTypes.PlayerJoined:
Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
@@ -672,7 +675,9 @@ namespace Barotrauma.Networking
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
GameMain.GameSession.StartShift(levelSeed);
-
+
+ respawnManager = new RespawnManager(this);
+
yield return CoroutineStatus.Running;
//myCharacter = ReadCharacterData(inc);
@@ -1023,7 +1028,7 @@ namespace Barotrauma.Networking
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
- private Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter)
+ public Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter)
{
string newName = inc.ReadString();
ushort ID = inc.ReadUInt16();
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index 6edcd4ef6..5251d4705 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -282,6 +282,8 @@ namespace Barotrauma.Networking
{
inGameHUD.Update((float)Physics.step);
+ respawnManager.Update(deltaTime);
+
bool isCrewDead =
connectedClients.Find(c => c.Character != null && !c.Character.IsDead)==null &&
(myCharacter == null || myCharacter.IsDead);
@@ -949,6 +951,8 @@ namespace Barotrauma.Networking
GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan);
GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan);
+ respawnManager = new RespawnManager(this);
+
yield return CoroutineStatus.Running;
List characterInfos = new List();
@@ -972,7 +976,7 @@ namespace Barotrauma.Networking
characterInfos.Add(characterInfo);
}
- WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
+ WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
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 = "")
{
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(character.ID);
diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs
index 7a167d71f..6b7edd427 100644
--- a/Subsurface/Source/Networking/NetworkMember.cs
+++ b/Subsurface/Source/Networking/NetworkMember.cs
@@ -39,7 +39,9 @@ namespace Barotrauma.Networking
RequestFile, FileStream,
- SpectateRequest
+ SpectateRequest,
+
+ Respawn
}
enum VoteType
@@ -74,6 +76,9 @@ namespace Barotrauma.Networking
protected Character myCharacter;
protected CharacterInfo characterInfo;
+
+ protected RespawnManager respawnManager;
+
public Voting Voting;
public Character Character
diff --git a/Subsurface/Source/Networking/RespawnManager.cs b/Subsurface/Source/Networking/RespawnManager.cs
new file mode 100644
index 000000000..8d4be8c2d
--- /dev/null
+++ b/Subsurface/Source/Networking/RespawnManager.cs
@@ -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 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();
+ foreach (Item item in Item.ItemList)
+ {
+ if (item.Submarine != respawnShuttle) continue;
+
+ var steering = item.GetComponent();
+ if (steering != null) shuttleSteering = steering;
+
+ var door = item.GetComponent();
+ if (door != null) shuttleDoors.Add(door);
+ }
+
+ shuttleSteering.TargetPosition = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
+
+ respawnTimer = RespawnInterval;
+ }
+
+ private List 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