diff --git a/Subsurface/Content/Items/Engine/engine.xml b/Subsurface/Content/Items/Engine/engine.xml
index 0df9c95e3..c7739754e 100644
--- a/Subsurface/Content/Items/Engine/engine.xml
+++ b/Subsurface/Content/Items/Engine/engine.xml
@@ -44,7 +44,7 @@
-
+
diff --git a/Subsurface/Source/Camera.cs b/Subsurface/Source/Camera.cs
index e073d267c..7a3ab5361 100644
--- a/Subsurface/Source/Camera.cs
+++ b/Subsurface/Source/Camera.cs
@@ -125,17 +125,11 @@ namespace Barotrauma
public void Translate(Vector2 amount)
{
position += amount;
+
}
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;
float interpolatedZoom = interpolate ? Physics.Interpolate(prevZoom, zoom) : zoom;
@@ -143,6 +137,13 @@ namespace Barotrauma
worldView.X = (int)(interpolatedPosition.X - worldView.Width / 2.0);
worldView.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
+
+ if (Level.Loaded != null && clampPos)
+ {
+ position.Y -= Math.Max(worldView.Y - Level.Loaded.Size.Y, 0.0f);
+ interpolatedPosition.Y -= Math.Max(worldView.Y - Level.Loaded.Size.Y, 0.0f);
+ }
+
transform = Matrix.CreateTranslation(
new Vector3(-interpolatedPosition.X, interpolatedPosition.Y, 0)) *
Matrix.CreateScale(new Vector3(interpolatedZoom, interpolatedZoom, 1)) *
@@ -216,14 +217,14 @@ namespace Barotrauma
Vector2 diff = (targetPos + offset) - position;
- moveCam = diff / MoveSmoothness;
+ moveCam = diff / MoveSmoothness;
}
shakeTargetPosition = Rand.Vector(Shake);
shakePosition = Vector2.Lerp(shakePosition, shakeTargetPosition, 0.5f);
- Shake = MathHelper.Lerp(Shake, 0.0f, deltaTime*2.0f);
+ Shake = MathHelper.Lerp(Shake, 0.0f, deltaTime * 2.0f);
- Translate(moveCam+shakePosition);
+ Translate(moveCam + shakePosition);
}
public Vector2 Position
diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs
index cf76785eb..d8107f9d5 100644
--- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs
+++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs
@@ -105,9 +105,8 @@ namespace Barotrauma
{
if (currentPath == null) return Vector2.Zero;
- if (currentPath.CurrentIndex == currentPath.Nodes.Count)
+ if (currentPath.Finished)
{
-
Vector2 pos2 = host.SimPosition;
if (character != null && character.Submarine == null && CurrentPath.Nodes.Last().Submarine != null)
{
diff --git a/Subsurface/Source/Characters/AI/SteeringPath.cs b/Subsurface/Source/Characters/AI/SteeringPath.cs
index 671421195..2a98ac366 100644
--- a/Subsurface/Source/Characters/AI/SteeringPath.cs
+++ b/Subsurface/Source/Characters/AI/SteeringPath.cs
@@ -70,6 +70,11 @@ namespace Barotrauma
}
}
+ public bool Finished
+ {
+ get { return currentIndex >= nodes.Count; }
+ }
+
public void SkipToNextNode()
{
currentIndex++;
diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs
index f9c33c541..ba75e1999 100644
--- a/Subsurface/Source/Items/Components/Door.cs
+++ b/Subsurface/Source/Items/Components/Door.cs
@@ -444,28 +444,31 @@ namespace Barotrauma.Items.Components
if (connection.Name=="toggle")
{
- SetState(!isOpen, false);
+ SetState(!isOpen, false, true);
}
else if (connection.Name == "set_state")
{
- SetState(signal != "0", false);
+ SetState(signal != "0", false, true);
}
-
- item.NewComponentEvent(this, false, true);
}
- private void SetState(bool state, bool isNetWorkMessage)
+ public void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage = false)
{
- if (GameMain.Client != null && !isNetWorkMessage) return;
+ if (GameMain.Client != null && !isNetworkMessage) return;
- if (isStuck || isOpen == state) return;
+ if (isStuck || isOpen == open) return;
PlaySound(ActionType.OnUse, item.WorldPosition);
- isOpen = state;
+ isOpen = open;
//opening a partially stuck door makes it less stuck
if (isOpen) stuck = MathHelper.Clamp(stuck - 30.0f, 0.0f, 100.0f);
+
+ if (sendNetworkMessage)
+ {
+ item.NewComponentEvent(this, false, true);
+ }
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs
index 8a34933fa..5516f9ed2 100644
--- a/Subsurface/Source/Map/Levels/Level.cs
+++ b/Subsurface/Source/Map/Levels/Level.cs
@@ -17,6 +17,8 @@ namespace Barotrauma
class Level
{
+ public const float ShaftHeight = 1000.0f;
+
public static Level Loaded
{
get { return loaded; }
@@ -56,7 +58,7 @@ namespace Barotrauma
private WrappingWall[,] wrappingWalls;
- private float shaftHeight;
+ //private float shaftHeight;
//List bodies;
private List cells;
@@ -121,7 +123,7 @@ namespace Barotrauma
{
get { return backgroundColor; }
}
-
+
public Level(string seed, float difficulty, int width, int height, int siteInterval)
{
this.seed = seed;
@@ -513,7 +515,7 @@ namespace Barotrauma
ShaftBodies = new Body[2];
for (int i = 0; i < 2; i++)
{
- ShaftBodies[i] = BodyFactory.CreateRectangle(GameMain.World, 200.0f, 10.0f, 5.0f);
+ ShaftBodies[i] = BodyFactory.CreateRectangle(GameMain.World, 200.0f, ConvertUnits.ToSimUnits(ShaftHeight), 5.0f);
ShaftBodies[i].BodyType = BodyType.Static;
ShaftBodies[i].CollisionCategories = Physics.CollisionLevel;
@@ -585,7 +587,7 @@ namespace Barotrauma
{
List wayPoints = new List();
- var newWaypoint = new WayPoint(new Rectangle((int)pathCells[0].Center.X, (int)(borders.Height + shaftHeight), 10, 10), null);
+ var newWaypoint = new WayPoint(new Rectangle((int)pathCells[0].Center.X, borders.Height, 10, 10), null);
newWaypoint.MoveWithLevel = true;
wayPoints.Add(newWaypoint);
@@ -625,7 +627,7 @@ namespace Barotrauma
//prevWaypoint = newWaypoint;
}
- newWaypoint = new WayPoint(new Rectangle((int)pathCells[pathCells.Count - 1].Center.X, (int)(borders.Height + shaftHeight), 10, 10), null);
+ newWaypoint = new WayPoint(new Rectangle((int)pathCells[pathCells.Count - 1].Center.X, borders.Height, 10, 10), null);
newWaypoint.MoveWithLevel = true;
wayPoints.Add(newWaypoint);
diff --git a/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs b/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs
index cf4c1e67f..832339281 100644
--- a/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs
+++ b/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs
@@ -319,9 +319,11 @@ namespace Barotrauma.RuinGeneration
(int)((wall.B.X - wall.A.X) + radius*2.0f),
(int)((wall.B.Y - wall.A.Y) + radius*2.0f));
+ //cut a section off from both ends of a horizontal wall to get nicer looking corners
if (wall.A.Y == wall.B.Y)
{
rect.Inflate(-32, 0);
+ if (rect.Width < Submarine.GridSize.X) continue;
}
var structure = new Structure(rect, structurePrefab.Prefab as StructurePrefab, null);
diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs
index 0d0b354a0..1cc21f166 100644
--- a/Subsurface/Source/Map/SubmarineBody.cs
+++ b/Subsurface/Source/Map/SubmarineBody.cs
@@ -114,6 +114,8 @@ namespace Barotrauma
foreach (Structure wall in Structure.WallList)
{
+ if (wall.Submarine != submarine) continue;
+
Rectangle rect = wall.Rect;
FixtureFactory.AttachRectangle(
ConvertUnits.ToSimUnits(rect.Width),
@@ -241,7 +243,11 @@ namespace Barotrauma
ForceTranslate(moveAmount);
- if (submarine == Submarine.MainSub) GameMain.GameScreen.Cam.UpdateTransform(false);
+ if ((Character.Controlled != null && Character.Controlled.Submarine == submarine) ||
+ (Character.Controlled == null && Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine))
+ {
+ GameMain.GameScreen.Cam.UpdateTransform(false);
+ }
submarine.SetPrevTransform(submarine.Position);
submarine.UpdateTransform();
@@ -296,7 +302,7 @@ namespace Barotrauma
if (Character.Controlled != null) Character.Controlled.CursorPosition += amount;
if ((Character.Controlled != null && Character.Controlled.Submarine == submarine) ||
- Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine)
+ (Character.Controlled == null && Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine))
{
GameMain.GameScreen.Cam.Position += amount;
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount;
diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs
index 2d401dd9b..bfc5100d6 100644
--- a/Subsurface/Source/Networking/GameClient.cs
+++ b/Subsurface/Source/Networking/GameClient.cs
@@ -413,6 +413,11 @@ namespace Barotrauma.Networking
reliableChannel.Update(deltaTime);
+ if (gameStarted && respawnManager != null)
+ {
+ respawnManager.Update(deltaTime);
+ }
+
if (updateTimer > DateTime.Now) return;
if (myCharacter != null)
@@ -730,6 +735,8 @@ namespace Barotrauma.Networking
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
+ respawnManager = null;
+
float endPreviewLength = 10.0f;
if (Screen.Selected == GameMain.GameScreen)
@@ -779,11 +786,6 @@ namespace Barotrauma.Networking
if (fileStreamReceiver != null &&
(fileStreamReceiver.Status == FileTransferStatus.Receiving || fileStreamReceiver.Status == FileTransferStatus.NotStarted))
{
- //Vector2 pos = Screen.Selected == GameMain.NetLobbyScreen ?
- // new Vector2(GameMain.NetLobbyScreen.SubList.Rect.X, GameMain.NetLobbyScreen.SubList.Rect.Bottom+5) : new Vector2(GameMain.GraphicsWidth / 2 - 200, 10);
-
-
-
Vector2 pos = new Vector2(GameMain.GraphicsWidth / 2 - 130, GameMain.NetLobbyScreen.InfoFrame.Rect.Y / 2 - 15);
GUI.DrawString(spriteBatch,
@@ -804,6 +806,16 @@ namespace Barotrauma.Networking
}
}
+ if (respawnManager != null && respawnManager.CurrentState == RespawnManager.State.Waiting &&
+ myCharacter != null && myCharacter.IsDead)
+ {
+ GUI.DrawString(spriteBatch,
+ new Vector2(GameMain.GraphicsWidth - 300.0f, 20),
+ "Respawning in " + (int)respawnManager.RespawnTimer + " s",
+ Color.White, null, 0, GUI.SmallFont);
+ }
+
+
if (!GameMain.DebugDraw) return;
int width = 200, height = 300;
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index 5251d4705..392234741 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -850,6 +850,10 @@ namespace Barotrauma.Networking
//save "normal" events again
existingEvents = new List(NetworkEvent.Events);
}
+
+ yield return new WaitForSeconds(0.1f);
+
+ sender.inGame = true;
yield return CoroutineStatus.Success;
}
@@ -1102,6 +1106,8 @@ namespace Barotrauma.Networking
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
+ respawnManager = null;
+
gameStarted = false;
if (connectedClients.Count > 0)
@@ -1144,7 +1150,7 @@ namespace Barotrauma.Networking
}
- public void RespawnClients()
+ public void SendRespawnManagerMsg()
{
NetOutgoingMessage msg = server.CreateMessage();
respawnManager.WriteNetworkEvent(msg);
@@ -1342,6 +1348,14 @@ namespace Barotrauma.Networking
log.LogFrame.Draw(spriteBatch);
}
+ if (respawnManager != null && respawnManager.CurrentState == RespawnManager.State.Waiting && respawnManager.CountdownStarted)
+ {
+ GUI.DrawString(spriteBatch,
+ new Vector2(GameMain.GraphicsWidth - 500.0f, 20),
+ "Respawning in " + (int)respawnManager.RespawnTimer + " s",
+ Color.White, null, 0, GUI.SmallFont);
+ }
+
if (!ShowNetStats) return;
int width = 200, height = 300;
diff --git a/Subsurface/Source/Networking/RespawnManager.cs b/Subsurface/Source/Networking/RespawnManager.cs
index 8d4be8c2d..1b5a4d2f5 100644
--- a/Subsurface/Source/Networking/RespawnManager.cs
+++ b/Subsurface/Source/Networking/RespawnManager.cs
@@ -16,7 +16,7 @@ namespace Barotrauma.Networking
const float RespawnInterval = 20.0f;
- enum State
+ public enum State
{
Waiting,
Transporting,
@@ -31,6 +31,22 @@ namespace Barotrauma.Networking
private Steering shuttleSteering;
private List shuttleDoors;
+ public float RespawnTimer
+ {
+ get { return respawnTimer; }
+ }
+
+ public bool CountdownStarted
+ {
+ get;
+ private set;
+ }
+
+ public State CurrentState
+ {
+ get { return state; }
+ }
+
private float respawnTimer, shuttleReturnTimer;
public RespawnManager(NetworkMember server)
@@ -85,42 +101,49 @@ namespace Barotrauma.Networking
private void UpdateWaiting(float deltaTime)
{
var server = networkMember as GameServer;
- if (server == null) return;
+ if (server == null)
+ {
+ if (CountdownStarted)
+ {
+ respawnTimer = Math.Max(0.0f, respawnTimer - deltaTime);
+ }
+ return;
+ }
respawnShuttle.Velocity = Vector2.Zero;
shuttleSteering.AutoPilot = false;
shuttleSteering.MaintainPos = false;
- if (GetClientsToRespawn().Count < MinCharactersToRespawn) return;
+ int characterToRespawnCount = GetClientsToRespawn().Count;
+ if (server.Character != null && server.Character.IsDead) characterToRespawnCount++;
- 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";
+ CountdownStarted = characterToRespawnCount >= MinCharactersToRespawn;
- server.SendChatMessage("Transportation shuttle dispatching in " + time, ChatMessageType.Server);
- }
+ if (!CountdownStarted) return;
respawnTimer -= deltaTime;
if (respawnTimer <= 0.0f)
{
- Respawn();
-
respawnTimer = RespawnInterval;
- state = State.Transporting;
+
+ Respawn();
}
}
private void UpdateTransporting(float deltaTime)
{
+ var server = networkMember as GameServer;
+ if (server == null) return;
+
if (Character.CharacterList.Any(c => c.Submarine == respawnShuttle && !c.IsDead)) return;
shuttleReturnTimer += deltaTime;
if (shuttleReturnTimer > 10.0f)
{
state = State.Returning;
+
+ server.SendRespawnManagerMsg();
shuttleReturnTimer = 0.0f;
}
}
@@ -134,14 +157,31 @@ namespace Barotrauma.Networking
shuttleSteering.AutoPilot = true;
shuttleSteering.MaintainPos = false;
- shuttleDoors.ForEach(s => s.IsOpen = false);
-
- if (shuttleSteering.SteeringPath != null && shuttleSteering.SteeringPath.CurrentIndex == shuttleSteering.SteeringPath.Nodes.Count-1)
+ foreach (Door door in shuttleDoors)
+ {
+ if (door.IsOpen) door.SetState(false, false, true);
+ }
+
+ var server = networkMember as GameServer;
+ if (server == null) return;
+
+ //shuttle has returned if the path has been traversed or the shuttle is close enough to the exit
+ if (shuttleSteering.SteeringPath != null && shuttleSteering.SteeringPath.Finished
+ || (respawnShuttle.WorldPosition.Y + respawnShuttle.Borders.Y > Level.Loaded.StartPosition.Y - Level.ShaftHeight &&
+ Math.Abs(Level.Loaded.StartPosition.X - respawnShuttle.WorldPosition.X) < 1000.0f))
{
CoroutineManager.StartCoroutine(
ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f));
+
+ if (GameMain.GameSession != null && GameMain.GameSession.Map != null)
+ {
+ string msg = "The transportation shuttle has returned to " + GameMain.GameSession.Map.SelectedLocation;
+ server.SendChatMessage(ChatMessage.Create("", msg, ChatMessageType.Server, null), server.ConnectedClients);
+ }
+
state = State.Waiting;
+ server.SendRespawnManagerMsg();
}
shuttleReturnTimer = 0.0f;
@@ -153,13 +193,15 @@ namespace Barotrauma.Networking
var server = networkMember as GameServer;
if (server == null) return;
+ state = State.Transporting;
+
ResetShuttlePos();
- server.SendChatMessage("Transportation shuttle dispatched");
+ server.SendChatMessage(ChatMessage.Create("", "Transportation shuttle dispatched", ChatMessageType.Server, null), server.ConnectedClients);
- server.RespawnClients();
+ server.SendRespawnManagerMsg();
- CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition, 100.0f));
+ CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f));
}
private IEnumerable