From 8c032d8368be6fe5bd844e9fcd2c71b0261f8b2f Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 26 Dec 2015 22:35:28 +0200 Subject: [PATCH] Lighting bugfixes, setting camera position to character on shift start --- Subsurface/Source/Characters/Character.cs | 13 ++++++----- Subsurface/Source/Items/Components/Door.cs | 22 +++++++++---------- Subsurface/Source/Map/Lights/ConvexHull.cs | 5 ++++- Subsurface/Source/Map/Lights/LightSource.cs | 7 ++++-- Subsurface/Source/Map/Submarine.cs | 5 ++++- Subsurface/Source/Map/TransitionCinematic.cs | 4 ++-- Subsurface/Source/Networking/GameClient.cs | 5 +++-- Subsurface/Source/Screens/GameScreen.cs | 10 ++++++++- Subsurface/Source/Screens/NetLobbyScreen.cs | 4 +++- Subsurface_Solution.v12.suo | Bin 802816 -> 825856 bytes 10 files changed, 49 insertions(+), 26 deletions(-) diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 54feae451..1e1be8458 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1104,6 +1104,8 @@ namespace Barotrauma { if (controlled != this) yield return CoroutineStatus.Success; + Character.controlled = null; + float dimDuration = 8.0f; float timer = 0.0f; @@ -1114,13 +1116,12 @@ namespace Barotrauma { timer += CoroutineManager.DeltaTime; - if (controlled == this) - { - if (cam != null) cam.OffsetAmount = 0.0f; + if (cam != null) cam.OffsetAmount = 0.0f; - GameMain.LightManager.AmbientLight = Color.Lerp(prevAmbientLight, darkLight, timer / dimDuration); - } + cam.TargetPos = WorldPosition; + GameMain.LightManager.AmbientLight = Color.Lerp(prevAmbientLight, darkLight, timer / dimDuration); + yield return CoroutineStatus.Running; } @@ -1138,6 +1139,8 @@ namespace Barotrauma yield return CoroutineStatus.Running; } + cam.TargetPos = Vector2.Zero; + yield return CoroutineStatus.Success; } diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs index ba43bf53e..695ff9dfa 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -143,13 +143,6 @@ namespace Barotrauma.Items.Components //string spritePath = Path.GetDirectoryName(item.Prefab.ConfigFile) + "\\"+ ToolBox.GetAttributeString(element, "sprite", ""); - Vector2[] corners = GetConvexHullCorners(doorRect); - - convexHull = new ConvexHull(corners, Color.Black, item.CurrentHull == null ? null : item.CurrentHull.Submarine); - if (window!=Rectangle.Empty) convexHull2 = new ConvexHull(corners, Color.Black, item.CurrentHull == null ? null : item.CurrentHull.Submarine); - - UpdateConvexHulls(); - IsActive = true; } @@ -210,10 +203,10 @@ namespace Barotrauma.Items.Components private Vector2[] GetConvexHullCorners(Rectangle rect) { Vector2[] corners = new Vector2[4]; - corners[0] = new Vector2(rect.X, rect.Y - rect.Height); - corners[1] = new Vector2(rect.X, rect.Y); - corners[2] = new Vector2(rect.Right, rect.Y); - corners[3] = new Vector2(rect.Right, rect.Y - rect.Height); + corners[0] = new Vector2(rect.X, rect.Y - rect.Height) + Submarine.HiddenSubPosition; + corners[1] = new Vector2(rect.X, rect.Y) + Submarine.HiddenSubPosition; + corners[2] = new Vector2(rect.Right, rect.Y) + Submarine.HiddenSubPosition; + corners[3] = new Vector2(rect.Right, rect.Y - rect.Height) + Submarine.HiddenSubPosition; return corners; } @@ -331,6 +324,13 @@ namespace Barotrauma.Items.Components public override void OnMapLoaded() { LinkedGap.ConnectedDoor = this; + + Vector2[] corners = GetConvexHullCorners(doorRect); + + convexHull = new ConvexHull(corners, Color.Black, item); + if (window != Rectangle.Empty) convexHull2 = new ConvexHull(corners, Color.Black, item); + + UpdateConvexHulls(); } public override void Remove() diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index adba60532..1b12d2454 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -148,6 +148,8 @@ namespace Barotrauma.Lights cachedShadows.Clear(); vertices = points; + + CalculateDimensions(); } public bool Intersects(Rectangle rect) @@ -307,6 +309,7 @@ namespace Barotrauma.Lights else { cachedShadow = new CachedShadow(shadowVertices, penumbraVertices, light.Position, shadowVertexCount, 0); + cachedShadows.Remove(light); cachedShadows.Add(light, cachedShadow); } } @@ -350,7 +353,7 @@ namespace Barotrauma.Lights else { shadowEffect.CurrentTechnique.Passes[0].Apply(); - graphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, shadowVertexCount); + graphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, shadowVertexCount*2 - 2); } } diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index 5bf53393c..0eb9fee15 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -21,6 +21,9 @@ namespace Barotrauma.Lights public Entity Submarine; + //what was the range of the light when HullsInRange were last updated + private float prevHullUpdateRange; + private Vector2 position; public Vector2 Position { @@ -64,11 +67,11 @@ namespace Barotrauma.Lights set { - float prevRange = range; range = MathHelper.Clamp(value, 0.0f, 2048.0f); - if (Math.Abs(prevRange - range)<5.0f) return; + if (Math.Abs(prevHullUpdateRange - range)>5.0f) return; UpdateHullsInRange(); + prevHullUpdateRange = range; } } diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index e2868a5d5..f42e4a647 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -301,7 +301,10 @@ namespace Barotrauma public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List ignoredBodies = null, Category? collisionCategory = null) { - if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.0f) return null; + if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f) + { + rayEnd += Vector2.UnitX * 0.001f; + } float closestFraction = 1.0f; Body closestBody = null; diff --git a/Subsurface/Source/Map/TransitionCinematic.cs b/Subsurface/Source/Map/TransitionCinematic.cs index acd4cd5b9..6eb51f51e 100644 --- a/Subsurface/Source/Map/TransitionCinematic.cs +++ b/Subsurface/Source/Map/TransitionCinematic.cs @@ -55,12 +55,12 @@ namespace Barotrauma GUI.ScreenOverlayColor = Color.Lerp(Color.TransparentBlack, Color.Black, timer/duration); - cam.Translate((cameraPos - cam.Position) * CoroutineManager.DeltaTime); + cam.Translate((cameraPos - cam.Position) * CoroutineManager.DeltaTime*10.0f); cam.Zoom = Math.Max(0.2f, cam.Zoom - CoroutineManager.DeltaTime * 0.1f); sub.ApplyForce((Vector2.Normalize(diff) * targetSpeed - sub.Velocity) * 500.0f); - timer -= CoroutineManager.DeltaTime; + timer += CoroutineManager.DeltaTime; yield return CoroutineStatus.Running; } diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 992cae94e..3d3e15c38 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -356,7 +356,7 @@ namespace Barotrauma.Networking { if (myCharacter.IsDead) { - Character.Controlled = null; + //Character.Controlled = null; //GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; } else if (gameStarted) @@ -610,7 +610,7 @@ namespace Barotrauma.Networking (float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f), (float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f))); - GameMain.GameScreen.Cam.TargetPos = Submarine.Loaded.Position + offset * 0.8f; + GameMain.GameScreen.Cam.TargetPos = Submarine.Loaded.DrawPosition + offset * 0.8f; //Game1.GameScreen.Cam.MoveCamera((float)deltaTime); messageBox.Text = endMessage + "\nReturning to lobby in " + (int)secondsLeft + " s"; @@ -742,6 +742,7 @@ namespace Barotrauma.Networking float closestDist = 0.0f; foreach (WayPoint wp in WayPoint.WayPointList) { + if (wp.SpawnType != SpawnType.Human) continue; float dist = Vector2.Distance(wp.WorldPosition, position); if (closestWaypoint != null && dist > closestDist) continue; diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 1c1bb5bb2..3e2649c02 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -39,7 +39,15 @@ namespace Barotrauma { base.Select(); - if (Submarine.Loaded != null) cam.TargetPos = Submarine.Loaded.Position; + if (Character.Controlled!=null) + { + cam.Position = Character.Controlled.WorldPosition; + } + else if (Submarine.Loaded != null) + { + cam.Position = Submarine.Loaded.Position; + } + foreach (MapEntity entity in MapEntity.mapEntityList) entity.IsHighlighted = false; diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index e56595e34..4a6958866 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -839,7 +839,9 @@ namespace Barotrauma public bool TrySelectSub(string subName, string md5Hash) { - Submarine sub = Submarine.SavedSubmarines.Find(m => m.Name == subName); + subName = subName.ToLower(); + + Submarine sub = Submarine.SavedSubmarines.Find(m => m.Name.ToLower() == subName); if (sub == null) { new GUIMessageBox("Submarine not found!","The submarine ''" + subName + "'' has been selected by the server. Matching file not found in your map folder."); diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 2539b262f75bba33b63e6cd39f217ed100ed1a66..0593a725b1530ae4ba471a4fcf7e99860b43a65c 100644 GIT binary patch delta 16224 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 Tcw+oCOWSP5MNmSzU;Tdpyf%o| delta 14898 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 MR=m88ePPW10o7!0Y5)KL