From 41569675f31a3d677df52d7c6006e03240e9f0d2 Mon Sep 17 00:00:00 2001 From: Regalis11 Date: Thu, 9 Jun 2016 18:34:43 +0300 Subject: [PATCH 01/13] Started refactoring the submarine class in order to make it possible to add multiple submarines (or other movable structures) --- .vs/Subsurface_Solution/v14/.suo | Bin 783360 -> 837120 bytes Subsurface/Source/Camera.cs | 7 +- .../Source/Characters/AI/HumanAIController.cs | 6 +- .../Characters/AI/IndoorsSteeringManager.cs | 6 +- .../AI/Objectives/AIObjectiveGoTo.cs | 2 +- .../AI/Objectives/AIObjectiveIdle.cs | 2 +- .../Source/Characters/Animation/Ragdoll.cs | 2 +- Subsurface/Source/Characters/Character.cs | 12 ++-- Subsurface/Source/DebugConsole.cs | 15 ++-- Subsurface/Source/Events/ArtifactEvent.cs | 2 +- .../Source/Events/Missions/CargoMission.cs | 2 +- .../Source/Events/Missions/MonsterMission.cs | 2 +- .../Source/Events/Missions/SalvageMission.cs | 2 +- Subsurface/Source/Events/MonsterEvent.cs | 2 +- Subsurface/Source/GUI/GUI.cs | 4 +- .../GameSession/GameModes/SinglePlayerMode.cs | 14 ++-- .../GameSession/GameModes/TraitorMode.cs | 2 +- .../GameModes/Tutorials/BasicTutorial.cs | 12 ++-- .../GameModes/Tutorials/TutorialType.cs | 2 +- Subsurface/Source/GameSession/GameSession.cs | 2 +- .../Source/GameSession/InfoTextManager.cs | 2 +- Subsurface/Source/GameSession/ShiftSummary.cs | 2 +- .../Items/Components/Holdable/Holdable.cs | 2 +- .../Items/Components/Machines/Engine.cs | 2 +- .../Items/Components/Machines/MiniMap.cs | 8 ++- .../Source/Items/Components/Machines/Radar.cs | 33 +++++---- .../Items/Components/Machines/Steering.cs | 12 ++-- .../Source/Items/Components/Signal/Wire.cs | 10 +-- Subsurface/Source/Items/Item.cs | 2 +- Subsurface/Source/Items/ItemPrefab.cs | 14 ++-- Subsurface/Source/Map/Gap.cs | 14 ++-- Subsurface/Source/Map/Hull.cs | 4 +- Subsurface/Source/Map/Submarine.cs | 65 ++++++++++++------ 33 files changed, 151 insertions(+), 117 deletions(-) diff --git a/.vs/Subsurface_Solution/v14/.suo b/.vs/Subsurface_Solution/v14/.suo index 195ff13d26d5c6440664ad902ca3ae7e4082f9ff..188fc21d54af280052ad9995ae6d2807c2c2c798 100644 GIT binary patch delta 29178 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 delta 22784 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 200.0f && character.AnimController.CurrentHull!=null) return; diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index de4362d40..a78ac465a 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -594,7 +594,7 @@ namespace Barotrauma CurrentHull = newHull; - character.Submarine = CurrentHull == null ? null : Submarine.Loaded; + character.Submarine = currentHull == null ? null : currentHull.Submarine; UpdateCollisionCategories(); } diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 54d676f9b..bdbb31842 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -855,7 +855,10 @@ namespace Barotrauma } cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition); - if (AnimController.CurrentHull != null) cursorPosition -= Submarine.Loaded.Position; + if (AnimController.CurrentHull != null && AnimController.CurrentHull.Submarine != null) + { + cursorPosition -= AnimController.CurrentHull.Submarine.Position; + } Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); @@ -1006,12 +1009,9 @@ namespace Barotrauma if (needsAir) { bool protectedFromPressure = PressureProtection > 0.0f; - - if (Submarine.Loaded != null && Level.Loaded != null) - { - protectedFromPressure = protectedFromPressure && WorldPosition.Y > SubmarineBody.DamageDepth; - } + protectedFromPressure = protectedFromPressure && WorldPosition.Y > SubmarineBody.DamageDepth; + if (!protectedFromPressure && (AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure >= 80.0f)) { diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index d6d5ffd54..cec862549 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -213,8 +213,6 @@ namespace Barotrauma break; case "near": case "close": - if (Submarine.Loaded == null) break; - float closestDist = 0.0f; foreach (WayPoint wp in WayPoint.WayPointList) { @@ -223,7 +221,7 @@ namespace Barotrauma //don't spawn inside hulls if (Hull.FindHull(wp.WorldPosition, null) != null) continue; - float dist = Vector2.Distance(wp.WorldPosition, Submarine.Loaded.WorldPosition); + float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter); if (spawnPoint == null || dist < closestDist) { @@ -319,7 +317,9 @@ namespace Barotrauma Character.Controlled = Character.CharacterList.Find(c => !c.IsNetworkPlayer && c.Name.ToLowerInvariant() == commands[1]); break; case "godmode": - Submarine.Loaded.GodMode = !Submarine.Loaded.GodMode; + if (Submarine.MainSub == null) return; + + Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode; break; case "dumpids": int count = commands.Length < 2 ? 10 : int.Parse(commands[1]); @@ -438,8 +438,11 @@ namespace Barotrauma return; } - if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName +".sub"))) NewMessage("map saved", Color.Green); - Submarine.Loaded.CheckForErrors(); + if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub"))) + { + NewMessage("Sub saved", Color.Green); + //Submarine.Loaded.First().CheckForErrors(); + } break; case "loadmap": diff --git a/Subsurface/Source/Events/ArtifactEvent.cs b/Subsurface/Source/Events/ArtifactEvent.cs index eec8653d0..2ce06c449 100644 --- a/Subsurface/Source/Events/ArtifactEvent.cs +++ b/Subsurface/Source/Events/ArtifactEvent.cs @@ -55,7 +55,7 @@ namespace Barotrauma state = 2; break; case 2: - if (!Submarine.Loaded.AtEndPosition && !Submarine.Loaded.AtStartPosition) return; + if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) return; Finished(); state = 3; diff --git a/Subsurface/Source/Events/Missions/CargoMission.cs b/Subsurface/Source/Events/Missions/CargoMission.cs index 27bb8dbe8..17002449c 100644 --- a/Subsurface/Source/Events/Missions/CargoMission.cs +++ b/Subsurface/Source/Events/Missions/CargoMission.cs @@ -96,7 +96,7 @@ namespace Barotrauma public override void End() { - if (Submarine.Loaded != null && Submarine.Loaded.AtEndPosition) + if (Submarine.MainSub != null && Submarine.MainSub.AtEndPosition) { int deliveredItemCount = items.Count(i => i.CurrentHull != null && i.Condition > 0.0f); diff --git a/Subsurface/Source/Events/Missions/MonsterMission.cs b/Subsurface/Source/Events/Missions/MonsterMission.cs index afab51956..503febcaa 100644 --- a/Subsurface/Source/Events/Missions/MonsterMission.cs +++ b/Subsurface/Source/Events/Missions/MonsterMission.cs @@ -44,7 +44,7 @@ namespace Barotrauma radarPosition = monster.Position; } else if (GameMain.Client == null) - { Vector2 diff = monster.WorldPosition-Submarine.Loaded.WorldPosition; + { Vector2 diff = monster.WorldPosition - Submarine.MainSub.WorldPosition; monster.Enabled = FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) < NetConfig.CharacterIgnoreDistance; } diff --git a/Subsurface/Source/Events/Missions/SalvageMission.cs b/Subsurface/Source/Events/Missions/SalvageMission.cs index b418cd62e..e0309ea79 100644 --- a/Subsurface/Source/Events/Missions/SalvageMission.cs +++ b/Subsurface/Source/Events/Missions/SalvageMission.cs @@ -69,7 +69,7 @@ namespace Barotrauma state = 1; break; case 1: - if (!Submarine.Loaded.AtEndPosition && !Submarine.Loaded.AtStartPosition) return; + if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) return; ShowMessage(state); state = 2; break; diff --git a/Subsurface/Source/Events/MonsterEvent.cs b/Subsurface/Source/Events/MonsterEvent.cs index 1bd0e6eaa..7162c7937 100644 --- a/Subsurface/Source/Events/MonsterEvent.cs +++ b/Subsurface/Source/Events/MonsterEvent.cs @@ -83,7 +83,7 @@ namespace Barotrauma { if (monster.IsDead) continue; - if (!isStarted && Vector2.Distance(monster.WorldPosition, Submarine.Loaded.WorldPosition) < 5000.0f) isStarted = true; + if (!isStarted && Vector2.Distance(monster.WorldPosition, Submarine.MainSub.WorldPosition) < 5000.0f) isStarted = true; monstersDead = false; break; diff --git a/Subsurface/Source/GUI/GUI.cs b/Subsurface/Source/GUI/GUI.cs index 75ea8bcb7..a8f4c269d 100644 --- a/Subsurface/Source/GUI/GUI.cs +++ b/Subsurface/Source/GUI/GUI.cs @@ -414,10 +414,10 @@ namespace Barotrauma "Camera pos: " + GameMain.GameScreen.Cam.Position, new Vector2(10, 70), Color.White); - if (Submarine.Loaded!=null) + if (Submarine.MainSub != null) { spriteBatch.DrawString(Font, - "Sub pos: " + Submarine.Loaded.Position, + "Sub pos: " + Submarine.MainSub.Position, new Vector2(10, 90), Color.White); } } diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index 9e933d519..db0c3801d 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -143,14 +143,14 @@ namespace Barotrauma CrewManager.Draw(spriteBatch); - if (Submarine.Loaded == null) return; + if (Submarine.MainSub == null) return; - if (Submarine.Loaded.AtEndPosition) + if (Submarine.MainSub.AtEndPosition) { endShiftButton.Text = "Enter " + Map.SelectedLocation.Name; endShiftButton.Draw(spriteBatch); } - else if (Submarine.Loaded.AtStartPosition) + else if (Submarine.MainSub.AtStartPosition) { endShiftButton.Text = "Enter " + Map.CurrentLocation.Name; endShiftButton.Draw(spriteBatch); @@ -199,7 +199,7 @@ namespace Barotrauma if (success) { - if (Submarine.Loaded.AtEndPosition) + if (Submarine.MainSub.AtEndPosition) { Map.MoveToNextLocation(); } @@ -240,7 +240,7 @@ namespace Barotrauma { isRunning = false; - var cinematic = new TransitionCinematic(Submarine.Loaded, GameMain.GameScreen.Cam, 5.0f); + var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, 5.0f); SoundPlayer.OverrideMusicType = CrewManager.characters.Any(c => !c.IsDead) ? "endshift" : "crewdead"; @@ -253,12 +253,12 @@ namespace Barotrauma { while (cinematic.Running) { - if (Submarine.Loaded == null) yield return CoroutineStatus.Success; + if (Submarine.MainSub == null) yield return CoroutineStatus.Success; yield return CoroutineStatus.Running; } - if (Submarine.Loaded == null) yield return CoroutineStatus.Success; + if (Submarine.MainSub == null) yield return CoroutineStatus.Success; End(""); diff --git a/Subsurface/Source/GameSession/GameModes/TraitorMode.cs b/Subsurface/Source/GameSession/GameModes/TraitorMode.cs index 7051902a5..7c5d99018 100644 --- a/Subsurface/Source/GameSession/GameModes/TraitorMode.cs +++ b/Subsurface/Source/GameSession/GameModes/TraitorMode.cs @@ -95,7 +95,7 @@ namespace Barotrauma endMessage = traitorCharacter.Name + " was a traitor! "; endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her"; endMessage += " task was to assassinate " + targetCharacter.Name + ". "; - endMessage += (Submarine.Loaded.AtEndPosition) ? + endMessage += (Submarine.MainSub.AtEndPosition) ? "The task was unsuccessful - the has submarine reached its destination." : "The task was unsuccessful."; } diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs index 228b79063..a600e0cfc 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs @@ -22,7 +22,7 @@ namespace Barotrauma.Tutorials //spawn some fish next to the player GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(2, - Submarine.Loaded.Position + Character.Controlled.Position); + Submarine.MainSub.Position + Character.Controlled.Position); yield return new WaitForSeconds(4.0f); @@ -276,7 +276,7 @@ namespace Barotrauma.Tutorials infoBox = CreateInfoFrame("Steer the submarine downwards, heading further into the cavern."); - while (Submarine.Loaded.WorldPosition.Y > 24600.0f) + while (Submarine.MainSub.WorldPosition.Y > 24600.0f) { yield return CoroutineStatus.Running; } @@ -300,7 +300,7 @@ namespace Barotrauma.Tutorials bool broken = false; do { - Submarine.Loaded.Velocity = Vector2.Zero; + Submarine.MainSub.Velocity = Vector2.Zero; moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget); Vector2 steeringDir = windows[0].WorldPosition - moloch.WorldPosition; @@ -349,7 +349,7 @@ namespace Barotrauma.Tutorials } } - Submarine.Loaded.GodMode = true; + Submarine.MainSub.GodMode = true; var capacitor1 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent(); var capacitor2 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent(); @@ -462,7 +462,7 @@ namespace Barotrauma.Tutorials yield return CoroutineStatus.Running; } - Submarine.Loaded.GodMode = false; + Submarine.MainSub.GodMode = false; infoBox = CreateInfoFrame("The creature has died. Now you should fix the damages in the control room: " + "Grab a welding tool from the closet in the railgun room."); @@ -588,7 +588,7 @@ namespace Barotrauma.Tutorials GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; GameMain.LightManager.LosEnabled = false; - var cinematic = new TransitionCinematic(Submarine.Loaded, GameMain.GameScreen.Cam, 5.0f); + var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, 5.0f); while (cinematic.Running) { diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs index 36af62a21..502ec7ec2 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs @@ -36,7 +36,7 @@ namespace Barotrauma.Tutorials public virtual void Initialize() { - GameMain.GameSession = new GameSession(Submarine.Loaded, "", GameModePreset.list.Find(gm => gm.Name.ToLowerInvariant() == "tutorial")); + GameMain.GameSession = new GameSession(Submarine.MainSub, "", GameModePreset.list.Find(gm => gm.Name.ToLowerInvariant() == "tutorial")); (GameMain.GameSession.gameMode as TutorialMode).tutorialType = this; GameMain.GameSession.StartShift("tuto1"); diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index b16e0d567..901e59b26 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -121,7 +121,7 @@ namespace Barotrauma return; } - if (reloadSub || Submarine.Loaded != submarine) submarine.Load(); + if (reloadSub || Submarine.MainSub != submarine) submarine.Load(); if (level != null) { diff --git a/Subsurface/Source/GameSession/InfoTextManager.cs b/Subsurface/Source/GameSession/InfoTextManager.cs index 3e28cfc0a..78bca7b25 100644 --- a/Subsurface/Source/GameSession/InfoTextManager.cs +++ b/Subsurface/Source/GameSession/InfoTextManager.cs @@ -51,7 +51,7 @@ namespace Barotrauma string text = infoList[Rand.Int(infoList.Count)]; - if (Submarine.Loaded!=null) text = text.Replace("[sub]", Submarine.Loaded.Name); + if (Submarine.MainSub != null) text = text.Replace("[sub]", Submarine.MainSub.Name); if (GameMain.GameSession != null && GameMain.GameSession.Map != null) { if (GameMain.GameSession.Map.CurrentLocation!=null) diff --git a/Subsurface/Source/GameSession/ShiftSummary.cs b/Subsurface/Source/GameSession/ShiftSummary.cs index 45c13bb6a..6c4c03c52 100644 --- a/Subsurface/Source/GameSession/ShiftSummary.cs +++ b/Subsurface/Source/GameSession/ShiftSummary.cs @@ -32,7 +32,7 @@ namespace Barotrauma bool singleplayer = GameMain.NetworkMember == null; bool gameOver = gameSession.CrewManager.characters.All(c => c.IsDead); - bool progress = Submarine.Loaded.AtEndPosition; + bool progress = Submarine.MainSub.AtEndPosition; GUIFrame frame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.8f); diff --git a/Subsurface/Source/Items/Components/Holdable/Holdable.cs b/Subsurface/Source/Items/Components/Holdable/Holdable.cs index fffafd02e..4684d0a9e 100644 --- a/Subsurface/Source/Items/Components/Holdable/Holdable.cs +++ b/Subsurface/Source/Items/Components/Holdable/Holdable.cs @@ -101,7 +101,7 @@ namespace Barotrauma.Items.Components Msg = ""; } - if (attachedByDefault || (Screen.Selected == GameMain.EditMapScreen && Submarine.Loaded != null)) Use(1.0f); + if (attachedByDefault || (Screen.Selected == GameMain.EditMapScreen)) Use(1.0f); //holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f); diff --git a/Subsurface/Source/Items/Components/Machines/Engine.cs b/Subsurface/Source/Items/Components/Machines/Engine.cs index a97d3030c..bf3be00fe 100644 --- a/Subsurface/Source/Items/Components/Machines/Engine.cs +++ b/Subsurface/Source/Items/Components/Machines/Engine.cs @@ -86,7 +86,7 @@ namespace Barotrauma.Items.Components { Vector2 currForce = new Vector2((force / 100.0f) * maxForce * (voltage / minVoltage), 0.0f); - Submarine.Loaded.ApplyForce(currForce); + item.Submarine.ApplyForce(currForce); if (item.CurrentHull != null) { diff --git a/Subsurface/Source/Items/Components/Machines/MiniMap.cs b/Subsurface/Source/Items/Components/Machines/MiniMap.cs index a03ecc9d2..9e3f3e9f9 100644 --- a/Subsurface/Source/Items/Components/Machines/MiniMap.cs +++ b/Subsurface/Source/Items/Components/Machines/MiniMap.cs @@ -36,6 +36,8 @@ namespace Barotrauma.Items.Components public override void DrawHUD(SpriteBatch spriteBatch, Character character) { + if (item.Submarine == null) return; + int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height; int x = GuiFrame.Rect.X; int y = GuiFrame.Rect.Y; @@ -48,12 +50,12 @@ namespace Barotrauma.Items.Components Rectangle miniMap = new Rectangle(x + 20, y + 40, width - 40, height - 60); - float size = Math.Min((float)miniMap.Width / (float)Submarine.Borders.Width, (float)miniMap.Height / (float)Submarine.Borders.Height); + float size = Math.Min((float)miniMap.Width / (float)item.Submarine.Borders.Width, (float)miniMap.Height / (float)item.Submarine.Borders.Height); foreach (Hull hull in Hull.hullList) { Rectangle hullRect = new Rectangle( - miniMap.X + (int)((hull.Rect.X - Submarine.HiddenSubPosition.X - Submarine.Borders.X) * size), - miniMap.Y - (int)((hull.Rect.Y - Submarine.HiddenSubPosition.Y - Submarine.Borders.Y) * size), + miniMap.X + (int)((hull.Rect.X - Submarine.HiddenSubPosition.X - item.Submarine.Borders.X) * size), + miniMap.Y - (int)((hull.Rect.Y - Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size), (int)(hull.Rect.Width * size), (int)(hull.Rect.Height * size)); diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index be281b135..b35a82a98 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -124,38 +124,41 @@ namespace Barotrauma.Items.Components float radius = rect.Width / 2.0f; float displayScale = radius / range; - - if (DetectSubmarineWalls) + + foreach (Submarine submarine in Submarine.Loaded) { - for (int i = 0; i < Submarine.Loaded.HullVertices.Count; i++) - { - Vector2 start = ConvertUnits.ToDisplayUnits(Submarine.Loaded.HullVertices[i]); - Vector2 end = ConvertUnits.ToDisplayUnits(Submarine.Loaded.HullVertices[(i + 1) % Submarine.Loaded.HullVertices.Count]); + if (item.Submarine == submarine && !DetectSubmarineWalls) continue; - if (item.CurrentHull!=null) + for (int i = 0; i < submarine.HullVertices.Count; i++) + { + Vector2 start = ConvertUnits.ToDisplayUnits(submarine.HullVertices[i]); + Vector2 end = ConvertUnits.ToDisplayUnits(submarine.HullVertices[(i + 1) % submarine.HullVertices.Count]); + + if (item.Submarine == submarine) { start += Rand.Vector(500.0f); end += Rand.Vector(500.0f); } CreateBlipsForLine( - start + Submarine.Loaded.WorldPosition, - end + Submarine.Loaded.WorldPosition, + start + submarine.WorldPosition, + end + submarine.WorldPosition, radius, displayScale, 200.0f, 2.0f); } - } - else + + + if (item.Submarine != null && !DetectSubmarineWalls) { float simScale = displayScale * Physics.DisplayToSimRation; - Vector2 offset = ConvertUnits.ToSimUnits(Submarine.Loaded.WorldPosition - item.WorldPosition); + Vector2 offset = ConvertUnits.ToSimUnits(item.Submarine.WorldPosition - item.WorldPosition); - for (int i = 0; i < Submarine.Loaded.HullVertices.Count; i++) + for (int i = 0; i < item.Submarine.HullVertices.Count; i++) { - Vector2 start = (Submarine.Loaded.HullVertices[i] + offset) * simScale; + Vector2 start = (item.Submarine.HullVertices[i] + offset) * simScale; start.Y = -start.Y; - Vector2 end = (Submarine.Loaded.HullVertices[(i + 1) % Submarine.Loaded.HullVertices.Count] + offset) * simScale; + Vector2 end = (item.Submarine.HullVertices[(i + 1) % item.Submarine.HullVertices.Count] + offset) * simScale; end.Y = -end.Y; GUI.DrawLine(spriteBatch, center + start, center + end, Color.Green); diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index c625eeb59..78befa10e 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -163,10 +163,10 @@ namespace Barotrauma.Items.Components Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40); //GUI.DrawRectangle(spriteBatch, velRect, Color.White, false); - if (Submarine.Loaded != null && Level.Loaded != null) + if (item.Submarine != null && Level.Loaded != null) { - Vector2 realWorldVelocity = ConvertUnits.ToDisplayUnits(Submarine.Loaded.Velocity * Physics.DisplayToRealWorldRatio) * 3.6f; - float realWorldDepth = Math.Abs(Submarine.Loaded.Position.Y - Level.Loaded.Size.Y) * Physics.DisplayToRealWorldRatio; + Vector2 realWorldVelocity = ConvertUnits.ToDisplayUnits(item.Submarine.Velocity * Physics.DisplayToRealWorldRatio) * 3.6f; + float realWorldDepth = Math.Abs(item.Submarine.Position.Y - Level.Loaded.Size.Y) * Physics.DisplayToRealWorldRatio; GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 65), "Velocity: " + (int)realWorldVelocity.X + " km/h", Color.LightGreen, null, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 50), @@ -220,7 +220,7 @@ namespace Barotrauma.Items.Components if (autopilotRayCastTimer <= 0.0f && steeringPath.NextNode != null) { - Vector2 diff = Vector2.Normalize(ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - Submarine.Loaded.WorldPosition)); + Vector2 diff = Vector2.Normalize(ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - item.Submarine.WorldPosition)); bool nextVisible = true; for (int x = -1; x < 2; x += 2) @@ -228,9 +228,9 @@ namespace Barotrauma.Items.Components for (int y = -1; y < 2; y += 2) { Vector2 cornerPos = - new Vector2(Submarine.Borders.Width * x, Submarine.Borders.Height * y) / 2.0f; + new Vector2(item.Submarine.Borders.Width * x, item.Submarine.Borders.Height * y) / 2.0f; - cornerPos = ConvertUnits.ToSimUnits(cornerPos * 1.2f + Submarine.Loaded.WorldPosition); + cornerPos = ConvertUnits.ToSimUnits(cornerPos * 1.2f + item.Submarine.WorldPosition); float dist = Vector2.Distance(cornerPos, steeringPath.NextNode.SimPosition); diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index 9cb18be5f..fcd82f401 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -366,7 +366,7 @@ namespace Barotrauma.Items.Components for (int i = 0; i < Nodes.Count; i++) { Vector2 worldPos = Nodes[i]; - if (Submarine.Loaded != null) worldPos += Submarine.Loaded.Position + Submarine.HiddenSubPosition; + if (item.Submarine != null) worldPos += item.Submarine.Position + Submarine.HiddenSubPosition; worldPos.Y = -worldPos.Y; GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-3, -3), new Vector2(6, 6), item.Color, true, 0.0f); @@ -407,7 +407,7 @@ 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) - Submarine.HiddenSubPosition - Submarine.Loaded.Position;// Nodes[(int)selectedNodeIndex]; + Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - Submarine.HiddenSubPosition - item.Submarine.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); @@ -428,10 +428,10 @@ namespace Barotrauma.Items.Components private void DrawSection(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, float width = 0.3f) { - if (Submarine.Loaded!=null) + if (item.Submarine != null) { - start += Submarine.Loaded.DrawPosition + Submarine.HiddenSubPosition; - end += Submarine.Loaded.DrawPosition + Submarine.HiddenSubPosition; + start += item.Submarine.DrawPosition + Submarine.HiddenSubPosition; + end += item.Submarine.DrawPosition + Submarine.HiddenSubPosition; } start.Y = -start.Y; diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 4e9fb0134..511a0f707 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -525,7 +525,7 @@ namespace Barotrauma CurrentHull = Hull.FindHull(WorldPosition, CurrentHull); if (body != null) { - Submarine = CurrentHull == null ? null : Submarine.Loaded; + Submarine = CurrentHull == null ? null : CurrentHull.Submarine; body.Submarine = Submarine; } diff --git a/Subsurface/Source/Items/ItemPrefab.cs b/Subsurface/Source/Items/ItemPrefab.cs index e75d2e392..e23f345f3 100644 --- a/Subsurface/Source/Items/ItemPrefab.cs +++ b/Subsurface/Source/Items/ItemPrefab.cs @@ -109,7 +109,7 @@ namespace Barotrauma public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam) { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (PlayerInput.RightButtonClicked()) { @@ -121,10 +121,10 @@ namespace Barotrauma { if (PlayerInput.LeftButtonClicked()) { - var item = new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this, Submarine.Loaded); + var item = new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this, Submarine.MainSub); //constructor.Invoke(lobject); - item.Submarine = Submarine.Loaded; - item.SetTransform(ConvertUnits.ToSimUnits(Submarine.Loaded==null ? item.Position : item.Position - Submarine.Loaded.Position), 0.0f); + item.Submarine = Submarine.MainSub; + item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub==null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f); item.FindHull(); placePosition = Vector2.Zero; @@ -152,11 +152,11 @@ namespace Barotrauma if (PlayerInput.LeftButtonReleased()) { - var item = new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.Loaded); + var item = new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.MainSub); placePosition = Vector2.Zero; - item.Submarine = Submarine.Loaded; - item.SetTransform(ConvertUnits.ToSimUnits(Submarine.Loaded == null ? item.Position : item.Position - Submarine.Loaded.Position), 0.0f); + item.Submarine = Submarine.MainSub; + item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f); item.FindHull(); //selected = null; diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index 930cb574c..31452a2ca 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -83,7 +83,7 @@ namespace Barotrauma } public Gap(MapEntityPrefab prefab, Rectangle rectangle) - : this (rectangle, Submarine.Loaded) + : this (rectangle, Submarine.MainSub) { } public Gap(Rectangle newRect, Submarine submarine) @@ -253,7 +253,7 @@ namespace Barotrauma var particle = GameMain.ParticleManager.CreateParticle( "watersplash", - (Submarine.Loaded == null ? pos : pos + Submarine.Loaded.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f), + (Submarine == null ? pos : pos + Submarine.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f), velocity); if (particle != null) @@ -269,7 +269,7 @@ namespace Barotrauma GameMain.ParticleManager.CreateParticle( "bubbles", - Submarine.Loaded == null ? pos : pos + Submarine.Loaded.Position, + Submarine == null ? pos : pos + Submarine.Position, flowForce / 10.0f); } } @@ -288,14 +288,14 @@ namespace Barotrauma var splash = GameMain.ParticleManager.CreateParticle( "watersplash", - Submarine.Loaded == null ? pos : pos + Submarine.Loaded.Position, + Submarine == null ? pos : pos + Submarine.Position, -velocity, 0, FlowTargetHull); if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f); GameMain.ParticleManager.CreateParticle( "bubbles", - Submarine.Loaded == null ? pos : pos + Submarine.Loaded.Position, + Submarine == null ? pos : pos + Submarine.Position, flowForce / 2.0f, 0, FlowTargetHull); } } @@ -552,7 +552,7 @@ namespace Barotrauma } else { - hull1.LethalPressure += (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime; + hull1.LethalPressure += (Submarine != null && Submarine.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime; } } else @@ -567,7 +567,7 @@ namespace Barotrauma } if (hull1.Volume >= hull1.FullVolume - Hull.MaxCompress) { - hull1.LethalPressure += (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime; + hull1.LethalPressure += (Submarine != null && Submarine.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime; } } diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 6a92645a7..4f3f4f7ea 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -178,7 +178,7 @@ namespace Barotrauma } public Hull(MapEntityPrefab prefab, Rectangle rectangle) - : this (prefab, rectangle, Submarine.Loaded) + : this (prefab, rectangle, Submarine.MainSub) { } @@ -821,7 +821,7 @@ namespace Barotrauma } else { - var newFire = new FireSource(pos + Submarine.Loaded.Position, this, true); + var newFire = new FireSource(pos + Submarine.Position, this, true); newFire.Size = new Vector2( newFire.Hull == null ? size : size * newFire.Hull.rect.Width, newFire.Size.Y); diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 59446d81d..7c5da46d5 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -30,7 +30,8 @@ namespace Barotrauma public static readonly Vector2 GridSize = new Vector2(16.0f, 16.0f); - private static Submarine loaded; + public static Submarine MainSub; + private static List loaded; private SubmarineBody subBody; @@ -96,16 +97,16 @@ namespace Barotrauma } } - public static Submarine Loaded - { - get { return loaded; } - } + //public static List Loaded + //{ + // get { return loaded; } + //} - public static Rectangle Borders + public Rectangle Borders { get { - return (loaded==null) ? Rectangle.Empty : Loaded.subBody.Borders; + return subBody.Borders; } } @@ -255,17 +256,17 @@ namespace Barotrauma //math/physics stuff ---------------------------------------------------- - public static Vector2 MouseToWorldGrid(Camera cam) + public static Vector2 MouseToWorldGrid(Camera cam, Submarine sub) { Vector2 position = PlayerInput.MousePosition; position = cam.ScreenToWorld(position); Vector2 worldGridPos = VectorToWorldGrid(position); - if (loaded != null) + if (sub != null) { - worldGridPos.X += loaded.Position.X % GridSize.X; - worldGridPos.Y += loaded.Position.Y % GridSize.Y; + worldGridPos.X += sub.Position.X % GridSize.X; + worldGridPos.Y += sub.Position.Y % GridSize.Y; } return worldGridPos; @@ -435,6 +436,23 @@ namespace Barotrauma //Level.Loaded.Move(-amount); } + public static Submarine GetClosest(Vector2 worldPosition) + { + Submarine closest = null; + float closestDist = 0.0f; + foreach (Submarine sub in Submarine.loaded) + { + float dist = Vector2.Distance(worldPosition, sub.WorldPosition); + if (closest == null || dist < closestDist) + { + closest = sub; + closestDist = dist; + } + } + + return closest; + } + public override bool FillNetworkData(Networking.NetworkEventType type, NetBuffer message, object data) { if (subBody == null) return false; @@ -519,15 +537,17 @@ namespace Barotrauma public static bool SaveCurrent(string filePath) { - if (loaded==null) + if (!loaded.Any()) { - loaded = new Submarine(filePath); + loaded.Add(new Submarine(filePath)); // return; } - loaded.filePath = filePath; + System.Diagnostics.Debug.Assert(loaded.Count==1); - return loaded.SaveAs(filePath); + loaded.First().filePath = filePath; + + return loaded.First().SaveAs(filePath); } public void CheckForErrors() @@ -766,8 +786,8 @@ namespace Barotrauma subBody = new SubmarineBody(this); subBody.SetPosition(HiddenSubPosition); - - loaded = this; + + loaded.Add(this); Hull.GenerateEntityGrid(); @@ -809,16 +829,19 @@ namespace Barotrauma public static void Unload() { - if (loaded == null) return; Sound.OnGameEnd(); if (GameMain.LightManager != null) GameMain.LightManager.ClearLights(); - - loaded.Remove(); + + + foreach (Submarine sub in loaded) + { + sub.Remove(); + sub.Clear(); + } loaded.Clear(); - loaded = null; } private void Clear() From 7349cdd310babc9ff20ef7be0ce125243367b58f Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 9 Jun 2016 22:15:50 +0300 Subject: [PATCH 02/13] Progress (compiles now) --- .../Characters/AI/IndoorsSteeringManager.cs | 3 + Subsurface/Source/CoroutineManager.cs | 22 +-- Subsurface/Source/GameSession/GameSession.cs | 4 + .../Items/Components/Holdable/RepairTool.cs | 137 +++++++++--------- Subsurface/Source/Map/EntityGrid.cs | 26 +++- Subsurface/Source/Map/Hull.cs | 23 ++- Subsurface/Source/Map/Levels/Level.cs | 6 +- Subsurface/Source/Map/MapEntity.cs | 2 +- Subsurface/Source/Map/MapEntityPrefab.cs | 8 +- Subsurface/Source/Map/Structure.cs | 4 +- Subsurface/Source/Map/StructurePrefab.cs | 14 +- Subsurface/Source/Map/Submarine.cs | 12 +- Subsurface/Source/Map/WayPoint.cs | 79 +++++----- Subsurface/Source/Networking/GameClient.cs | 2 +- Subsurface/Source/Networking/GameServer.cs | 22 ++- Subsurface/Source/Program.cs | 2 +- Subsurface/Source/Screens/EditMapScreen.cs | 32 ++-- Subsurface/Source/Screens/GameScreen.cs | 19 ++- Subsurface/Source/Sounds/SoundPlayer.cs | 9 +- Subsurface/Source/Utils/SaveUtil.cs | 4 +- Subsurface_Solution.sln | 47 ------ Subsurface_Solution.v12.suo | Bin 385024 -> 385024 bytes 22 files changed, 237 insertions(+), 240 deletions(-) diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index c1e622deb..8c1ba6307 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -78,6 +78,7 @@ namespace Barotrauma Vector2 pos = host.SimPosition; if (character!=null && character.Submarine==null) { + //todo: take multiple subs into account pos -= Submarine.MainSub.SimPosition; } @@ -107,6 +108,7 @@ namespace Barotrauma Vector2 pos2 = host.SimPosition; if (character != null && character.Submarine == null) { + //todo: take multiple subs into account pos2 -= Submarine.MainSub.SimPosition; } return currentTarget-pos2; @@ -120,6 +122,7 @@ namespace Barotrauma Vector2 pos = host.SimPosition; if (character != null && character.Submarine == null) { + //todo: take multiple subs into account pos -= Submarine.MainSub.SimPosition; } diff --git a/Subsurface/Source/CoroutineManager.cs b/Subsurface/Source/CoroutineManager.cs index 7d9187e9c..a6b9929d5 100644 --- a/Subsurface/Source/CoroutineManager.cs +++ b/Subsurface/Source/CoroutineManager.cs @@ -86,21 +86,21 @@ namespace Barotrauma } } - try - { + //try + //{ Coroutines[i].Coroutine.MoveNext(); - } + //} - catch (Exception e) - { - DebugConsole.ThrowError("Coroutine " + Coroutines[i].Name + " threw an exception: " + e.Message); + //catch (Exception e) + //{ + // DebugConsole.ThrowError("Coroutine " + Coroutines[i].Name + " threw an exception: " + e.Message); -#if DEBUG - throw e; -#endif +//#if DEBUG +// throw e; +//#endif - Coroutines.RemoveAt(i); - } +// Coroutines.RemoveAt(i); +// } } } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index 901e59b26..d31140560 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -68,6 +68,8 @@ namespace Barotrauma public GameSession(Submarine submarine, string saveFile, GameModePreset gameModePreset = null, string missionType="") { + Submarine.MainSub = submarine; + GameMain.GameSession = this; CrewManager = new CrewManager(); @@ -88,6 +90,8 @@ namespace Barotrauma public GameSession(Submarine selectedSub, string saveFile, XDocument doc) : this(selectedSub, saveFile) { + Submarine.MainSub = submarine; + GameMain.GameSession = this; CrewManager = new CrewManager(); diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index e23911b06..b1d4037f1 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -132,80 +132,19 @@ namespace Barotrauma.Items.Components IsActive = true; activeTimer = 0.1f; + Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition); + Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition); - for (int n = 0; n < 2; n++) + if (character.Submarine == null) { - Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition); - Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition); - - if (n == 0) + foreach (Submarine sub in Submarine.Loaded) { - //do a raycast in "submarine coordinates" - rayStart -= Submarine.Loaded.SimPosition; - rayEnd -= Submarine.Loaded.SimPosition; + Repair(rayStart - sub.SimPosition, rayEnd - sub.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies); } - else - { - //do a raycast outside the sub if the character is outside - if (character.AnimController.CurrentHull != null) continue; - } - - Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies); - - pickedPosition = Submarine.LastPickedPosition; - - if (ExtinquishAmount > 0.0f) - { - Vector2 displayPos = rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f; - Hull hull = Hull.FindHull(displayPos, item.CurrentHull); - if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); - } - - if (targetBody == null || targetBody.UserData == null) continue; - - Structure targetStructure; - Limb targetLimb; - Item targetItem; - if ((targetStructure = (targetBody.UserData as Structure)) != null) - { - if (!fixableEntities.Contains(targetStructure.Name)) continue; - - int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition)); - if (sectionIndex < 0) continue; - - targetStructure.HighLightSection(sectionIndex); - - targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess); - - //if the next section is small enough, apply the effect to it as well - //(to make it easier to fix a small "left-over" section) - for (int i = -1; i < 2; i += 2) - { - int nextSectionLength = targetStructure.SectionLength(sectionIndex + i); - if ((sectionIndex == 1 && i == -1) || - (sectionIndex == targetStructure.SectionCount - 2 && i == 1) || - (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)) - { - targetStructure.HighLightSection(sectionIndex + i); - targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess); - } - } - - - } - else if ((targetLimb = (targetBody.UserData as Limb)) != null) - { - if (character.IsKeyDown(InputType.Aim)) - { - targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, character); - } - } - else if ((targetItem = (targetBody.UserData as Item)) != null) - { - targetItem.IsHighlighted = true; - - ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); - } + } + else + { + Repair(rayStart, rayEnd, deltaTime, character, degreeOfSuccess, ignoredBodies); } GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition + TransformedBarrelPos, @@ -214,6 +153,64 @@ namespace Barotrauma.Items.Components return true; } + private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List ignoredBodies) + { + + Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies); + + pickedPosition = Submarine.LastPickedPosition; + + if (ExtinquishAmount > 0.0f) + { + Vector2 displayPos = rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f; + Hull hull = Hull.FindHull(displayPos, item.CurrentHull); + if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); + } + + if (targetBody == null || targetBody.UserData == null) return; + + Structure targetStructure; + Limb targetLimb; + Item targetItem; + if ((targetStructure = (targetBody.UserData as Structure)) != null) + { + if (!fixableEntities.Contains(targetStructure.Name)) return; + + int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition)); + if (sectionIndex < 0) return; + + targetStructure.HighLightSection(sectionIndex); + + targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess); + + //if the next section is small enough, apply the effect to it as well + //(to make it easier to fix a small "left-over" section) + for (int i = -1; i < 2; i += 2) + { + int nextSectionLength = targetStructure.SectionLength(sectionIndex + i); + if ((sectionIndex == 1 && i == -1) || + (sectionIndex == targetStructure.SectionCount - 2 && i == 1) || + (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)) + { + targetStructure.HighLightSection(sectionIndex + i); + targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess); + } + } + + + } + else if ((targetLimb = (targetBody.UserData as Limb)) != null) + { + targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user); + } + else if ((targetItem = (targetBody.UserData as Item)) != null) + { + targetItem.IsHighlighted = true; + + ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); + } + } + public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { Gap leak = objective.OperateTarget as Gap; diff --git a/Subsurface/Source/Map/EntityGrid.cs b/Subsurface/Source/Map/EntityGrid.cs index b5b5b9d90..8641b6539 100644 --- a/Subsurface/Source/Map/EntityGrid.cs +++ b/Subsurface/Source/Map/EntityGrid.cs @@ -12,9 +12,12 @@ namespace Barotrauma private float cellSize; - public EntityGrid(Rectangle limits, float cellSize) + public readonly Submarine Submarine; + + public EntityGrid(Submarine submarine, float cellSize) { - this.limits = limits; + this.limits = submarine.Borders; + this.Submarine = submarine; this.cellSize = cellSize; entities = new List[(int)Math.Ceiling(limits.Width / cellSize), (int)Math.Ceiling(limits.Height / cellSize)]; @@ -71,11 +74,28 @@ namespace Barotrauma } } + public static List GetEntities(List entityGrids, Vector2 position, bool useWorldCoordinates = true) + { + List entities = new List(); + foreach (EntityGrid entityGrid in entityGrids) + { + Vector2 transformedPosition = position; + if (useWorldCoordinates) + { + transformedPosition -= entityGrid.Submarine.Position; + } + + entities.AddRange(entityGrid.GetEntities(position)); + } + + return entities; + } + public List GetEntities(Vector2 position) { if (!MathUtils.IsValid(position)) new List(); - if (Submarine.Loaded != null) position -= Submarine.HiddenSubPosition; + if (Submarine != null) position -= Submarine.HiddenSubPosition; Point indices = GetIndices(position); diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 813119bf8..d124b5305 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -15,7 +15,7 @@ namespace Barotrauma class Hull : MapEntity, IPropertyObject { public static List hullList = new List(); - private static EntityGrid entityGrid; + private static List entityGrids = new List(); public static bool ShowHulls = true; @@ -248,13 +248,15 @@ namespace Barotrauma return rect; } - public static void GenerateEntityGrid() + public static void GenerateEntityGrid(Submarine submarine) { - entityGrid = new EntityGrid(Submarine.Borders, 200.0f); + var newGrid = new EntityGrid(submarine, 200.0f); + + entityGrids.Add(newGrid); foreach (Hull hull in hullList) { - entityGrid.InsertEntity(hull); + if (hull.Submarine == submarine) newGrid.InsertEntity(hull); } } @@ -313,8 +315,14 @@ namespace Barotrauma } //renderer.Dispose(); + if (entityGrids != null) + { + foreach (EntityGrid entityGrid in entityGrids) + { + entityGrid.RemoveEntity(this); + } + } - if (entityGrid != null) entityGrid.RemoveEntity(this); hullList.Remove(this); } @@ -652,15 +660,14 @@ namespace Barotrauma //returns the water block which contains the point (or null if it isn't inside any) public static Hull FindHull(Vector2 position, Hull guess = null, bool useWorldCoordinates = true) { - if (entityGrid == null) return null; + if (entityGrids == null) return null; if (guess != null) { if (Submarine.RectContains(useWorldCoordinates ? guess.WorldRect : guess.rect, position)) return guess; } - var entities = entityGrid.GetEntities( - useWorldCoordinates && Submarine.Loaded!=null ? position-Submarine.Loaded.Position : position); + var entities = EntityGrid.GetEntities(entityGrids, position, useWorldCoordinates); foreach (Hull hull in entities) { diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index 338de50a6..8a34933fa 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -181,7 +181,7 @@ namespace Barotrauma float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3; GameMain.LightManager.AmbientLight = new Color(backgroundColor*(40.0f/avgValue), 1.0f); - float minWidth = Submarine.Loaded == null ? 0.0f : Math.Max(Submarine.Borders.Width, Submarine.Borders.Height); + float minWidth = Submarine.MainSub == null ? 0.0f : Math.Max(Submarine.MainSub.Borders.Width, Submarine.MainSub.Borders.Height); minWidth = Math.Max(minWidth, 6500.0f); startPosition = new Vector2(minWidth * 2, Rand.Range(minWidth * 2, borders.Height - minWidth * 2, false)); @@ -783,9 +783,9 @@ namespace Barotrauma public void Update (float deltaTime) { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - WrappingWall.UpdateWallShift(Submarine.Loaded.WorldPosition, wrappingWalls); + WrappingWall.UpdateWallShift(Submarine.MainSub.WorldPosition, wrappingWalls); } renderer.Update(deltaTime); diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 0e9867f99..e1fa83562 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -518,7 +518,7 @@ namespace Barotrauma Vector2 placePosition = new Vector2(rect.X, rect.Y); Vector2 placeSize = new Vector2(rect.Width, rect.Height); - Vector2 mousePos = Submarine.MouseToWorldGrid(cam); + Vector2 mousePos = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (resizeDirX >0) { diff --git a/Subsurface/Source/Map/MapEntityPrefab.cs b/Subsurface/Source/Map/MapEntityPrefab.cs index f4056f461..c16577b7d 100644 --- a/Subsurface/Source/Map/MapEntityPrefab.cs +++ b/Subsurface/Source/Map/MapEntityPrefab.cs @@ -128,7 +128,7 @@ namespace Barotrauma if (placePosition == Vector2.Zero) { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); GUI.DrawLine(spriteBatch, new Vector2(position.X-GameMain.GraphicsWidth, -position.Y), new Vector2(position.X+GameMain.GraphicsWidth, -position.Y), Color.White); @@ -138,7 +138,7 @@ namespace Barotrauma } else { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (resizeHorizontal) placeSize.X = position.X - placePosition.X; if (resizeVertical) placeSize.Y = placePosition.Y - position.Y; @@ -147,9 +147,9 @@ namespace Barotrauma newRect.Width = (int)Math.Max(newRect.Width, Submarine.GridSize.X); newRect.Height = (int)Math.Max(newRect.Height, Submarine.GridSize.Y); - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - newRect.Location -= Submarine.Loaded.Position.ToPoint(); + newRect.Location -= Submarine.MainSub.Position.ToPoint(); } if (PlayerInput.LeftButtonReleased()) diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 6298baf60..349498bb3 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -520,7 +520,7 @@ namespace Barotrauma public AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false) { - if (Submarine.Loaded != null && Submarine.Loaded.GodMode && Submarine == Submarine.Loaded) return new AttackResult(0.0f, 0.0f); + if (Submarine != null && Submarine.GodMode) return new AttackResult(0.0f, 0.0f); if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f); Vector2 transformedPos = worldPosition; @@ -546,7 +546,7 @@ namespace Barotrauma private void SetDamage(int sectionIndex, float damage) { - if (Submarine.Loaded != null && Submarine.Loaded.GodMode) return; + if (Submarine != null && Submarine.GodMode) return; if (!prefab.HasBody) return; if (!MathUtils.IsValid(damage)) return; diff --git a/Subsurface/Source/Map/StructurePrefab.cs b/Subsurface/Source/Map/StructurePrefab.cs index abedc550c..9d9f7f123 100644 --- a/Subsurface/Source/Map/StructurePrefab.cs +++ b/Subsurface/Source/Map/StructurePrefab.cs @@ -128,7 +128,7 @@ namespace Barotrauma public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam) { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); //Vector2 placeSize = size; Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y); @@ -137,7 +137,7 @@ namespace Barotrauma if (placePosition == Vector2.Zero) { if (PlayerInput.LeftButtonHeld()) - placePosition = Submarine.MouseToWorldGrid(cam); + placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); newRect.X = (int)position.X; newRect.Y = (int)position.Y; @@ -154,14 +154,10 @@ namespace Barotrauma if (PlayerInput.LeftButtonReleased()) { - if (Submarine.Loaded != null) - { - newRect.Location -= Submarine.Loaded.Position.ToPoint(); - } + newRect.Location -= Submarine.MainSub.Position.ToPoint(); - var structure = new Structure(newRect, this, Submarine.Loaded); - - structure.Submarine = Submarine.Loaded; + var structure = new Structure(newRect, this, Submarine.MainSub); + structure.Submarine = Submarine.MainSub; selected = null; return; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 7c5da46d5..87382b78c 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -31,7 +31,7 @@ namespace Barotrauma public static readonly Vector2 GridSize = new Vector2(16.0f, 16.0f); public static Submarine MainSub; - private static List loaded; + private static List loaded = new List(); private SubmarineBody subBody; @@ -97,10 +97,10 @@ namespace Barotrauma } } - //public static List Loaded - //{ - // get { return loaded; } - //} + public static List Loaded + { + get { return loaded; } + } public Rectangle Borders { @@ -789,7 +789,7 @@ namespace Barotrauma loaded.Add(this); - Hull.GenerateEntityGrid(); + Hull.GenerateEntityGrid(this); for (int i = 0; i < MapEntity.mapEntityList.Count; i++) { diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 2197edc70..9854a9348 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -83,7 +83,7 @@ namespace Barotrauma } public WayPoint(MapEntityPrefab prefab, Rectangle rectangle) - : this (rectangle, Submarine.Loaded) + : this (rectangle, Submarine.MainSub) { if (prefab.Name.Contains("Spawn")) { @@ -306,7 +306,7 @@ namespace Barotrauma return editingHUD; } - public static void GenerateSubWaypoints() + public static void GenerateSubWaypoints(Submarine submarine) { if (!Hull.hullList.Any()) { @@ -332,13 +332,13 @@ namespace Barotrauma if (hull.Rect.Width(); if (door != null) { - WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, Submarine.Loaded); + WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, submarine); newPoint.Ladders = ladders; newPoint.ConnectedGap = door.LinkedGap; @@ -538,7 +539,7 @@ namespace Barotrauma if (gap.Rect.Height < 150.0f) continue; var wayPoint = new WayPoint( - new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height + heightFromFloor), SpawnType.Path, Submarine.Loaded, gap); + new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height + heightFromFloor), SpawnType.Path, submarine, gap); for (int dir = -1; dir <= 1; dir += 2) { @@ -557,7 +558,7 @@ namespace Barotrauma if (gap.Rect.Width < 100.0f) continue; var wayPoint = new WayPoint( - new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height/2), SpawnType.Path, Submarine.Loaded, gap); + new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height/2), SpawnType.Path, submarine, gap); for (int dir = -1; dir <= 1; dir += 2) { @@ -583,35 +584,35 @@ namespace Barotrauma WayPoint closest = null; - foreach (WayPoint wp in WayPointList) + foreach (WayPoint wp in WayPointList) + { + if (wp.SpawnType != SpawnType.Path || wp == this) continue; + + float diff = 0.0f; + if (horizontalSearch) { - if (wp.SpawnType != SpawnType.Path || wp == this) continue; + if ((wp.Position.Y - Position.Y) < tolerance.X || (wp.Position.Y - Position.Y) > tolerance.Y) continue; - float diff = 0.0f; - if (horizontalSearch) - { - if ((wp.Position.Y - Position.Y) < tolerance.X || (wp.Position.Y - Position.Y) > tolerance.Y) continue; - - diff = wp.Position.X - Position.X; - } - else - { - if ((wp.Position.X - Position.X) < tolerance.X || (wp.Position.X - Position.X) > tolerance.Y) continue; - - diff = wp.Position.Y - Position.Y; - } - - if (Math.Sign(diff) != dir) continue; - - float dist = Vector2.Distance(wp.Position, Position); - if (closest == null || dist < closestDist) - { - if (Submarine.CheckVisibility(SimPosition, wp.SimPosition) != null) continue; - - closestDist = dist; - closest = wp; - } + diff = wp.Position.X - Position.X; } + else + { + if ((wp.Position.X - Position.X) < tolerance.X || (wp.Position.X - Position.X) > tolerance.Y) continue; + + diff = wp.Position.Y - Position.Y; + } + + if (Math.Sign(diff) != dir) continue; + + float dist = Vector2.Distance(wp.Position, Position); + if (closest == null || dist < closestDist) + { + if (Submarine.CheckVisibility(SimPosition, wp.SimPosition) != null) continue; + + closestDist = dist; + closest = wp; + } + } return closest; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 0cc704603..905d2e5e1 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -729,7 +729,7 @@ namespace Barotrauma.Networking if (Screen.Selected == GameMain.GameScreen) { - var cinematic = new TransitionCinematic(Submarine.Loaded, GameMain.GameScreen.Cam, endPreviewLength); + var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength); float secondsLeft = endPreviewLength; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index f15001b48..0ea8f8c99 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -289,7 +289,7 @@ namespace Barotrauma.Networking //restart if all characters are dead or submarine is at the end of the level if ((autoRestart && isCrewDead) || - (endRoundAtLevelEnd && Submarine.Loaded!=null && Submarine.Loaded.AtEndPosition)) + (endRoundAtLevelEnd && Submarine.MainSub != null && Submarine.MainSub.AtEndPosition)) { if (AutoRestart && isCrewDead) { @@ -363,7 +363,8 @@ namespace Barotrauma.Networking { if (!(c is AICharacter) || c.IsDead) continue; - Vector2 diff = c.WorldPosition-Submarine.Loaded.WorldPosition; + //todo: take multiple subs into account + Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; @@ -389,7 +390,13 @@ namespace Barotrauma.Networking private void SparseUpdate() { - if (gameStarted) new NetworkEvent(Submarine.Loaded.ID, false); + if (gameStarted) + { + foreach (Submarine sub in Submarine.Loaded) + { + new NetworkEvent(sub.ID, false); + } + } foreach (Character c in Character.CharacterList) { @@ -397,7 +404,8 @@ namespace Barotrauma.Networking if (c is AICharacter) { - Vector2 diff = c.WorldPosition - Submarine.Loaded.WorldPosition; + //todo: take multiple subs into account + Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; } @@ -601,7 +609,7 @@ namespace Barotrauma.Networking case (byte)PacketTypes.SpectateRequest: if (gameStarted && allowSpectating) { - var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset); + var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset); server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered); dataSender.Spectating = true; @@ -985,7 +993,7 @@ namespace Barotrauma.Networking GameMain.GameSession.CrewManager.characters.Add(myCharacter); } - var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset); + var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset); SendMessage(startMessage, NetDeliveryMethod.ReliableUnordered); @@ -1113,7 +1121,7 @@ namespace Barotrauma.Networking float endPreviewLength = 10.0f; - var cinematic = new TransitionCinematic(Submarine.Loaded, GameMain.GameScreen.Cam, endPreviewLength); + var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength); float secondsLeft = endPreviewLength; diff --git a/Subsurface/Source/Program.cs b/Subsurface/Source/Program.cs index d330ef949..a9467f510 100644 --- a/Subsurface/Source/Program.cs +++ b/Subsurface/Source/Program.cs @@ -65,7 +65,7 @@ namespace Barotrauma sb.AppendLine("Game version " + GameMain.Version); sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name); sb.AppendLine("Level seed: "+ ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); - sb.AppendLine("Loaded submarine: " + ((Submarine.Loaded == null) ? "none" : Submarine.Loaded.Name +" ("+Submarine.Loaded.MD5Hash+")")); + sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "none" : Submarine.MainSub.Name +" ("+Submarine.MainSub.MD5Hash+")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.Server != null) diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index eccca1c49..2e17f1da8 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -46,7 +46,7 @@ namespace Barotrauma public string GetSubName() { - return ((Submarine.Loaded == null) ? "" : Submarine.Loaded.Name); + return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Name; } private string GetItemCount() @@ -231,11 +231,11 @@ namespace Barotrauma GUIComponent.MouseOn = null; characterMode = false; - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - cam.Position = Submarine.Loaded.Position + Submarine.HiddenSubPosition; - nameBox.Text = Submarine.Loaded.Name; - descriptionBox.Text = ToolBox.LimitString(Submarine.Loaded.Description,15); + cam.Position = Submarine.MainSub.Position + Submarine.HiddenSubPosition; + nameBox.Text = Submarine.MainSub.Name; + descriptionBox.Text = ToolBox.LimitString(Submarine.MainSub.Description, 15); } else { @@ -303,9 +303,9 @@ namespace Barotrauma string savePath = nameBox.Text + ".sub"; - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - savePath = Path.Combine(Path.GetDirectoryName(Submarine.Loaded.FilePath), savePath); + savePath = Path.Combine(Path.GetDirectoryName(Submarine.MainSub.FilePath), savePath); } else { @@ -313,9 +313,9 @@ namespace Barotrauma } Submarine.SaveCurrent(savePath); - Submarine.Loaded.CheckForErrors(); + Submarine.MainSub.CheckForErrors(); - GUI.AddMessage("Submarine saved to " + Submarine.Loaded.FilePath, Color.Green, 3.0f); + GUI.AddMessage("Submarine saved to " + Submarine.MainSub.FilePath, Color.Green, 3.0f); return false; } @@ -560,7 +560,7 @@ namespace Barotrauma return false; } - if (Submarine.Loaded != null) Submarine.Loaded.Name = text; + if (Submarine.MainSub != null) Submarine.MainSub.Name = text; textBox.Deselect(); textBox.Text = text; @@ -572,9 +572,9 @@ namespace Barotrauma private bool ChangeSubDescription(GUITextBox textBox, string text) { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - Submarine.Loaded.Description = text; + Submarine.MainSub.Description = text; } else { @@ -593,9 +593,9 @@ namespace Barotrauma private void ExpandDescriptionBox(GUITextBox textBox, Keys key) { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - textBox.Text = Submarine.Loaded.Description; + textBox.Text = Submarine.MainSub.Description; } else if (textBox.UserData is string) { @@ -617,7 +617,9 @@ namespace Barotrauma private bool GenerateWaypoints(GUIButton button, object obj) { - WayPoint.GenerateSubWaypoints(); + if (Submarine.MainSub == null) return false; + + WayPoint.GenerateSubWaypoints(Submarine.MainSub); return true; } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index a00726b7c..1532eeea0 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -56,9 +56,9 @@ namespace Barotrauma { cam.Position = Character.Controlled.WorldPosition; } - else if (Submarine.Loaded != null) + else if (Submarine.MainSub != null) { - cam.Position = Submarine.Loaded.WorldPosition; + cam.Position = Submarine.MainSub.WorldPosition; } foreach (MapEntity entity in MapEntity.mapEntityList) @@ -119,9 +119,11 @@ namespace Barotrauma //Lights.LightManager.ViewPos = Character.Controlled.WorldPosition; } cam.MoveCamera((float)Physics.step); - - - if (Submarine.Loaded != null) Submarine.Loaded.SetPrevTransform(Submarine.Loaded.Position); + + foreach (Submarine sub in Submarine.Loaded) + { + sub.SetPrevTransform(sub.Position); + } foreach (PhysicsBody pb in PhysicsBody.list) { @@ -175,7 +177,7 @@ namespace Barotrauma if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch); - if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.Loaded); + if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.MainSub); GUI.Draw((float)deltaTime, spriteBatch, cam); @@ -187,7 +189,10 @@ namespace Barotrauma public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch) { - if (Submarine.Loaded != null) Submarine.Loaded.UpdateTransform(); + foreach (Submarine sub in Submarine.Loaded) + { + sub.UpdateTransform(); + } GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision; diff --git a/Subsurface/Source/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs index 6663693a2..59606fefd 100644 --- a/Subsurface/Source/Sounds/SoundPlayer.cs +++ b/Subsurface/Source/Sounds/SoundPlayer.cs @@ -183,7 +183,8 @@ namespace Barotrauma startDrone = null; } - if (Submarine.Loaded==null) + //todo: ambient sounds for multiple subs + if (Submarine.MainSub == null) { for (int i = 0; i < waterAmbienceIndexes.Length; i++) { @@ -213,9 +214,9 @@ namespace Barotrauma //how fast the sub is moving, scaled to 0.0 -> 1.0 float movementFactor = 0.0f; - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - movementFactor = (Submarine.Loaded.Velocity == Vector2.Zero) ? 0.0f : Submarine.Loaded.Velocity.Length() / 5.0f; + movementFactor = (Submarine.MainSub.Velocity == Vector2.Zero) ? 0.0f : Submarine.MainSub.Velocity.Length() / 5.0f; movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f); } @@ -303,7 +304,7 @@ namespace Barotrauma { return musicClips.Where(x => x != null && x.type == "ruins").ToList(); } - else if (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) + else if (Submarine.MainSub != null && Submarine.MainSub.AtDamageDepth) { return musicClips.Where(x => x != null && x.type == "deep").ToList(); } diff --git a/Subsurface/Source/Utils/SaveUtil.cs b/Subsurface/Source/Utils/SaveUtil.cs index cd6903cd3..cf4f714d1 100644 --- a/Subsurface/Source/Utils/SaveUtil.cs +++ b/Subsurface/Source/Utils/SaveUtil.cs @@ -30,9 +30,9 @@ namespace Barotrauma try { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - Submarine.Loaded.SaveAs(Path.Combine(tempPath, Submarine.Loaded.Name+".sub")); + Submarine.MainSub.SaveAs(Path.Combine(tempPath, Submarine.MainSub.Name+".sub")); } } catch (Exception e) diff --git a/Subsurface_Solution.sln b/Subsurface_Solution.sln index acdb73956..19e687774 100644 --- a/Subsurface_Solution.sln +++ b/Subsurface_Solution.sln @@ -11,8 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network", "Lidgren. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launcher", "Launcher2\Launcher.csproj", "{251AAFE1-F24B-4837-9128-9D04FCBFD528}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrashReporter", "CrashReporter\CrashReporter.csproj", "{6BE950CD-9A34-49C9-939A-786AC89C287E}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D32A29D8-AC7B-4189-B734-8ED9EB4120D0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hyper.ComponentModel", "Hyper.ComponentModel\Hyper.ComponentModel.csproj", "{3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}" @@ -228,51 +226,6 @@ Global {251AAFE1-F24B-4837-9128-9D04FCBFD528}.Windows8|Mixed Platforms.Build.0 = Release|x86 {251AAFE1-F24B-4837-9128-9D04FCBFD528}.Windows8|x86.ActiveCfg = Release|x86 {251AAFE1-F24B-4837-9128-9D04FCBFD528}.Windows8|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|Any CPU.ActiveCfg = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|x86.ActiveCfg = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|x86.Build.0 = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|x86.Build.0 = Release|x86 {3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}.Android|Any CPU.ActiveCfg = Release|Any CPU {3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}.Android|Any CPU.Build.0 = Release|Any CPU {3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}.Android|Mixed Platforms.ActiveCfg = Release|Any CPU diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index fd7b05d759a106c14de4c06e169dc44c9022020d..ab8b5bd6d7356afa1875ffd39fd3b9de1e534392 100644 GIT binary patch delta 11161 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 Date: Fri, 10 Jun 2016 20:53:35 +0300 Subject: [PATCH 03/13] "Shifting" entity IDs to prevent them from overlapping between different subs, loading another submarine now works without crashing --- Subsurface/Source/DebugConsole.cs | 8 +-- .../GameModes/Tutorials/TutorialMode.cs | 2 +- Subsurface/Source/GameSession/GameSession.cs | 7 ++- .../Items/Components/Machines/MiniMap.cs | 4 +- .../Source/Items/Components/Signal/Wire.cs | 18 +++--- Subsurface/Source/Items/ItemSpawner.cs | 3 +- Subsurface/Source/Map/Entity.cs | 2 +- Subsurface/Source/Map/EntityGrid.cs | 2 +- Subsurface/Source/Map/MapEntity.cs | 5 +- Subsurface/Source/Map/Submarine.cs | 56 ++++++++++++++----- Subsurface/Source/Map/SubmarineBody.cs | 2 +- Subsurface/Source/Map/TransitionCinematic.cs | 2 +- Subsurface/Source/Map/WayPoint.cs | 6 +- Subsurface/Source/Screens/EditMapScreen.cs | 10 ++-- 14 files changed, 83 insertions(+), 44 deletions(-) diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index cec862549..76ccb4097 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -296,12 +296,12 @@ namespace Barotrauma case "edit": if (commands.Length>1) { - Submarine.Load(string.Join(" ", commands.Skip(1))); + Submarine.Load(string.Join(" ", commands.Skip(1)), true); } GameMain.EditMapScreen.Select(); break; case "test": - Submarine.Load("aegir mark ii"); + Submarine.Load("aegir mark ii", true); GameMain.DebugDraw = true; GameMain.LightManager.LosEnabled = false; GameMain.EditMapScreen.Select(); @@ -450,10 +450,10 @@ namespace Barotrauma case "load": if (commands.Length < 2) break; - Submarine.Load(string.Join(" ", commands.Skip(1))); + Submarine.Load(string.Join(" ", commands.Skip(1)), true); break; case "cleansub": - for (int i = MapEntity.mapEntityList.Count-1; i>=0; i--) + for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--) { MapEntity me = MapEntity.mapEntityList[i]; diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs index 5a16434a4..d0b80c2ca 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialMode.cs @@ -9,7 +9,7 @@ namespace Barotrauma public static void StartTutorial(TutorialType tutorialType) { - Submarine.Load("Content/Map/TutorialSub.sub", ""); + Submarine.Load("Content/Map/TutorialSub.sub", "", true); tutorialType.Initialize(); diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index d31140560..28c67bb6a 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -125,7 +125,10 @@ namespace Barotrauma return; } - if (reloadSub || Submarine.MainSub != submarine) submarine.Load(); + if (reloadSub || Submarine.MainSub != submarine) submarine.Load(true); + + //var secondSub = new Submarine(submarine.FilePath, submarine.MD5Hash.Hash); + //secondSub.Load(false); if (level != null) { @@ -133,6 +136,8 @@ namespace Barotrauma submarine.SetPosition(level.StartPosition - new Vector2(0.0f, 2000.0f)); + //secondSub.SetPosition(level.EndPosition - new Vector2(0.0f, 2000.0f)); + GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(80); } diff --git a/Subsurface/Source/Items/Components/Machines/MiniMap.cs b/Subsurface/Source/Items/Components/Machines/MiniMap.cs index 9e3f3e9f9..55cef9917 100644 --- a/Subsurface/Source/Items/Components/Machines/MiniMap.cs +++ b/Subsurface/Source/Items/Components/Machines/MiniMap.cs @@ -54,8 +54,8 @@ namespace Barotrauma.Items.Components foreach (Hull hull in Hull.hullList) { Rectangle hullRect = new Rectangle( - miniMap.X + (int)((hull.Rect.X - Submarine.HiddenSubPosition.X - item.Submarine.Borders.X) * size), - miniMap.Y - (int)((hull.Rect.Y - Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size), + miniMap.X + (int)((hull.Rect.X - item.Submarine.HiddenSubPosition.X - item.Submarine.Borders.X) * size), + miniMap.Y - (int)((hull.Rect.Y - item.Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size), (int)(hull.Rect.Width * size), (int)(hull.Rect.Height * size)); diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index fcd82f401..6dcd34036 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -117,16 +117,16 @@ namespace Barotrauma.Items.Components if (!addNode) break; - if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - Submarine.HiddenSubPosition) break; - if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - Submarine.HiddenSubPosition) 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 (i == 0) { - Nodes.Insert(0, newConnection.Item.Position - Submarine.HiddenSubPosition); + Nodes.Insert(0, newConnection.Item.Position - item.Submarine.HiddenSubPosition); } else { - Nodes.Add(newConnection.Item.Position - Submarine.HiddenSubPosition); + Nodes.Add(newConnection.Item.Position - item.Submarine.HiddenSubPosition); } @@ -200,7 +200,7 @@ namespace Barotrauma.Items.Components // position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height; //} - newNodePos = RoundNode(item.Position, item.CurrentHull)-Submarine.HiddenSubPosition; + newNodePos = RoundNode(item.Position, item.CurrentHull) - item.Submarine.HiddenSubPosition; //if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10) //{ @@ -366,7 +366,7 @@ namespace Barotrauma.Items.Components for (int i = 0; i < Nodes.Count; i++) { Vector2 worldPos = Nodes[i]; - if (item.Submarine != null) worldPos += item.Submarine.Position + Submarine.HiddenSubPosition; + if (item.Submarine != null) worldPos += item.Submarine.Position + item.Submarine.HiddenSubPosition; worldPos.Y = -worldPos.Y; GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-3, -3), new Vector2(6, 6), item.Color, true, 0.0f); @@ -407,7 +407,7 @@ 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) - Submarine.HiddenSubPosition - item.Submarine.Position;// Nodes[(int)selectedNodeIndex]; + Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - item.Submarine.HiddenSubPosition - item.Submarine.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); @@ -430,8 +430,8 @@ namespace Barotrauma.Items.Components { if (item.Submarine != null) { - start += item.Submarine.DrawPosition + Submarine.HiddenSubPosition; - end += item.Submarine.DrawPosition + Submarine.HiddenSubPosition; + start += item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition; + end += item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition; } start.Y = -start.Y; diff --git a/Subsurface/Source/Items/ItemSpawner.cs b/Subsurface/Source/Items/ItemSpawner.cs index 73a53a293..c72637a8f 100644 --- a/Subsurface/Source/Items/ItemSpawner.cs +++ b/Subsurface/Source/Items/ItemSpawner.cs @@ -56,7 +56,8 @@ namespace Barotrauma if (itemInfo.Second is Vector2) { - Vector2 position = (Vector2)itemInfo.Second - Submarine.HiddenSubPosition; + //todo: take multiple subs into account + Vector2 position = (Vector2)itemInfo.Second - Submarine.MainSub.HiddenSubPosition; items.Add(new Item(itemInfo.First, position, null)); inventories.Add(null); diff --git a/Subsurface/Source/Map/Entity.cs b/Subsurface/Source/Map/Entity.cs index cad366b60..ccb0f386c 100644 --- a/Subsurface/Source/Map/Entity.cs +++ b/Subsurface/Source/Map/Entity.cs @@ -81,7 +81,7 @@ namespace Barotrauma //give an unique ID bool IDfound; - id = 1;//Rand.Int(int.MaxValue); + id = submarine == null ? (ushort)1 : submarine.IdOffset; do { id += 1; diff --git a/Subsurface/Source/Map/EntityGrid.cs b/Subsurface/Source/Map/EntityGrid.cs index 8641b6539..efd1088ef 100644 --- a/Subsurface/Source/Map/EntityGrid.cs +++ b/Subsurface/Source/Map/EntityGrid.cs @@ -85,7 +85,7 @@ namespace Barotrauma transformedPosition -= entityGrid.Submarine.Position; } - entities.AddRange(entityGrid.GetEntities(position)); + entities.AddRange(entityGrid.GetEntities(transformedPosition)); } return entities; diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index e1fa83562..ed9051a21 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -607,10 +607,11 @@ namespace Barotrauma /// Has to be done after all the entities have been loaded (an entity can't /// be linked to some other entity that hasn't been loaded yet) /// - public static void MapLoaded() + public static void MapLoaded(Submarine sub) { foreach (MapEntity e in mapEntityList) { + if (e.Submarine != sub) continue; if (e.linkedToID == null) continue; if (e.linkedToID.Count == 0) continue; @@ -619,6 +620,7 @@ namespace Barotrauma foreach (ushort i in e.linkedToID) { MapEntity linked = FindEntityByID(i) as MapEntity; + Debug.Assert(linked.Submarine == sub); if (linked != null) e.linkedTo.Add(linked); } @@ -626,6 +628,7 @@ namespace Barotrauma for (int i = 0; i SavedSubmarines = new List(); @@ -704,9 +715,9 @@ namespace Barotrauma return doc; } - public void Load() + public void Load(bool unloadPrevious) { - Unload(); + if (unloadPrevious) Unload(); Loading = true; @@ -715,6 +726,19 @@ namespace Barotrauma Description = ToolBox.GetAttributeString(doc.Root, "description", ""); + + HiddenSubPosition = HiddenSubStartPosition; + foreach (Submarine sub in Submarine.loaded) + { + HiddenSubPosition += Vector2.UnitY * (sub.Borders.Height + 5000.0f); + } + + IdOffset = 0; + foreach (MapEntity me in MapEntity.mapEntityList) + { + IdOffset = Math.Max(IdOffset, me.ID); + } + foreach (XElement element in doc.Root.Elements()) { string typeName = element.Name.ToString(); @@ -748,11 +772,13 @@ namespace Barotrauma Vector2 center = Vector2.Zero; - if (Hull.hullList.Any()) + var matchingHulls = Hull.hullList.FindAll(h => h.Submarine == this); + + if (matchingHulls.Any()) { - Vector2 topLeft = new Vector2(Hull.hullList[0].Rect.X, Hull.hullList[0].Rect.Y); - Vector2 bottomRight = new Vector2(Hull.hullList[0].Rect.X, Hull.hullList[0].Rect.Y); - foreach (Hull hull in Hull.hullList) + Vector2 topLeft = new Vector2(matchingHulls[0].Rect.X, matchingHulls[0].Rect.Y); + Vector2 bottomRight = new Vector2(matchingHulls[0].Rect.X, matchingHulls[0].Rect.Y); + foreach (Hull hull in matchingHulls) { if (hull.Rect.X < topLeft.X) topLeft.X = hull.Rect.X; if (hull.Rect.Y > topLeft.Y) topLeft.Y = hull.Rect.Y; @@ -767,6 +793,8 @@ namespace Barotrauma foreach (Item item in Item.ItemList) { + if (item.Submarine != this) continue; + var wire = item.GetComponent(); if (wire == null) continue; @@ -778,7 +806,7 @@ namespace Barotrauma for (int i = 0; i < MapEntity.mapEntityList.Count; i++) { - if (MapEntity.mapEntityList[i].Submarine == null) continue; + if (MapEntity.mapEntityList[i].Submarine != this) continue; MapEntity.mapEntityList[i].Move(-center); } @@ -799,7 +827,7 @@ namespace Barotrauma Loading = false; - MapEntity.MapLoaded(); + MapEntity.MapLoaded(this); //WayPoint.GenerateSubWaypoints(); @@ -808,19 +836,19 @@ namespace Barotrauma ID = ushort.MaxValue; } - public static Submarine Load(string fileName) + public static Submarine Load(string fileName, bool unloadPrevious) { - return Load(fileName, SavePath); + return Load(fileName, SavePath, unloadPrevious); } - public static Submarine Load(string fileName, string folder) + public static Submarine Load(string fileName, string folder, bool unloadPrevious) { - Unload(); + if (unloadPrevious) Unload(); string path = string.IsNullOrWhiteSpace(folder) ? fileName : System.IO.Path.Combine(SavePath, fileName); Submarine sub = new Submarine(path); - sub.Load(); + sub.Load(false); //Entity.dictionary.Add(int.MaxValue, sub); diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index 5341d9f7a..e12508dbd 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -392,7 +392,7 @@ namespace Barotrauma (Rand.Int(2) == 0) ? Borders.Y : Borders.Y - Borders.Height); } - damagePos += submarine.Position + Submarine.HiddenSubPosition; + damagePos += submarine.Position + submarine.HiddenSubPosition; SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f, damagePos, 10000.0f); GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f; diff --git a/Subsurface/Source/Map/TransitionCinematic.cs b/Subsurface/Source/Map/TransitionCinematic.cs index ce2fa7f5c..b0e14352b 100644 --- a/Subsurface/Source/Map/TransitionCinematic.cs +++ b/Subsurface/Source/Map/TransitionCinematic.cs @@ -66,7 +66,7 @@ namespace Barotrauma cam.Zoom = Math.Max(0.2f, cam.Zoom - CoroutineManager.UnscaledDeltaTime * 0.1f); - Vector2 cameraPos = sub.Position + Submarine.HiddenSubPosition; + Vector2 cameraPos = sub.Position + Submarine.MainSub.HiddenSubPosition; cameraPos.Y = Math.Min(cameraPos.Y, ConvertUnits.ToDisplayUnits(Level.Loaded.ShaftBodies[0].Position.Y) - cam.WorldView.Height/2.0f); GUI.ScreenOverlayColor = Color.Lerp(Color.TransparentBlack, Color.Black, timer/duration); diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 9854a9348..b901c0775 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -357,7 +357,7 @@ namespace Barotrauma borders.Width += outsideWaypointDist * 2; borders.Height += outsideWaypointDist * 2; - borders.Location -= Submarine.HiddenSubPosition.ToPoint(); + borders.Location -= submarine.HiddenSubPosition.ToPoint(); if (borders.Width <= outSideWaypointInterval*2) { @@ -379,7 +379,7 @@ namespace Barotrauma for (float x = borders.X + outSideWaypointInterval; x < borders.Right - outSideWaypointInterval; x += outSideWaypointInterval) { var wayPoint = new WayPoint( - new Vector2(x, borders.Y - borders.Height * i) + Submarine.HiddenSubPosition, + new Vector2(x, borders.Y - borders.Height * i) + submarine.HiddenSubPosition, SpawnType.Path, submarine); if (x == borders.X + outSideWaypointInterval) @@ -401,7 +401,7 @@ namespace Barotrauma for (float y = borders.Y - borders.Height; y < borders.Y; y += outSideWaypointInterval) { wayPoint = new WayPoint( - new Vector2(borders.X + borders.Width * i, y) + Submarine.HiddenSubPosition, + new Vector2(borders.X + borders.Width * i, y) + submarine.HiddenSubPosition, SpawnType.Path, submarine); if (y == borders.Y - borders.Height) diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index 2e17f1da8..00076ded1 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -233,15 +233,17 @@ namespace Barotrauma if (Submarine.MainSub != null) { - cam.Position = Submarine.MainSub.Position + Submarine.HiddenSubPosition; + cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition; nameBox.Text = Submarine.MainSub.Name; descriptionBox.Text = ToolBox.LimitString(Submarine.MainSub.Description, 15); } else { - cam.Position = Submarine.HiddenSubPosition; + cam.Position = Submarine.MainSub.HiddenSubPosition; nameBox.Text = ""; descriptionBox.Text = ""; + + Submarine.MainSub = new Submarine("", "", false); } nameBox.Deselect(); @@ -399,7 +401,7 @@ namespace Barotrauma if (selectedSub == null) return false; - selectedSub.Load(); + selectedSub.Load(true); nameBox.Text = selectedSub.Name; descriptionBox.Text = ToolBox.LimitString(selectedSub.Description,15); @@ -739,7 +741,7 @@ namespace Barotrauma if (GameMain.DebugDraw) { GUI.DrawLine(spriteBatch, new Vector2(0.0f, -cam.WorldView.Y), new Vector2(0.0f, -(cam.WorldView.Y - cam.WorldView.Height)), Color.White*0.5f, 1.0f, (int)(2.0f/cam.Zoom)); - GUI.DrawLine(spriteBatch, new Vector2(cam.WorldView.X, -Submarine.HiddenSubPosition.Y), new Vector2(cam.WorldView.Right, -Submarine.HiddenSubPosition.Y), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom)); + GUI.DrawLine(spriteBatch, new Vector2(cam.WorldView.X, -Submarine.MainSub.HiddenSubPosition.Y), new Vector2(cam.WorldView.Right, -Submarine.MainSub.HiddenSubPosition.Y), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom)); } Submarine.Draw(spriteBatch, true); From 495a0f41249989e70abd6cea85310bc271acb312 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 11 Jun 2016 17:55:47 +0300 Subject: [PATCH 04/13] - teleporting from sub to another works now - repairtool fix - submarines collide with each other - every submarine is updated (so MainSub isn't the only one that can move) - submarinebody vertex generation fix --- .../Source/Characters/AI/IndoorsSteeringManager.cs | 9 ++++++--- Subsurface/Source/Characters/Animation/Ragdoll.cs | 9 ++++++++- .../Source/Items/Components/Holdable/RepairTool.cs | 2 +- Subsurface/Source/Map/SubmarineBody.cs | 14 ++++++++++++-- Subsurface/Source/Screens/GameScreen.cs | 6 +++--- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index 8c1ba6307..6f0579542 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -76,10 +76,13 @@ namespace Barotrauma currentTarget = target; Vector2 pos = host.SimPosition; - if (character!=null && character.Submarine==null) + if (character != null && character.Submarine == null) { - //todo: take multiple subs into account - pos -= Submarine.MainSub.SimPosition; + var targetHull = Hull.FindHull(FarseerPhysics.ConvertUnits.ToDisplayUnits(target), null, false); + if (targetHull!=null && targetHull.Submarine != null) + { + pos -= targetHull.SimPosition; + } } currentPath = pathFinder.FindPath(pos, target); diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index a78ac465a..b84831684 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -572,6 +572,7 @@ namespace Barotrauma if (setSubmarine) { + //in -> out if (newHull == null && currentHull.Submarine != null) { for (int i = -1; i < 2; i += 2) @@ -584,12 +585,18 @@ namespace Barotrauma if (Gap.FindAdjacent(currentHull.ConnectedGaps, findPos, 150.0f) != null) return; Teleport(ConvertUnits.ToSimUnits(currentHull.Submarine.Position), currentHull.Submarine.Velocity, true); - } + //out -> in else if (currentHull == null && newHull.Submarine != null) { Teleport(-ConvertUnits.ToSimUnits(newHull.Submarine.Position), -newHull.Submarine.Velocity, false); } + //from one sub to another + else if (newHull != null && currentHull != null && newHull.Submarine != currentHull.Submarine) + { + Teleport(ConvertUnits.ToSimUnits(currentHull.Submarine.Position - newHull.Submarine.Position), + Vector2.Zero, false); + } } CurrentHull = newHull; diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index b1d4037f1..2f4ebc673 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -144,7 +144,7 @@ namespace Barotrauma.Items.Components } else { - Repair(rayStart, rayEnd, deltaTime, character, degreeOfSuccess, ignoredBodies); + Repair(rayStart - character.Submarine.SimPosition, rayEnd - character.Submarine.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies); } GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition + TransformedBarrelPos, diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index e12508dbd..1688d683e 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -153,7 +153,13 @@ namespace Barotrauma body.BodyType = BodyType.Dynamic; body.CollisionCategories = Physics.CollisionWall; - body.CollidesWith = Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionCharacter | Physics.CollisionProjectile; + body.CollidesWith = + Physics.CollisionItem | + Physics.CollisionLevel | + Physics.CollisionCharacter | + Physics.CollisionProjectile | + Physics.CollisionWall; + body.Restitution = Restitution; body.Friction = Friction; body.FixedRotation = true; @@ -179,6 +185,8 @@ namespace Barotrauma foreach (Structure wall in Structure.WallList) { + if (wall.Submarine != submarine) continue; + for (int x = -1; x <= 1; x += 2) { for (int y = -1; y <= 1; y += 2) @@ -233,7 +241,7 @@ namespace Barotrauma ForceTranslate(moveAmount); - GameMain.GameScreen.Cam.UpdateTransform(false); + if (submarine == Submarine.MainSub) GameMain.GameScreen.Cam.UpdateTransform(false); submarine.SetPrevTransform(submarine.Position); submarine.UpdateTransform(); @@ -336,6 +344,8 @@ namespace Barotrauma float volume = 0.0f; foreach (Hull hull in Hull.hullList) { + if (hull.Submarine != submarine) continue; + waterVolume += hull.Volume; volume += hull.FullVolume; } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 1532eeea0..d05756828 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -136,11 +136,11 @@ namespace Barotrauma Ragdoll.UpdateAll(cam, (float)Physics.step); - if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine!=null) + foreach (Submarine sub in Submarine.Loaded) { - GameMain.GameSession.Submarine.Update((float)Physics.step); + sub.Update((float)Physics.step); } - + GameMain.World.Step((float)Physics.step); //Level.AfterWorldStep(); From cf822cfae6687c8f2edf074ad9a683fede325d55 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sun, 12 Jun 2016 14:23:08 +0300 Subject: [PATCH 05/13] Submarine saving fixes, impact damage in sub-sub collisions, submarine ambient sounds --- Subsurface/Source/Items/Item.cs | 2 ++ Subsurface/Source/Items/ItemSpawner.cs | 41 +++++++++++----------- Subsurface/Source/Map/Submarine.cs | 12 +++---- Subsurface/Source/Map/SubmarineBody.cs | 33 ++++++++++++----- Subsurface/Source/Networking/GameServer.cs | 8 ++--- Subsurface/Source/Screens/EditMapScreen.cs | 4 +-- Subsurface/Source/Sounds/SoundPlayer.cs | 28 +++++++++++---- 7 files changed, 80 insertions(+), 48 deletions(-) diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 884d23797..b8e908275 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -1438,6 +1438,8 @@ namespace Barotrauma element.Add(new XAttribute("name", prefab.Name), new XAttribute("ID", ID)); + + System.Diagnostics.Debug.Assert(Submarine != null); if (ResizeHorizontal || ResizeVertical) { diff --git a/Subsurface/Source/Items/ItemSpawner.cs b/Subsurface/Source/Items/ItemSpawner.cs index c72637a8f..7899ba652 100644 --- a/Subsurface/Source/Items/ItemSpawner.cs +++ b/Subsurface/Source/Items/ItemSpawner.cs @@ -13,20 +13,20 @@ namespace Barotrauma spawnQueue = new Queue>(); } - public void QueueItem(ItemPrefab itemPrefab, Vector2 position, bool isNetworkMessage = false) - { - if (!isNetworkMessage && GameMain.Client!=null) - { - //clients aren't allowed to spawn new items unless the server says so - return; - } + //public void QueueItem(ItemPrefab itemPrefab, Vector2 position, bool isNetworkMessage = false) + //{ + // if (!isNetworkMessage && GameMain.Client!=null) + // { + // //clients aren't allowed to spawn new items unless the server says so + // return; + // } - var itemInfo = new Pair(); - itemInfo.First = itemPrefab; - itemInfo.Second = position; + // var itemInfo = new Pair(); + // itemInfo.First = itemPrefab; + // itemInfo.Second = position; - spawnQueue.Enqueue(itemInfo); - } + // spawnQueue.Enqueue(itemInfo); + //} public void QueueItem(ItemPrefab itemPrefab, Inventory inventory, bool isNetworkMessage = false) { @@ -54,16 +54,17 @@ namespace Barotrauma { var itemInfo = spawnQueue.Dequeue(); - if (itemInfo.Second is Vector2) - { - //todo: take multiple subs into account - Vector2 position = (Vector2)itemInfo.Second - Submarine.MainSub.HiddenSubPosition; + //if (itemInfo.Second is Vector2) + //{ + // //todo: take multiple subs into account + // Vector2 position = (Vector2)itemInfo.Second - Submarine.MainSub.HiddenSubPosition; - items.Add(new Item(itemInfo.First, position, null)); - inventories.Add(null); + // items.Add(new Item(itemInfo.First, position, null)); + // inventories.Add(null); - } - else if (itemInfo.Second is Inventory) + //} + //else + if (itemInfo.Second is Inventory) { var item = new Item(itemInfo.First, Vector2.Zero, null); diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 2469d85fd..d481627a5 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -526,7 +526,7 @@ namespace Barotrauma foreach (MapEntity e in MapEntity.mapEntityList) { - if (e.MoveWithLevel) continue; + if (e.MoveWithLevel ||e.Submarine != this) continue; e.Save(doc); } @@ -548,17 +548,15 @@ namespace Barotrauma public static bool SaveCurrent(string filePath) { - if (!loaded.Any()) + if (Submarine.MainSub == null) { - loaded.Add(new Submarine(filePath)); + Submarine.MainSub = new Submarine(filePath); // return; } - System.Diagnostics.Debug.Assert(loaded.Count==1); + Submarine.MainSub.filePath = filePath; - loaded.First().filePath = filePath; - - return loaded.First().SaveAs(filePath); + return Submarine.MainSub.SaveAs(filePath); } public void CheckForErrors() diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index 1688d683e..ad6dd7500 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -415,12 +415,9 @@ namespace Barotrauma public bool OnCollision(Fixture f1, Fixture f2, Contact contact) { - VoronoiCell cell = f2.Body.UserData as VoronoiCell; - - if (cell == null) + Limb limb = f2.Body.UserData as Limb; + if (limb!= null) { - Limb limb = f2.Body.UserData as Limb; - if (limb == null) return true; bool collision = HandleLimbCollision(contact, limb); @@ -436,12 +433,32 @@ namespace Barotrauma return collision; } - var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(body.Position) - cell.Center); + VoronoiCell cell = f2.Body.UserData as VoronoiCell; + if (cell != null) + { + var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(body.Position) - cell.Center); - float wallImpact = Vector2.Dot(Velocity, -collisionNormal); + float wallImpact = Vector2.Dot(Velocity, -collisionNormal); - ApplyImpact(wallImpact, -collisionNormal, contact); + ApplyImpact(wallImpact, -collisionNormal, contact); + return true; + } + + Submarine sub = f2.Body.UserData as Submarine; + if (sub != null) + { + Debug.Assert(sub != submarine); + + Vector2 normal; + FixedArray2 points; + contact.GetWorldManifold(out normal, out points); + + ApplyImpact(Vector2.Dot(Velocity - sub.Velocity, normal) / 2.0f, normal, contact); + + return true; + } + return true; } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 0ea8f8c99..6edcd4ef6 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -364,9 +364,9 @@ namespace Barotrauma.Networking if (!(c is AICharacter) || c.IsDead) continue; //todo: take multiple subs into account - Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; + //Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; - if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; + //if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; new NetworkEvent(NetworkEventType.EntityUpdate, c.ID, false); } @@ -405,9 +405,9 @@ namespace Barotrauma.Networking if (c is AICharacter) { //todo: take multiple subs into account - Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; + //Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; - if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; + //if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; } new NetworkEvent(NetworkEventType.ImportantEntityUpdate, c.ID, false); diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index 00076ded1..977ddc69e 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -239,11 +239,11 @@ namespace Barotrauma } else { - cam.Position = Submarine.MainSub.HiddenSubPosition; + cam.Position = Vector2.Zero; nameBox.Text = ""; descriptionBox.Text = ""; - Submarine.MainSub = new Submarine("", "", false); + Submarine.MainSub = new Submarine(Path.Combine(Submarine.SavePath, "Unnamed.sub"), "", false); } nameBox.Deselect(); diff --git a/Subsurface/Source/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs index 59606fefd..5266dbf48 100644 --- a/Subsurface/Source/Sounds/SoundPlayer.cs +++ b/Subsurface/Source/Sounds/SoundPlayer.cs @@ -183,7 +183,7 @@ namespace Barotrauma startDrone = null; } - //todo: ambient sounds for multiple subs + //stop submarine ambient sounds if no sub is loaded if (Submarine.MainSub == null) { for (int i = 0; i < waterAmbienceIndexes.Length; i++) @@ -213,17 +213,31 @@ namespace Barotrauma } //how fast the sub is moving, scaled to 0.0 -> 1.0 - float movementFactor = 0.0f; - if (Submarine.MainSub != null) - { - movementFactor = (Submarine.MainSub.Velocity == Vector2.Zero) ? 0.0f : Submarine.MainSub.Velocity.Length() / 5.0f; + float movementSoundVolume = 0.0f; + foreach (Submarine sub in Submarine.Loaded) + { + float movementFactor = (sub.Velocity == Vector2.Zero) ? 0.0f : sub.Velocity.Length() / 5.0f; movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f); + + if (Character.Controlled==null || Character.Controlled.Submarine != sub) + { + float dist = Vector2.Distance(GameMain.GameScreen.Cam.WorldViewCenter, sub.WorldPosition); + movementFactor = movementFactor / Math.Max(dist / 1000.0f, 1.0f); + } + + movementSoundVolume = Math.Max(movementSoundVolume, movementFactor); } + //if (Submarine.MainSub != null) + //{ + // movementFactor = (Submarine.MainSub.Velocity == Vector2.Zero) ? 0.0f : Submarine.MainSub.Velocity.Length() / 5.0f; + // movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f); + //} + SoundManager.LowPassHFGain = lowpassHFGain; - waterAmbienceIndexes[0] = waterAmbiences[0].Loop(waterAmbienceIndexes[0], ambienceVolume * (1.0f-movementFactor)); - waterAmbienceIndexes[1] = waterAmbiences[1].Loop(waterAmbienceIndexes[1], ambienceVolume * movementFactor); + waterAmbienceIndexes[0] = waterAmbiences[0].Loop(waterAmbienceIndexes[0], ambienceVolume * (1.0f - movementSoundVolume)); + waterAmbienceIndexes[1] = waterAmbiences[1].Loop(waterAmbienceIndexes[1], ambienceVolume * movementSoundVolume); } From dc7956274c7dea19c567575558f5f21b5b30cfe5 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 18 Jun 2016 14:46:40 +0300 Subject: [PATCH 06/13] - camera follows the closest sub - WIP "respawn shuttle" - submarine size affects its mass - electricity fixes --- .gitignore | 2 + Subsurface/Barotrauma.csproj | 1 + Subsurface/Content/Items/Engine/engine.png | Bin 62247 -> 91905 bytes Subsurface/Content/Items/Engine/engine.xml | 30 ++- Subsurface/Source/Camera.cs | 20 +- .../Characters/AI/IndoorsSteeringManager.cs | 9 +- Subsurface/Source/GUI/GUIImage.cs | 7 +- Subsurface/Source/GameSession/CrewManager.cs | 2 +- .../Items/Components/Machines/Steering.cs | 16 +- .../Items/Components/Power/PowerContainer.cs | 25 +- .../Items/Components/Power/PowerTransfer.cs | 4 +- .../Source/Items/Components/Signal/Wire.cs | 27 ++- Subsurface/Source/Items/Item.cs | 2 +- Subsurface/Source/Map/Submarine.cs | 7 +- Subsurface/Source/Map/SubmarineBody.cs | 76 +++--- Subsurface/Source/Map/WayPoint.cs | 14 +- Subsurface/Source/Networking/GameClient.cs | 9 +- Subsurface/Source/Networking/GameServer.cs | 16 +- Subsurface/Source/Networking/NetworkMember.cs | 7 +- .../Source/Networking/RespawnManager.cs | 226 ++++++++++++++++++ Subsurface/Source/Screens/EditMapScreen.cs | 6 +- Subsurface/Source/Screens/GameScreen.cs | 6 +- Subsurface/Submarines/Shuttle Mark I.sub | Bin 0 -> 2333 bytes 23 files changed, 413 insertions(+), 99 deletions(-) create mode 100644 Subsurface/Source/Networking/RespawnManager.cs create mode 100644 Subsurface/Submarines/Shuttle Mark I.sub 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 ff3ed0c094123c2848d4adb3f0c269b9b882f112..a99150aa15dca530fe3000adfdb61284bb1a158d 100644 GIT binary patch literal 91905 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

AfP$SkTA7RO-7oV2aiM(zACh&R6D*h!hvi+4j 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 Ks?;dkM*TlX{I-Yy literal 62247 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ⅇ6khOqs9`SQo1J z_lHZqbpv>qgcQYl?aKJj8FHPbwC22DUS9qY9D7~Z*OtK#PZ#UkdI;YHg>l`C;zY29 zf!2*@4dtwvEOA}e_qFEHuj!%dWo}q1s46CII5prJHjObQELp%)#w;fcM9_gyW?(+; zG3G1W1_#I&&V+ z&)Ex)P`svc4kQMwh-olntkBwfBpFSNLtbyp3gUzmc#IgX+@zu8GS@0pcf(hKAHnM>(g?z#&&&x?ITVl+hGy zSxS^l2oxdTXPOU6EWbRfp%S@kBIC>(b&qx> zTl$)a)Y&dX6D^`!hE>6To>*y zTF5<|x*sk**HdWlz90IkuhWm#5JkW%YeTN}BpWbL2#BI!h6-~Hbwtr$Kc+Q=v;N-0 z-(53S9yYA?Vsg9P_Qtj>OJ@Vcb6&^tt<|6F`+o?}JY?L&<9@i)SpR((2D49Sz-C}@ zVJve+5(burfeFGuV|DDrahh%*uejj%esk%Jp!%SZCXu?KZ?&Zr(_4pkIoP|BFw2`UYz;{luP4oxa{yKBtL zjL%=)VjMU4!4E#h&6`(HD8Bc@Px0+P{nPl$SHB8o#!r6zt7yxD%iV?1NK-;>6>na@ z0<@XRwz-1 z*f8O~nn_(2k-RP(Yn9?3SJ>C^${Isn!y#*E18+?%^hdDuFT$PIFw7bPTGRj5?3XB_ z>j`bw5&PKJ(7O$qOv?9|^%sM6$6Om))jd$74(g!8FD>-Nt3h9R!LB*&0H8c@NoBa33a58s8(Z}g_UIL zfe`)V?EGsaE7pVG7U1rGWQC*!JP?kH-e^Vabx$s5Z@vsR`MYB|!TF&FIk9d|CZwoR zqjW>r7*si1v9;5e!Kab0st|BeK*$Wq)S~XPJ4{+2i_si|4dmU)*h-0U+D~|SSTKwu zhH=E>$4`v$QY*AhwyaFq-#3K2yBplRd4rdm0dH>JV1GP;m@$kQ-~QP@kNI@M?&1=^ z^;^GfngCVgoN#e*h3#gGySqEwetwI2nlQ)SM+NF(>P-}yO|`t&dyLBlOCoGWH7$V< zbW12L;k4g_njnoCn%Pd6JlW^{PLM_9@xw)BuqoEk^e=*2)`fnJ_dYa}dN`%8r}>y} z1L9dTJs#r9Uqs^z6>4~=ukrAQIQ$yhUyGU66Zd-2y50>uWa5Onbhq365iwPWuGVzI zHJ%<`D_?}sN8@@3&8$xg>r+ECn1{<=BEs=r&^Q6Dq6`^z7D#Fk@+jX#Qb!cf<%O zh*LF)kkrBuh?BW0_9;I3((_#0fP}ftwn%eht>B6qH=4VYJn&tJMd~F^)*Qn0t7GHl zqiu^)^A%87$aBsa($2{`VVfJlLZOy5hK8LEjD=y0m$tNy%Xce)n=eaHFo|6h$Ru7&b4CQ-|+7^EnST zGF)w`ZB`Fq_7>hgK}RHq-IitrmX!K)R&@ojGUlaXlM>oeahex9gZXJn)H*MR8CMU9 z_T?>SKpU!<$R=|^g-ye)8cp>6<_?dquP`qasSKdjP|DD2)G&^Ce07D7-hGPeN7s1w zgP*{Ue(*h9?6&y&xBe_HFRrjuK`I-hobl0zU&8PG?(g(4mWWRjQB3oUCW?8fXd<|~ zy~E|@C5RZyV$PJ58PpP%yVpoh9%0!4k27IvKx07?K#ohdp{}_hWgzj0;X;x40;vd8 z?!c|JVNJ&i#pA=juZ!zL!>Na9_Ui@an)R|~o~)Hl+Dc$ivVptb(KHuA!uWN!H8THQzoY`%#?l@9%Lu9=mT#uw}wFH&mqY{b`!| z^A6Z$y{KJ#)~tPP9%j9+n{1qjx^p7~7!`TQsG`UNV}WrIbpdKSVNBVo&4wVeEwHp@ zjKK*f^8|?vS_<`J1T(BeG~!{qz2W;5%q|uJTadBR%3nJm75}?&rqBKtv8?LKQ}@!K z&QGSZW1u$31*-b=DaO^dz>9=M1x*!c$ZjEsvn>H9FkD(+9o=q*A-5G2 zq+XaEG)K-E+sy_gyK9~oV0a^o9}V~+BcEiCaVFHGn!IY7> zfGMF?^&%K9mZ2xG$uoHdg#|(QF2WmJ^JZdxD?p-zlEeJU_c+~})}2#A`N*lWkYcX@ z=c4z3iFjWyLzyf&DJPVi`?XV5oTd}zc`~}BD`d@(szGY&{C;Y(YW}_+4I5{tgo+0- z2W3!UkF5;F8l1v~K8jQZv|2HX;>FD#WqXA`_}(Aj2Ooce+q*mbzy6zlj!%B{Lwg*e zcy#>;U;WCLar62mpw?)@4j_!mm@K`?_AKYR2x{HaMTxMVtvROYh-tBeqt+C2Yv2SN zTSZ01c1WNG6f{U1u)D~3dUc6549Fs~dAN9t!nXdm^@RRKLYeiSYdn698?TG;8eaLL z?9w%B-$(6b3KHW9`fMVMqKNNy!FoEiyp(8 z{qpent)Z)jCSB`mwr(;H>7HTeLv1iCQV~lKCp$_~njsCCi7;$8Ak7$u6HW(0U1qQj z-QzlV*A|}ORJBM{389Pv%r;FjB{zstoaTlh0*tU)rVF|cj07{m>1!kaadjgsOY;#Z zTJv(|tPLeW;?k4f!)rxEz`2+Yhh)q%xd?~dgCm_oAYiHLrE}6#4^d|K-LRkrPj!Pq zKji%8RvVUiwv!MsnBDX%5tgNyK&d%w;x-53csf=MLDZNyOPwK$U?>H-m;qds22sM0 z1~i$S#o^p@KOqs@Nr9R{P=I=N>RI?>+gdeiVDiN!0ZXgiP_3XC)5TJbQc0LkGfvaw zX-VF^H7J4blq&7+hP~mFPpr-u5;3T12`?jm9pTL(d&C@kr^Cq#9VB^`7N9dH~7E*=l^f~U+?a)9T^SW8Ci*FwY)d-!trplx<~+|I;>S8+E7x%lZ%X{ zRpeod_djfLsrMb+YI{P8Z(b6Km5kS4j{Z>!aZ`W5M58lYlvfAs^YS)nj(GHsNM2V75~gh|sj+%U}HfU#icLI9s}m z2VaM{QnjI}F+18)0alch9oisEAfk-9&Yt$J*o?(JT?i=`Y;r-b@V3dSL z#`;LjTo2j3*G-jcRHX1>SEur66U<9RZ51ktp;$08+@@Ds1ehqk_NRWr3zcV|`qEak z8J3+L{1S)ONG%SJ#Em1})_^mZ)&2B=$z$(|TOu&bqh_fMtxh1%UKP;U;-^cdi8uKK0_x+D>y1nfu8Ep;hdz;#--KV-6 zYinSoF8v2F?v?PRXCLDJ&F^9eHg4RpdwTw1u=c;3A;i7G)M7qU%xuSHUK4aKb$j4H$|QIdQx= zuwQkb5D0bCDsh_tqzuf8S{LLpVv_(WqnrI(oYs&%-%_0|kr-7Jtu9Wj1X>Q80mo>e zt_n10W1deSwxTErU=1Je#W2)xR*d5~*@>uzIhIrqXJc@X@ybOSTGMX(YXe5}z=v{H zqbg&}gU7X1Y=;4o9SST3!!UNdy1OevQR@t835l~qFYq7+o4B$+XNAeZPxAsML0uS| z?FK_GzKmqlrpPYR5jQv^NU6Z#)wP~X^EmXOKD;T5)#_zQ0#I7I9uR&B-h!d+h6N| zr5q)f22H_)YJg^=)W-D;?{Pf`P1{gpr>r~7HoF|lo+RF!Zb~m{kyw#`{M;~ zUcbTf&tK!)fBL8K>GMx<*dOrcKKuzJ2FBe51d63DX8*iQ7_Tnugrn$wR>#v3`97nf zVRJcH^JYbxo1I8xEg_^ z@^(n{7pXWO%K0BIIv+Y3Mr>P5sZspbo+|4F=|h<1A?)yQYLDL!yf|ozk*-v0?dD() zgC!m|gEh>vwyX^}Cp=;TR$1R?{QLTJ5k+{tPl!hFMc4F;3VBdD*O{qnKL10O(8E(x zoRUf@U=%0;!!Tkw9dPyd8u#~apoba6*|G{4m`*c>JmWCmVYt|U^9VjhH4s!WKZ-7b z@MAPr=V&LxQAy5`XeAdkoxxfmO|i^(SgK+u8JtH@8X(oA_91N+HiyK_HU$ELRu^Y) z08$n6A}C{lG;0Dmk8pPZqfe?WN5cZZ7z>sj)28_xL#C}qi9yvUbIIS&VqEi#)EAS1 z!z-CR>O3!weVlNbCfEFJ2BZuu)7)V?Y0d0xb7ZOli3d9|xTS;YIna3+ii?okT`^P8 zjQ}+FnL$?*pZ)mxyonB*FK_VYVJV@E7TR;17R-0E!CTCLHZ0SO>HdW0pMQq0eEB21 zeDNH|shULt1G|e$_ug;#%2&UNdYx_@@M z^vbS_P3b_bW*bn5OrTVTUU(sv#mbya*$Bhv?b@0GcAjikP%>jPZhIq5%vk0H(2Dzc z!EU$3m`BfeRWyG-0FXI%ZhiLnwdSw8!F{>o)21IFrzhGe1wuV!BeVIy1oUC>Q+Vw- z3`DM7*w1be3@pZei47DGt@HrQ-7X!9PAt{>w|U->#R z1AqA4-^YtLw}_08%gZZFrxW(|9#RFoOVFA7QlFioO91jPKmnZUEu@|xb+TnDCoGfE zXHUn9OoEJpfis#mq)eFAhSD7mXelA9>T@Fc_7`F3@%J???tf?*x=ssvTRf5eNWu9c z>^COn`2E1D*HiUcjI&mEMgf0l4ED#VI@k9dFiK>RUR+#sJbP^_wr*1E9mB)tvwqI& zSi1GH_m8v8T^IkgcxpY-f05lnJnwbN(l};Jnm~ERkP# z83Q!{8PmSHu@rSLZ;0`wrP;D7hm@W?o3Slej(hOnOQxK#Ocl$tfYWTaJ7;se^GU6> zhC1ybMkm3|-91VwE{p*v!@1f{19M1ZECZSt*VjB;T)*g4Ln;hZ$8KGbM@o=(LP{A! zHi>_0>hT!_&G29dQ;Ieblp%MU7S(D~l?NcFVtD!8{%D0YdjK;US`jm!a?jYXS!h}@ zpYFgsAP*x5gr!!TrUe4Uuxt=EHJeSrycpj>%w5kM2aU5nFGnP?;uQRJh(K66 zy_CdrRLSiYDBz{R3Lo57*BvIKfm!iRnC8VMT$$Vk!sx1&Novp4*f9B z_n-%R;G4>M+GqBxRz16+Dm=BySXk3^#MR{m9$j5vnHM~{z5wTp``b4d#u4*8na-gk z9PVC&xuDjDI-ekIHran`sMSt!B3{!}-Ri-QPrjodwT#=s1r-^avEVRIP);Zya8~4E z&{R_e4;h6smMMYi1Wq$*O{k}eEF%9rrSz*0myhe?`xh}OzKD79Fq$s@`{5M(5KDh( z8?YAFe9=U|h8@On#NFLphjC7)(_0LbhYX%CVwJ@6y}rK2G)+ASI^d3n^8Iyldnle- zD?cAf{T~+VFXEuDzrWT3JoL|5KmIke6wBbvW`kkaA>lPP<0Y6D9PTFYkf4(yv0I>4 zMjI4#%%C#jus?v&P^&$U%ozy`NzPP>MxEF&S_Y&|AZaM$;Cy7kxVgahzyAZgc=0)c ztR^rvLQ1k2E`qogZV917bi%-B!s(XoZ=T}1&oC<#U!_V;Q)vLZ} zH5wne=Zv}eHJRP?%6_la22PAJ7#2Iv3v#mGucG+yqxbOjuYH7NIXZ@%vD69kB-mbT zT?AtZO4(_r;qb^V#!?kCc-Mv+Ocwy8)*KQ$PTi_c?1FhdBIOa}f*%We81Qd??+SZZAT-b z;I>%&p=YL=U9EOcozyw9dbSF1Z+4r`&#qo|p4<~idefelitR;0;thWE*=KnE`R5>J zjN{fn$07UuE~wM78_KwWs=a?}YY?3Pr0#o8%}#)Io;u`b{`vqGJ2j-t$Xmvcft%Mi z7%w;GrZ_hY!xpkkX1lRVP$Aq;GX}auql(jMK$Z!NjLgjc?BUee zGV4svb-{TkzyBgt=z04f4GDABB9kf^!efKu75ACaV&M?y4z0S3ftX?tiYs#LX1t$ zI64Ow7yxcQ)!1=AZwR&QkoeX5AGuB3!0 zBr%u^@{n8s%nCAw;$ri>6 zH@|E0*U;Hcc1A#Lz*3t{_-Z~iiHcvlhIz5? zrVJ)KxzuGr8vMS*!%{SA4!S^0(E!@w_RSlNWdNs)iPTWhZ5q7J(}#P`?txfVIa-`BBo4;Q@;PYP>anxH|hx%v-_ z{=?<;`h*e8oNjv7fMXSGl5wr;NPt#cTrj2+VV+NDO_2x1aKV^v|3B>gS*&zfcHfEp z)*j9|5pnM~W@cp#EEdUPmPC=_AhoP+s|7+3WHqdA0o`an8V%S$!w~#r1AaF=0R12s zelTFbFxv2oAM6I?2cu!Yf(MeKq&CU6N;QyFvF55AzUdAT=bXLwT7FnNBBO#gNegYO zrE*2$Lw@5O;>KNj?X~{@-{0WX%%h(cUPSs_R^4)MwO{qmX49=}^F%)`Of*v7`Rl~Y zIU~_AqDMrnfv4nX-%q6A^eyqLr`Fmn;}NX*`|hbhNF$`cdbmGDkp=5!BwPYmYe8aj z_DTELsYsW%9VK=r>Z3%Ww61lpNXp&SDYRzZ5$2KIcFS_OLz}~|npV~_pXUCpvr=*h zo&2aS^NU+T^O(Z5tqd^{^FUc=jO6(mPOXP)3c)%DJ$g9CaXzj1^*x5*7~SNDZEVMcuL%{;>#2vCC@xzK(g9o@uWQwM zV8!vq(hGSUF#9;bLry>{-=$c9RgI=X=|LkBeSAeslv=3A01Y!juoFi-B5F=UW6bH~WLAt)W=9gVfVN6ZnPD7g#RFT+juCq8l)e{2 zWV5|Kxq{t6>l~a?R+huTwfa4BamP(cV z#NdXkAcDk^JUC4+O;@CG%UtezC~+h9*IiDjb6q^2wA5bI+=+#@;(F}R?dmAC-Xlb) zGwc0ph=VUqb0CGlT(oCxCRdh(p2(wywMG*0POrJcHpO&ueiFS~^^UzaN+@U`4%tUi z!DHDDheBHq{_#hj)wi}fiWjJ@fJ6f66i#wddvUhB7d#eFy&;f1biH^_DeAqs^@Jjk zK+L{0P7+Vuwom!H>@j-iMTnios^X-^zRL+pHzc{T26bcCvcG3NtTa{X+^DMuV@vec z%~~3&%g1b=9^2>pp8T=jp%-pMu%(>bp!Ct47xT(8AE;(b+tHWE&8VxVg89LyBsnsR zAW7v=3%kM4H84G`?Du{576q!oXbiET7JVPmjEeF2dSYENn_)W17XOi%{rW@cL+9p~ zhq~p5Ea;a|t4n70<;ddl{ah|pFXesuBbj~aM@&ZNh=I$4;_^T^Co~>E#`Cb~^O4Q@ zp>Ph;x}+hVV-g+$e4Q^-&mE)Z3)jQp@FM{nmml{rJN5XSoTCg%DW~Ob$N}0w=d~dT z4y!_}*xq0>v6ey*Bgh7`*JR6RbyH6|@_14rTXlVRhjIl`kNJv6nOyWjqm9;9YH@zG z96Q0D0&iUc=UfqAt`VfCvmb+p0@eIlJ0$;R^~4;*TBWUvQ}@IJFH8dSVTLe}VxX+v z(hYq~P@7+Gr7s0rb<<9Y3DfG9?cjy~c&MbKOV$Fx+}4izb8&K({ zTKUqtk1~>{MOCfN=dzENr7>j=s}gN-###=5f2+0j>koB~mlDRyqJByLyNs2)BnY0*h%bx(c_Dm=E_mMY9=r3S z66R_ml!_eKz-<-I{&?gkO$}Ej`J@6oTq;NabN!b^8H@2=#OvvQg(TMgSdQ7 zj^mnTSx&R`&<-|d1kzz)k6+)tgndy2Wd>B6tK@`_#p+nDn%HmSCj_GZt9(*lFhv|`31It=Z zz1{xxP;=F^>M68niY$;?=ar`2|X? zXwNcD!$b(eG;L5kG&?0Z@pZ;Lb`Fe>MS=+})V_=GgX@^eEy1%;0}&M?8bJ^i3WGQrrSLdud>cLa)-A~X?qpX%-$jLb-2Bj50_|2hMX-Jf%P^vmd zKWFaenYJ#Njij6iS-P5v6YoVUe_hx^a&D#`EcN;KJyNWtC&<bu{zFnFFWybCCK@L^s-nU3;p46IE@P~XUpgB^ONlV z$KrSFRF4PIIga)rdEzBT_q^+WNHcypGP!h@UUJqSx>a0q)GrT)hg`bnH<0t^;e7FY z9_}&E^J&L%JnR5k7@)4yn26fB8L4;dwIM@dwFTBn8-!FcweDHUfhx`~*B%~Bh$oYZ zcAMk691wLmT#E^-wawk&=+yC`9xxKsP@%1~b z+YRelsB7Ww)oWMi#MBq#KF0Ep6$i4lwfcg$#~&UU`62kBW6fDMO%<)x<%-q$Fq`d$ z%{X%N=7xXmSAUV+Zt}6CL{i9@1#W=n+vs%2RjFZQ8k{8BO7VSC9v~~CKBn9bfw~Cy zt)ffs&{g#}L}YEP4G+09&pXx2&hWg0J=a>Fzm4if1Ixx>~ z4wsA9%fsQJ8UN+{|57i0*_EFkUJo4KILrt}&O_JdDz!(oiCMqm`Zvu|R!mDz(di8C zu8AK82XaY@u6M%=0tOZhsqrM&JEB@c>TzpUU@4?w?5Az+k#}7cL7}dDf&|7qa#&Z& zYLueXqOA3RHg}vZ^W10H15gRAn?yR6*sRd1b&_N^{KSY-SW0ErgmIiGrFYrU#}yon z{Q@BlL_5aFD}?Mi@5LD?CVfUM&Q3uhsfS=-&P$gNTz%U4?Vi8tDNrp&WEhcYLc3nx z1D554;iYks1jY_AJB}$1w)!^79LAYtw9+g?MCZ?o@XtRpFM@?FNdt|ywJV(ztQ>i&lq8FS!jv*E?d*ZhTF z`6WL8`OgqSI>jf(=+A39?3v4!Y=ZSHSC=@tk*_vLv3WSi2)ZhFhl)jITnpsE3;LJ8 z{N^3zT~xB zhHG5X3(w!*ky7|jXvg`?{QMSi{&}4j^~;6trP}488T;k$Ul!_19?m(o_#v5O+hk7& zZ^oE5v{2DiohiNnvDjzOf`!0na9b-X$`B$^B4h69caFoh$8sdr4$(`cFou67$@9x%#@;%7xk zAyV2xGh;eQ)e?|s^?Wq!Gx-nb*YX>h}n5E0Ikv##$j||){y-9Qbm_S z7zy&ptQBKdNL_bs06A-(7+~TjD(gw zRtwFBj+toWF_PklR(Ii6HG;+C2)|2PyTtNrIeT;lH&v|qI4|dkpZVe!i81pVzwz6= zxw&`5K?u;Dt*Sk7s)v2Mm!J`1e?2(}-$&*B`zH10T4Ese@NR7$Af8f0RJpy|^A~>g zm-zH&KJ7OFdU{gVF6!FYK6%U-MoOrRVPIJs1E9eu)m20$!N;hj(##M0W!YR+fm$6ucppDQ2bhUXUj^Evt@ zcJ?xL>71~53DLTg44ykY|0MM7L%RNRgV96(?wlfdE(1Mxot~?B&W%eCeGJF(Q&5nx zLyKzj7c3d>R|c1c_#&{uqTSlx)R7(0kdz1nN;xpZLAHRi645{1c+bP8*2G2`(U3Ef&xZ!7*kfzM*krC42V8M_m)WhnD zLsnVlM$3huZh~?piNm67V;K zMBpF(qu=HJ_LgDD48!0-E1^q&FPbpxsYe~|-)}g5e^y)fE7>Xd;~0+8R&P9h?JxWi zpa0xvsVc-mQL%FA^-?G-Vv968O(GGf4vc$n}MmbQ|J=VVlc{BKHYApnd zNEDJ}ALYbID+*Bwz_Q*m3>(iqRYj5?&e8)sdS%2y@WpTs0@v1e3#s-LCFQ5S@YBQ) z`3JxK|72Yjq6kAuGzkPr&gM5)MrrHrPB$-{;tM|p)hXJJE^X^Mw>|PMC4TKM{t}=6 z%%|LAa$GpCGjYshMsj%V8uM9sdObl%L=+7|nl`j`WsI5Pq8q>MR*#3&)?8XTFP=Vi zR_uPG*1D#YhV#z!lOS22^faeH|BtIJh*`s$1CeRz zhAj~*tB+Ko+uQ4W@U9#2E?vcod=RY8u9Xgflp|UfUjh%V3pB%K zFe_ADT_#r>YgrkG32TkJ+ZQa$Oo)*&uN>xEhRu$Ku&xKf(CM0znWin%?y)0mml>-C zZO%z=A)smuF?sS($fzk1AFEU?#JK52%oRGZBV_3&BMUAY45@P*==$*f_N0?1=_(e( zh-o0mk*DMtmuiOTdb-J~33vB*{w#1TLu)RSR=OLW*RHL;2w@yzTUJ1LJ#gRg0@paP^pdF5)$1gm(svz zKL0uX##Lml&Y^KMLF+MkeIcw$tE*?9YEQfBiXClkiVGH<4Wx}Bdn1yf)7dw}#AceD zP+2Ql7SKx0L+9ITzcd+1lvY-TETlN0xe-)}k}1tS2hton?K>ss;#aHWMTpZ`hyInX zeC6iP{kcE)_e&{%^L#G+&}{p%yL_k!pBKk-SXOK8q?bM~oDcC$9#X1YCMg|9E=TS5 zr7rxT@y8`N>@s`w2*kRam7gChmth;19QTLlm7nxD*SeqIXf9{;m(S7hW4%21PEmFd zB>8eMiqMYB!b3%pcV|`I_z{Ohl#xaE)G!m&9fhfLHdOsE@I_i8rh%rFVTi2VVjsrQ zJ7;NV^Kbf6Rwpcy*dJzEU0LS>QMtNKhz6H`NnoB=YAbBhmTE#GF(y}JNKX(-DKhU5 zXlHXT%gX(J1_=z~2ncI!#3-~9&Q~gmKKY&?t*1-B(+Dp&0`qrXKJi4vMnsXaH$`!-)~o&|ziW15#!rCqE#H zD^c>`g)qk9)YVH5Vip3X6;oGNNN}ruZF?jLMZHVcR(mc$@Erkzj|Q|6^MKaMv>6F8 z`$BUq>J!fl`vg}5$_EUnT`iA+MX zLW;hFDCC0KB#9`Axh!mk(RV8`Qh^Y&L(+7GMXA+@WzqYjqJAtc=K&1o^Wbyx z;6n@8Pci~sDoW1(-O+$^)Nwz=aKChMUOG=NvAPc(Dwoi#bJqLuZJ&3{56L?(6O7J3 zk8@7Ur6lt5ZJpmLE(1f31$}9IXfO_ec~M$uL~X=fW<4lr@GGf@)EXiclT4~c8aITH z$XLwq-rCY@$$uM{_u~!$?cmxwP}wXb4g-t z+D9E;L>#0PcLZz@xYKjH$!xb1kDpxe`1%RY-g?Gn@=;BSkvMGq zAW6Q6rX7_R?qC%Z;z&x45^%Cj^ut^NzNG z+Ul?}!*I?5wpa+EW{kqkf8Ri0#-Ydyfqq;m@~t=`n+9)VanubB8CK}zIelDx*^7HxXGO#o@uq9 z<}*~IF>N+rjeqtB-{dQQ_zkRi2k34)b%0ba?t-DMEAXPL2;TqbB_Dk7lB=tcpZ&t8 z`OHth!!%wwdZ1^aT3l!cFLWWtu46ZsC8ms|f!K>xTMA=Hy}J&WG(s9Es~-$GI`caO zrLDzr0%1T!Px+cLCwDk8_`MSY<61A-rOwQ z-YvX%dC%kPJMQ;0@4ovEo6Q894dZxRf(^c2tc_xg(7EI(XRP`%w8f0{rM7guu5;9@ zvrX`HA*}^7AFo&hDXu1pF*={z+~m~C;-tw2%Y4gMzV;oy|HC)loEax%#9CLER`%c% z5$XIBqebQR?vBkgaQo$3KKKe1gHbIYwYvJCDI%3314DL4wpt=W32~C+Yd$yJVYRcBz+Rm&**(%a7%DLrL6MYHGBDdJ;Z50@7ynML6^ISa~03!L3eqmzCIinr-)jkt{zI8Lt{QDDQ8-0 zgeI6qcb`e11?B16*VI?e7dP|ywF;gpADv?7_|I;#5MLG%2XYiz+tYgI{pBzJKHvJz z_j|;dYm{3l?vk^WYup3!C&X=Z?))|J;3kUEQe}f)f|jm$$d~_dK2-b8~aU zkOO5&&Ox`@;Z}iCSJ!rjq0dqiRVuNmV~)*764t-DRSk&~M)N(07Dv|hud8DaD)qj( zI;A^4OIujyH%Rbt%2&SjZNB;47u|h&M0r>TXDYR{e#i&UBQ*tU=&~|pj|(i?_|~_+ zONzpueedTydMyMGd0!S9l@KQ^8X+htB-ZA$`;ZYr6dXl&rhIRyc zqS6I0>NlF8*5PFyav@#nS=-FlzWUGj#y7uDO5Vr-w6b>RYtNfizj<_UrZ0MrA=laQ z1K;}A`;61TJMTVYng(byMH@pJ5JE>4^u1RnhWak2P?w5@=qQX zVw_NM!`GX24{PJFtbaU$uGad$8HVAnoU235L!vLc^gn6#ec5H7%NWm@ESIzKhi2E8 zlD>xym3f|d{P^*MiA0xUqEFfhoU3%sMrNUXsM2?#U*OnAO!KX<1QS$t0RaQfxHqi8!Tkc)7xuNj=opdh$!m z*%>B52<`as^r9cSBrpV2XT~)0wLkbHzVXfPIh?EZuZIa&yOBI(mx+nToW&SuYhzhg zT63L%;Ymm_I*sw`fAAd$#!r3jIji_Af831F0<|^DGPBMrAtllfX%&+CHQP*`>!RXD zn`9`F5MdZcQqD*Wv|7l~UCb8f>=7dhG+WUs*f^4>9cbY@-}{iSeC@kF?(0URX~-@s z>^B)du#8e?mm&tYnBUJc`}>)gTr$^6;|Je=pK*j|Pd#MC`6e4zM$&w1zc7gZ1aP5|W2fFUw5I12ww6d@Y4M!gs&>n(ut~6>7dP zY@H{bQV%;xnRW34Z%9JkdXDU}tQ_VA)r!ta%!v>K|LmLJ=JEB8pZVF(vsw?mZjDV! zorP~6kElYHhG?S}#}Mr$Gb9I^Mz;`$=<$%IY*M5(H!BnotQcvN2+iGqT4C6vV=@55=$hl;9BQ}3cZ_Yf z&zsJaTKL8veb<+X5nAzE!CP-V>X=d2tZTQxcL_VY-Ic2;O6iemk$EnJK@e+v=UYGE z?WZF;D!Z#EwArO`OIfjMq$zg?qk>f|XCmTDujo2%iGi}Lu6qwg3Z5sa#hr;nS4*tR z;@>dcd<6-O0oA~Ac+LKB%kTc)*V)haohj6~-fbPZ91>>1*(>XUn33ajqB5?{$Z6!! zaFbwpN!JMxdH7ZAM2X=g7RjB7F1P-{YOPc5HS}P;=R68l-FEkM3Mo=V)+EH~6@t z6~(e3Cy$CBn3(u%I(jmYOU6C#ReH#(YVfgAJqAzVfvsichd+G7JMX^5xETooS67oCyg1AbQ_8wf zR%hHV1rmXIuFx7K1O^c-M%ro&L0AwhxYIT&Ov4qs=L7rVT$w*s(7*iUFV|oAg_f_uPts8zuVn%rf5vWVe(ufb!JKxV+>yQ_w&jyWNvToczwI)?L0c4 zB@O=egAxay<=5uqZ;6T2!C*}zD#DN^%6#908`6nkF2NZbf}5-ip&Bgv1DnmnI1C;l zq2i(0O}M++^XBG;oSZ~>b+vPoo5IjPz9h;J!~=%am!vUyp)ae?!moB4ZtwP|w4a;1 zJK|Ibo$@))*((tl!Rs*Ee_Mq0ghW@Z@^uvwW@OG`UMw8$-&Z=!MxTV)J&WL8aw*f zqU+I9q5~WI_o)XK2570>W8a`|#Bbt(&T1@SAApu3!m{`fbgb`t`85W`9xgRDE%sp;f5&cfOo% zvGe7P-ELr>8@IQ&+&`K6c=UmS-X)BG7x=qB|MNfpXusd{{Q2|0d^jBb>nWvQk1_tD zh=g-(^m!3Kx;D>UmzRa-RCTpFFu$3fFHQGtyH=C~4S zLan&#Qj}Z;&GzvU)?iK%*2b&lj<%{_v3qRVDT`67bIDDRWbTIRe3WDNCModZ2e;ii zsx+%yUr+8*?YPmp%pINDvl5#kDKP{=JP?!+M^u%~7@23K*5Y@7qR5bu6e!D#iU($t zwW75ULRfpCuWR%}%Cxp;EqiY7 zRzmc7`Y>(CL;vQN*d4Z!9F?}N4z3i>S`GbflEy@76{5qN_V7b3;({1!w5FohuEbFXWqhE(xvPiQ>CI%t6>(|jsu6<9hNcrxJd$On4F~8 z)0B?TtC%xFpjq<-qUJMeHP5>ZeZel-4R9g#z!%(fWBuzNW5k+|twQklK8evi8m*nw zOc)rAahlx49uvnvJk+|xw_z4MQ#JU_RHiL+Rj#f#91eTW8vrVmbza!+28LndfV9)i z+)!~ma4joyYeZH)cy-U!^G_kIVXZRvh(Jr3aU97pvNq?9YHM$TW2McaPG|hX{}762*0OLf~<3KJ|snWe~`D zxBsWnA?eG#IVjSc*rsVBg@%^u$Wq)0Bvz=v{h~+;Bop!!yjv1qf}W~=Cua~`l6K^+ z1oNV^)|oLSmcyZU6VA)tT}`fzkc5>L!ANm9L5D(9mb$R|9@Ix49kq*QcGo*@Zf`pe z1+w_uwJZk*i1nqI#etL}9A?)F=dBlzvNCKZBn0N-nVEu{bkvN}mv1LbZVwhPGyN`Ht`?}*)Gn>tX2@H844%?n6RW) zwXC$N+#U`mf@8}5b*L3m3{;;gu+Ei`22u(P48#Od3k7reXUI;*Y%7iC62@Z+wJKH% zG4{XH`SCQP#m2fEpeVPmUsB6~JZxC&fyYmtP^%l)q=$ZIOHS|X)XOG{BlaL8)`^^q1rJ5fNst`>y*)^FR2(57IPE|Gir4 zXQpZTcY5Ir=dAMcu;@=h$6j`z4_W0emyMVIKX$h{=RX#ycPX8GsB6D8J6*Ej|D=!m zl0WkhkLLLHFP)*s@zD9(S=SX+J*5#{%0(}C1P?*NQj8??;yc$s(!wm=Z8k=-z_K zR2*b$(g?Nng=k>dn1556XPO3tx~^#T5x^JXr!Xs|D8wOP?KldWSq_z8f!r2wlqO_|=;AtfHDAO@N-k%#>SG83m>2QVl^Zd`$jGpJ#Np6b*8|h`%9DkHk;f78 zNU#;kQ63w;b8U`Qjl+nfc(SAi@f=To9e7W8KNm_c@^VWQFD^=;g>+KMAcg2ab#iir zONRs-YpHKjE|vtw)Tb8nnEj&^K!bT34$ zF8!<8NO>gWfVDzh-KiTT`E!60Wk6d2YpxdQadx2|5zUPdGq<+~EcpBOeNb}4(6V?^ z5`o-Zw3Y;GjZzIQl`Pq#{Y05pc=q^;@FLKpvd)E5}kXw zoO~!0`#1-`T!ub$E4Y+4p3539-KUqj`AbB=@$ICPSl9LR@l4b7$7G9_Gx_sH@MW0D z_DSN!Yu6=PZM111N%epP5~~f2gR&~5B!q)mYTzTTl9q%@@ ztsUDd{G)&TExz^#KlEkjTG(udo&YuU8FK8)Df4ke*S4n+Xx(-#YR+C!=_8&-q@fZ1 z;19mX^)B#<-RymzX?v5F0|6f;W1MV47-7#m9iJ)Pshn(iQj`9WY3f*rkL1eZLh~|k`*NIfu0cP~K|M$59!*66 zPd5`keEE_oXDk{+O02~Q(#X+^ng&7EO0&lO{T;XWGk@vVzQkAm@OwOe`_t^MuTT+! zHKM6s2{AX^938D@9F~RsyhpV1!4H1O;coBFJ0jCI5)*9lmR5|ryIW6}$|JRwju+^P zp`ML;ck`O7>qq46&Rvf4%+2jRY0TWdc@1sm3t#v-#@#ij6B;pJmdTO)Xnv#cxho9A zrlWhk8{QvgPxBFR7V9zYt9O(sI)lVakq}v0^Z;d3-n@K8+28Z%**hHWUiKSkWY|3+ z5LgcPYzChJFU7k@wMJQ2e|JP`EsWDZN&|=ambM(2tB}Wu{rx@Dka_F*6H?5CA$vfE zx@<6rcZ#70AfFJjr`K{Irrgu!{f4EjQdJ%OYsb`k95HJUbHHk&h|t!V@BiTYPWp?1 z{p}r39`DfT2}#;k%3M#9I}36GWzF+}A;+F1HnV&5r~}_Tez=z?iA)`ljI5xMTIQiH?b2(>9EkrdM*=4ptJWH0~az1?Y=ka@v!QIab zZ9VYAAAG>NtZcRuhx<2NU2UB4)u5Kfvd&y>wvGhm7(`z>w9Uh%YisPTHpD#n>+{tO zclUd?S3BvJ2JbRJ`h3ZI8L{_CVI1c(`17v) zp#|_mZrO8_)^QJU`TowwMdzxQOC^$-5w?NxjeovF8lX03QzY1g0Ksk2+6jyYY2-0+ zxb-efRXEIzAaK~@}a46($6iQUfOR{Q&VUVrqF!@flM=`Z{=W5|63HXtFgE(gi=QE#U95)nO zxm^lU8!>p-yUYy+Ws?R{%1FfZ*5>zXQ)4YX7@OR4OX)%0zBDz7i21xF`zPHzXK9W7T)2L;BOu(~-Z)w}XFl35 zeCE?{p$w{HcTW+UC1%gXe|2`Qe)T+w1ZKW18usZ92&3d9dlX##TE4P z$KU&VfA3}g>EG@D{||rVSAOLeUcP+!H+H+-|2XFyL}WT2!JNw_&kN?U@Sm$qjsY5% z0nkTTV~mku7*56d(y@8$b{`6PzEtR38k{aM0uNClFGok0QpC&TqhoP@h%5DOd~?UuqaE96#jHP85uNWF(NXvq{7#s)%_$ zsU#19a1fJp${@66ARYihN^WTCVZpT-H6-@?J?JZBAUt`0DAU<v>-eJbChnXHTy9;SWFZ+e7MO67k#2{r!Q*R~xRMUh(3^8=rZPBl9{tSujA_M8;|4 z`tcLSVM7{6a!fwr=wLC-c`c?DC8IGDQ-(YoO$tTCQlPpBQXYdR~xiLR!ZqV zDW&|*dDPmundjVub1aaLd8Cb3;)pXUGiowHSOnk zfa8zj=;<<{=-fGac`Gi)ZJ4YdbGE}#y%NY6QlX83 zs!jF#>sa6hv@9B9=Tr;RVs zjyDl?xuqi9-5m&NWZYbl(~;*PE^kv0=r!}Gy3&-=Jmf-pAhd;mm@`-ik(@UkNF9S` zPaoOl!-&L$iib%M6HTn|1+2?6GuFGpa7?!$I97G7)MiLd5CXg1hQr-!=6R)*%9uwV zdGu^lYmH$XS(k;wVUIRt+Ke6x7oeQUS5ajtm3eJcHI`CXYhhiz14KO`DMfcrYAa~1 z-R0QFiJ{x^RZodcQ6fPc18i!PcC@ei%w3y@Z;U~(+LMeVkfO^ThiTxjpZVycSG1}O zWA2%*>Xb+IThm+$Z(i;Z6RtL+kBGWl(mCTG`3kk<)ZSW9D}+9yrn_K|OZ3p=38{Xd z)#7AC=~x6&C19sK+SqR=<`GS(dQPaIw7M{iV^@^9YgSBrY1}GTyA6j!;pOW)QX2eq zIK&faG{(TVnOJ7!&8r)rF--$&sf6GmCoyFz##)b#-wG707P7i(#@()-=priwBC!OP z+CWw`;(Q(jP0CuT@3G7}F>)jcXj#Z6|K)V(f7;_WfAcrL27C?pPXT`ASAHcd%ktk) z)h`ai@E@-0I>Z>?ITo<RECSPJ;`!TevmEwJ*N@oju4sCo z6{iYH6z*;p)}??9Xdbz{-+QE49oF;@rS8uMjd*-cxb2?;j0J(={QCtfla1 z`^42Yk$zxQOwD%~`#q{ct-dfHhk-Wrg4LR90{h3>)I5kKc5y)PsKW(cnmbvdLtI?M z=z-1Vn)V=()(+0L@BEy*`vc2TNaNt4Bgqf;VRKE6fpt|LKYfNuA_Rrzu1=H0FpNC^ z)N|%#;pt|emP)h5vAX`s;c!=2=0eDGhogDC-5ZpVz_Ju-o6%yB6o!DZl5iSmoEtJm zViu$nY)GUWp(<+?TD|9f7Ge~_82{xg=nr)73jFW-FaJmHz4zYd=Xw4QLJ0pg5&1XH zi|TRNcz1Wl_4V~1lMo*N{5aA$j&&|aEa$WNhX7&^acnL*@|Tf%4`q-(B+I-U&m3p% z=cA`fef>ibeeb{cKCuK^t_;IOZ2_pnEVQ;_5?Na&nSmaVX@pW?5%$X+W0_#@CJvE6 zYwF?!jBGw?SnHnIlvXPD`+Mej&;6Sl9zT0V9w%g3y2H(i6!S(Dppd|L@ayyHe6cbjQ$04oX zh_oVy;<7psY$*hc+8V*L%T9|z(_;*op$Bt^YctmMKwS&BuU}E>%I@)F+PaWp@&E^n zx88c&_4_^i!@84F%~Rf`DZ8sHc2`$`Qk&9BUubG0r4a+(yt!eTb_lS{MhwEbtgagG zovxW69XLgghtt#8PI``oxhxZU4ruE|(r7*1$wd3Uz)oqTy3t{@89&d z<4H(44Wu}dvo`{ShJ|=a@@Z=1VPZ2~QM9@;COPMQnl>;_>|efumme~`omicq>S0{RM64b`=K@ad{p}rByRDm&RFS@42^d%1$XL}F#)+zsa^msRC)~Y$ z#r|;b2TF9NQV1251thR6dk;mS5>^io58IJRl-0}wTC{N}E4nwXuAJx7%+)_R3ge(0 zW}%gTMGE@m=aj(%iAt;`#bbLL~Wpl0jam?66L3R^$ ze#H0p3+n;#FAmV*z}59cnkLrU`#$#aZ#I9ec?be(UU(6|Mw>ehyAqC~N+Pn|ZMl2% zin265_36*Cx!#eYki~Bw5)-i-psa_wswrjhq$d-{%35-J!TH;|EbI^I-_Jj`OQy|bG~edYhUHF?T9B9+ zrLjt)mBug_Qk9C4*F+0mv>Ofq!h$d6#)R46b8_i1TQNC@f)Uz|7=^WmKnD?OQ}m-3 zEQiW`nAt{GfC$!&L~ije>w#K5C|ov=yR%d~;~GcuY9vJ`CrSWBd361Rciw&Ckzn{j z)W6$(CM>bf!>tior|?QI+IAdWWzuxC>Z=!BgFtfabVrS8UAv7P60XFN5P19T=bchm zJR+i&?nuM~m^rdLTzS)CB~)Kny1}XQBn|&2&w+LE^q(}2JbN0se)`zeI4OCSq-hUq z0I`T2F|2JM=W@yiRiLVmH3*52GS(JM3nK$V9U2vjZPE^}0Ybp3?QxZ#KI ze~4NoX1BQ$(h0~GQ|z6;&#Kel1z4-15*c!!mUc>43YO7!PfC&Nal_m1M4ml*>>(J@ z7nsh9cSD&85EK-$L|R{bhj1J+`He=#+?S`?Uqg{79mXY!ZwoS-BH6NIDioeQ|1{gH z$9(kuN3^yw?`KRR!??j}>4@G;?HSb0YBWOfywKL{#E4NdQV`ORK$T%pw8EpSE8hOp zQ>=CIrCJXV2^4`8B11~ljqedy3+2ifInd_hug(5^YXR9rhLpKoD=ju`R!UwSJ3Qnc zkAi;w_~tjidDrLfUjzQ<@4fe4Fth)@h&%`WW(eW)BJ$*+%+yN>d)F0}& z&kOZAhW9)$`ytl*L!J3~h{d|DpJHpkA`ZVG8kY_6}!<47>URq=-E>?m9nU(6+uE(Lf=jF*Mol^-Tm8o)6@@b@5&n}eKu{U zJwgn}1ztm<5rcRB0v>fJM|_1KL$~!?g6yn$(?(E3gD@Op3R7pl)GoLYFSu&>a}-?J zW7W{=IEG=|u-$ICyDj8lWVe~{wWIk0Hwe+}IMM3Oh!ArknH!qC5%519^FZ705gI9F zHd~L|6br;Wc;n$$0Z(SiuIPzrM66I+fTdEmN)Y$fkcE0sv@Eo+;UMac-KKsk zaJw%*eg*x3@r(lhQUB%t;Jx?WyHeG6bI$M7TK_!}c>?^cUQFM)jIDc!zkVr0ye#II zl*muI8Jz3RA9|bTw*K>A?IRfNGL7k|-#`BSmKxkBnpTKH3XR1II%k>*d9KuCsI3e( zv1lc%Zsl*CEa(UlpNX1viCb&LKC2aj);#6LOi?`M4ulwuaolqC=rPN>x(rK>^t=v3 z5(vYl7tBV?qt9fe5@J6D%S;T$kbHkI4hbPKjT0n+CLONSf#6*+VSZV6RnA$l_NcYc zrF)^9Y`PpU^pT8svXCPRdX{7-eWe(w)R++<@yJDPm@=cn4Q2_l^m2xXaj zT8%plV;GUVdisyJ8YG$HereSuppyFY3=$kI>n5s%w(5mJ0vd!i7g7k_;p+%mk)!e_ z^rNJYB{U+r7ct2MspQnCIgrN)#lL1lO5D$tG!2Ac9!8=)ZcrWn+uCt%A84(TdP0wy zIi|pZx5rj}7F-s>cIU6p=;0MEsq)mM5Xilgcr-8#hqq?vhW~v!Me5vdhW>PL87-0oa_C?< zX{4AsD%Xjegov02r&x0oL2HKSN{(AvzC+b0YhyDeLQ2f*?DESr5OSc_1EDuc>*}Ms zwJwOHAOC{>K!Lvl{;>b}t>f?i{LlaVTfi>>|E;qEIRL2_*1v9MkIXFmNkP^R(In58 zmPZ=pLm?ZNH-U!^3V_XKb9x)+qnVuZk1R}Y-zYcx8>UTW8VA$@0}1+zacyhwh$1Bk zVc%%cBhzAYHg;<+k7`9vN&{`H%L2oZP}j2?323djLb{QI%jsHcoq2sE@Fln9hlHfb zsd&v3Wnv7J!%aty2Dfe(2S-VOA!e5*c0-VKSERPp=d2bG@xTXn23p7AdZ*@-m)LpR z$8Ua@V@g+3_^H6L{Ck%v5X=$0s>LJVtn~~_$U|aYmBz=R+A%_H?$jg%mjm`z&&N7O z?n}mYw$KbApr$?}Zi?jKUE)!jtwt1c$(stp5NVw)=^dqzM$Z-%p!PX^5DyfY%gX++ zXBv&`IG)rplKn5oK0+x9)8xh_t*a|WR56k-7g2&FLd;(HM4&qIx1lbr6hBB}2wlv6 zGzR)>W*A1INH@4SC9&1kyYwzkHdh`Y&acOO5@QlbDLQ>I^&UC68&u7AFWPTFKABUX zLW|CqiGJHk;G{+kv~H*yhtOyEPHz+u-?gX_Ojy*BxZo*NgG5IT#E8TJWnqXov`!W6 zw@=kdBe?6eODGLxUKQCXNh60A*ltIf3EB!%oG4b=Xe7tcgKGL1aF-%5Qx_lc{r_D- z{}afP9|8aO{^P;Nd+)vXOhkTGM1IB0{yV@ILI}?;Wrq(HBZUH8N^(8`L6zrf|B!st1i^u^N< zJrSr|>0|I|wU(oj#>=oo&}u&a^_(F8SVCWZ_d;XV({IfB?7n{z;^e@iZ9K;8qaQ7_ zvi711aR>~O8HP-$J}$5pdrVt9(I~aGuJ!TaH4I~)1NRuW+6ZaF+U$!%2@KiUGQoFv zJ@QP5(XaRsp-I1?1$WBE-p$f2CWes33su);lB2L02Bs)jtyu05vXH59Wi3h`2gU|# zhLjfe^GvIah+uNqtsme(UAhdfoGms+Kn*{(suNjy@dX?^+1bO{HBpY z=s^=lo=YF)bX|JW(z)x$X`4E*EXc?4c)^uHeh7Bu&(VQe3QP0lVvc>~A~0??92SSO zP1DpH8u5b*-{CmLu`79!-++i7C)aQ}r#2;xLstN)JC?=wNYa6HK2|y&7ET;3G(z$n z$+9lwF%VKc*e_b-8$z<&n(ufFu9FAZik znAzV{)vFM~zYn|x{2AcU`Rx2S61h~wToN6RW0P}((fQK$5)O9m4n3z@iU>hRq$oo- z7>QKEeW6MRPD#Q>LBbVL_oygM)Uz%<1I+(j$mA>(E3U&$UWl!?yeb}IYqok;WrtDa z6gZS_H3zDfbFWNsU>J62S+H(&Nn@Za_gz`-uEh|Hf|A45$#gk0juYdMs6Fvz8b&mD zs?h2A=`8GHQL8~AHABY9Okh?t*eeCQ-sdx3# zQ2>pjqtj0M^e9K1te~CYGKIvr=>amh-a80XU0B!Z4E6qBqBkpemtC~FI%>?_Jmzy| zX`QOrDUvaPX?9>%@LOEts9u2~MI;I_dnFYVQ6G1?QOXTMer{N|zC{SodOohjj~%fl z_`%T3!D@K4n?%3uIEzSney38ckyCUZfmN~uw0d~Ov>91v-z|9qH8>vzqgrvtu?QB_ z5y2dv_~2tP>7I%dk(e+U`%R@EPz@yc_mB1@q!5MsWhS>q6Jy;v?szH2wkk*?T7*=v zrmRh{VPq#`SKK75g`X7k|AOk86KK32Z9AH(LxN-DQ{hg;WIne;EEmRpnAI2dWf!ToRc_P`hH$Lf=wbJcA02Q{zAuy zA|Y)E=A)8z-V=w3Vcb!x(pX&4BDqH{LJULqF{m@nt83E5q_buE zq16nc_3YBxU$YHa9Kov%ma61<%hDQ;Lt?WV*^QA$|X=_N&mrn@4ff#FbtU4ziVdCRQ2B$k)LMIXEYO#v$A>!f^D#`$ z`A1}o=Zo02xp7L<4MRwL_N_;J^M~*A_T~{g-BPWvKdjupnc3go@$|{tjJllD zS2Lva*{}2vljh%KAvlNp$N~u(P6ieihy+5AzGP|y$ux{wSGJo+K9esCNTihmrOrN@ z>5IJM1p7EU4tSCAtVl1&(>T#O;?~E@-eDRJ#|i`pnPx{Ni1dyvo;vwsa=k~awQj@D zy_;^mQ}1X9-05f0yZ0~*$a?6ub2ov|lY0W)ooLm^6Dc9oz7O_AVx_~=hJ++x$^%16 zZZQ|bq7s!}&75jz&4U`kkxhaUtxE{y7&F+P1@R?hI8Fnt3;v`d5L)e>x{^eF$rl8I z(I}^Y3JFSWUdU0SG^KTp%nHDno0w8HI>9bQ-_$j;j8$qi^y&}a=+g@ zH@%NXlmNCm<aPM zTO&N42zN7ctGxU6j;oltxmy^d@_XOA<#UflY}jTfWZ}YAF3+#i2Y!kajBcB}ye)#&1SGOOqdHft}n|l$vHcQ>$j3~UR(z%|M>3$%8ieQ;ZP$}`)l5h}qfCQ$x~2BLh#mrhOSrRD**QuLR{!|+xZa!(|h1eC+Lb2x3$10cdH!fQ_JL zKmDH^fA5!m>6do$aRvXYB9cVpi)Qv;?Opo6)5k68d_lU|Y)%j_Gb5}cal3GLH}m$@ zBQ~22|M>U6#r|f&QYOrWX+JOz*L?2t&-u;|Uoco;7}h0axfW59NRRdk{VLn~xP&h4 zQ_srGer1J#1P^+U7>LnMg&_!pVK^1g7;>L*xQar=M-I@n>f&xX`uA-fvd6J?V^YeV zzV2#@qr8?3bKq16y`V}!7iG*I^VhU>E=gBl^_zu+ z1g#K*OXjSu9-bf$l4@3=1urVrPO?o8nL5tDIn9Av^V?9Wl_ZHgCZstwwjIAFeG{37 zK$4N7#cw@*Y!yO3G^~=s2J1TXb#~(EZZk4&C(<ZzM59S6Z17jx(>;fa=ekLd$(mq>ZHB5DdW&n76ix&+Z=cfBC21 zV^C%D_FOD632Qf=Rc@X&*h{FI*GX47YAjG4V8?aGX7BFXFz0 zj3#}l<&HQj3yjfIi4ceh>sNXupt^dfK&?K43C1)Irvgpu)^I!=*cwzVCu*VeZ(f(Y zOE@N^<~H-Ltf^Yv#n)Y&)>bSwVi<{7A5VE# z8fbns#|=;3Q32UaN7;O?FQO#t4EE3u4^{6FLm%>skwfZENmtgy6bPnB9?=G>rT-9O z^08BpVAXXnj(#GwDX5PcDgR1bBCE<-gc+Wd7VblFd5)pW>TG8sW%hVb<4SeU-Esv6NXcMpA|A_6gXIwwp@Zx3U z=5Ei+?Vc&@nB&Sd8;UHX>Df;T`oF4=FMs*Vzkl}2-#Y)ZfBnxrl{j5gn_BrpzT~yOXoVG-R5aD9&)>{0!uZmg3f^;E`1G0?Zh+Nf^OVY<6jt!7jU1pXdRr)BQG(V71Bt%2h zL0(G58Z^}T8tP8Sb-tk$mp+ClegL$B)Pl82wIk)EGjWCtA)-{Ek%J&D5(k&HI)uTP zdk2|=AXd7%$q2!37e10uLa7vmoP1oRwe&GhCG_xSGr?GWEKq&NP)h55tk{_^N~Mva zU#Y~P*20v>E+aH7HiuMMSK&n0dy7a%=mO29nV3?K{FPeBF%pLXRiEYS@djo})Qkjo ztHxl?^ACzP$4W%=Ae5kPCaXXQ&UWufc?8L3$??sA)t@Xy zf9xLr=3o4*OuK7AiCb%|Awe)64cE;2L%#6tyF5yX$D4_pd*i)NKjU}5@<+VBIl%RR zS&&D$jbvKVDmf;yS7)|J{j)g;!TL!LlRS+M3stF8y?x}a96#h7Dc7zbh$ z=7T%-%!E8mh$Pmgh%U5s!KMvsnMnbbB`}15)rGq`FpdLvt8>t;38k$b;7~i!FGp(e zd3t_)<@5fqdRAjIh8!8A%K}3!zVJI7s5)az#O(xYB@ez6zzkcI!{N>|K$B6MP{e4n zvdj$|gt;i13$%hpVO1d(uq?`ui<@3FqNPBn-Aycvsc&CXM(2XA38GLHf~`bTvR2xBPu7Jd z){8K-r4XwUqp-EWigI^T8K#kWDcy);#e(C=_4=kn^wD1f_P?U7&@=L zLEH`g`b5#Xy6d*@QEDfVHn09vvPata)d%b9E(-w*8C@HPnwPt>>c( zv{DH}MwSs(H^0@jur3ShQe8SZxZJm`ilxSWtw@{rg`a)Oo7-E~!=AUEKjL$rdcrrp z^C91Vb;q--iH3Ptcm0X6=*R9MZ{84}UB@Ypqg@ZQn|p5V6_p#FU%kZ#uRr8#-`TNN zx!d*jWmAhoiJ69fr?@X?Bm15y@J9H}DI*B_9@6J_#f6d;lr zro<0FeCbhns?5c(Vhn?lMOYLL4VI$pt^=jsGHeFQUU{+^c>A*(-g^F79=~-(Sm1+~ zA7L1q&11gyJ6~mEw>*0HZF0Ki{>>eG;K?rWYMohcK4Oz2Wp9KKSsJVjCNZWWgU8qgCO^xg98u`@RwKzPz zLUmxj7B&=WHLMD+KQx{`j^sG7UuLG3J)Nlr8Uy!p;c6T_FEkip(Yf_g6E#-o5?wmtx+^k#*D5jDf^6gPvlAxAKe|;O^KWWL-O3vR%T)h z%q0b10rAeRJ=(uPFz1*$86X&5be!c6s3StA!;D?Dq=|Wl9kl zBGD3I8lVEvcLWKgbZ1%9=0G%zqBGJ8+v^>NyFKkLu?ZP1!hZ4Fq>MsJ-BBC^(h^vu zg^k}@hLKh(=t@jN-5V{A+#F^iD^m(AD8qJwW%W=CQz%O9eSNb)DH)P8`%7ue%j#LK z&A5*?s$_-N&JUihg`J*COW z=4uCR<@0Y({LX*=Eo6XNU{*I?Oyk7Wvu7Oc4=nqc)%JwirDPU5bSt3ZhK!|F1_}Lo z3Ne~@aUB?(O%y9IY(UzG zq=L0bT^lQ<2S`J0jkPb<HwnOyM$UnvO;NSG(wA1jFc0@I1<7Dp}0<61I^&kG=RaXjkXr% z*0|nmNCNl!J!?6fq@ijaAW;`(je&J3^ zk{B8jRvM-&H6&8b3<@nqbX{T0WGA>{7JO_W5y$@+&DWJ+-7ptm2pxrBff$rh10gg| za_XA$F$h%~P4H2Xb{8xTRSW7PlTdv8p&^lbChQ4fC$1<-P7@>VcK&=@Ky0O1AW&## zJzT}GTG5c8)DDd^7zC+w7EIUo_b_bhehbvC|E3PJs}%_9DNL=q}Rug<&`HQ;)XHWrSg%t@nKQgBuR(fk)TZJl-Z=-mkR#d#;{8=5aI_Mt<(6 zzr;7c^KEWd{Yi)ZlxfStI897jVSf{_Y*_LIV6cp!XlIx+ z7k1YfWJFr++DA84gzMm%?+8`|k|!xiQ))^CTd5_GOGKnHZU>|Y46am(GQntw1%^6f zG9sZ!m41>cr8lzECu?qFFd!L5MKqyOF%mh+ zDXb!m6|;;q*Y_&|N!Y~!(awC~2+@=-J_M^unIN#h>{|VV5?i2%FLI(7s~S1N^5zB$ zZV2wz*pW-SY! z`}C)%K@n|KZH&9fopzYrPdfA;ug9T55qEhZ}sAcAz#~W@B zBd>41M_nLnCt?tG!!;o&FJFGd&wc(a{^6IuL0gPCO?>vR}urf~7|4k~|BU)((u1K8Mg)_Wto3VCB}k z?J+Xn9Ty{Uia5(XOu46I8- z@`}zrug<~HkbS``fhL0O3o1gH_grlxDJn>S&2){VL_A6p6EFveisgvt!g{~5 z+dbuA2U3OYW};QYCT9eNRVl|n4~-0Z&tjFO-Ll?C)FRWBVQZo$(ED5N_m#(21CO3w zV`A*@E1L}CTc4uLGly3GEPPcTZYXQpMUT3eEn;Gz{^)}ep1kX+#Y}Z z*Z*qRTy1l(u>I!Ozxwj}*$%Z#97lq>)37cpF(~uRYuB)=^VKB`9M**^5#E1s;L&F{ zJPI4~?g|+vtgTGrmbn#dQPS0hAw>@NmD?9TV1H;xHpU^KM6?(o3(+!B8s@|-=b|_N z<{ff4IW@7sCS~r|g&Z@bx=AXi(Ik>$Kv=1z5w<&IX_Ui@&dX48o@j9(&UcthXj*8c z5ebwA(JDx!wC1yH3*>Q2-d=GCO4I~(b>)IN%`#PGE`=Nih9^79Qkcuk*b+8n%3K}G z8(il;&-di)sN1p}NFlJyg<*TecK4W~j>gqygq&%0>5+GxOlT2}jjFO zToskT?S27+JY2aJymh5gYZP;xcp7>!*UmHPj}|^YzzO&gRue6N;F#HSZhweIl8i>f zXDyMSjcUTvt7}H?*v|`B&wd(OWu+1`u4>YNhQxYzM~;zsE#$CgUK;u8In)_l6|+6- z-5nMpr4~q6+#l{q(QgT^{|{V0dO}EpGkAuC1w~rw3(v-~z9!a6LwWr8vmT-@0kV-b z5v7v0zQ5RDn7KQdj-{>7gU>mlZ}Y1(+n zoLJ{WHz6rvjrmA^T<)>8f+S=!5JH9un=wOzP}Svqs>IyLA@TZVMv~FmLXa)f6qu_r zk{tTg4g_n|r6T#-`4-t1nigI9SelY(6qK+A2Qih#X1AefLxQ3$5b$v7pvIxD#C65u zL>57!u>v+9ywgh=YUy||m)W%(vBiTGATw+qc}n~U_b=~}NOy;V)E+(9jA=7ai%&!w z!Zb}TKdT-$r&7^HG2Md<3}d1!3t9@YdCWLPYUzfO-pxkb1cP|D8^SUE&ZT}56|u^C z2&AcD#o=DHdhTWl-r<_K1W-z0Rb|{=v+UmxLh3x5LhYRPEZ)%~fmSNx)fL);J3xyY zsd9{r*N-q;U3HMoPwE! z6gOBhsEHKCe=lW+CU36L*2n=uGGdKX8QJbe_OD+c($G5l=cX&Wr=P>ZNK8g(La~`P z0~6G_fCy!2EL5&yKx_o7)VMOwl{OdJdSGcnN=hq*V1foc1#X*0#wobWwX7XhmQk$? zdBTEmclVkc#-9}QAGgP^{PHh{6lyNkw)eODmzz9d;}%`!6LVwF$`Av&1&TCheYD{7 zO>_P1T8igK#(;?@yr4%$v@^s*jL=|3$p&jH&KWl+Mp}a=mB9v-!hXNF)Gj3tc2);+ z87oOrPbLzyR@&;ASRz<8su<&#$RV({o;`Uijn$WnRST^OnMP5dd9X(?C{ak}Jojkg zwfqzZ0WGwfusQX5`+Th5k zfj}W$J@;jz_;>~X484yy>169O45lF@T0M*KAgcFlPv*z-esDaiTAxrVax|yOH ziGz@H@Wpp?j!({!e7rA&K&wi6`i$kpOJ}945Rzdjdoaq0%;@r2Rr4U{X(F_WjT49O zeTSAE^U#8HMmiJ>nHMA)TA_tR9R2ejuby-?^Z^@2*ZJ3#ko(uP8i7I;&nl% z{CsIM?f#Y_yT&?3_dsZFs77bjU{p2QeIaG1RVGP3%TAp*s!*z8FJBNlW1QTd-zv1C z#AHaTR598rNNu#3$r7*#_aA%@nKFUkMka$qqcvQ1J0{c;A%nC^#wf#pF1JWXl*l?56d{d1Zj)9CITBT2++akOW%iMu{shkT zWA~^bkW`47ejRqM`MQ5aPC|*1DZlbwEON*sk!dtib#tO=SL(E^fu2x6;ws(kGc zUZXFqf*5rLi`5rf5?Mm!{>|dVxk1nvSl5QeK&CUMn_(%Da)c_FtX-kfI$#QyJ*LQE zp2^chPQo@%)aGeGT41S#AtahKQVtX%slgyZm@@Nz?FHB4&4Tr@LH1>tF83UkJGRp` zU@Y~(_SrL*d7;jQ92c}Dkjh$Ca!BrcER_^?v}mMcpvp2AKM+G8ZZftQbzME$t+UL{ ztRrX>!8|wtlqAP*#hznoN=&0WYWvqTB$y0LJiAo{Uu+J7R!CvRLT0&naVpxCL>vpU zG*k;YKf&rAqmlBKxV>`oizz88sF5CRq3mfSBnqm2TM(UD=89M$$_Ub9sZrzh|@EGHka!lCQffJ4MZ`FHL)xg~XBi@*^Znr+iX>cv6y>t7UXBQZs5w zG;3%S!dl45pGWD<#4v=O=NTxiQCB4bO=m)o?kx7hQVfcShnO@$!w$npU3Qv-%Q0JD zct*q3P3BCWKVNTdS4s>79vp#YhAF_dF*;b{aT?Vck)Jca2x8bQnTPrGJaRgq`5albVP#5;20g0PlCixEpO!~u&Pr(4wR+hq^x3(>L^2n$gnr8YvT zgcM0RuRG*&t=@@n?QO-!Jz}!P9Ug z6bMu2pO2^(qIhyoh!evAwM1+%Hp7Ij2P7n79=rglcZL!J`@^2?c1sL_d2Xl_FIEVL z*$Yg_0&DgN!swp^0-=n|hZlrq - + @@ -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 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)LYWEO@-Q)Csd}W?m6;b>&dUoYuIu%w&ExJt1qrYe z!j)`pm0Ay=8x)4cwz{>pi`FcEv`d>BKZ+>vrrh6n!7SWlGU!%Dsy@wz(`x8{NrRyr zy&*FO*q&0ia|bMUr#-QtAKjaeROLIg_IWfHi^2rH^69rslA{1&x<&>As~?2V;p!gL zxEB2JIhUXqxXsWYQJoR16*2V%55CT2Z`_g!2&Y4uO(_c3^MxvcNs9pe2dRgdYCmog zvCJD^^JKcn?MU{Xj0iqj*L*MdCT3tC0CBvEyhKbxKa9ZQjr5453Cg)^1Ont zKEO?@m6!oV#dBn;b1A_KR_mm&j``dddT|jhV?VSF3=L6RsTZu0xbswAwfI;hU*d!( zqSPW>C(12&`3rodbpE`m_ZR1g#U3j6scVXvhQpatjP!CFy;EYtUI{kN@FhX84U!*% zIYiD31L@op=p7xZ)3|3Mv?YIf2%{;;rltwLwe*6=(1&~B8}rQ3wG}`fO~W8wFY{pR z;C)`qLFGr}n`r$vK$fcY#S1DyqfRf-(gCOz>BD!F3!pC=Vg1bZr$U)~?Al6BQQP=l*3?B9mafl$hFQ|Tf%0JoE++D{tibC7*^)19k4E_4Jhdi>+i#wcF$x_iuLu{_p^XO zW#r3(9!`zY$>j!ev`8UkrO~iF55g(wu&$MAR*Bm_uT;7p>> z_eIo*IZ1t-Rr1 zJ5T;U#b2ps44t$H^M-#{{H<4jKT*qIZ}i`X{+p%kfgrr=o};J{Ly zMBOe|zB^awQq*4szz%uQ0C%Y$^sD@-RdbvdXzvBUoovhImQuPKS;nA$7)YgVg-Wo0 zAlV&mTE;zGJ9==Sy@NvyVDEyNHVK!jFaV~_J(!gjp-Atn9fTG#wZvPBhbVm*7(!7V z(6t9#{@8w2o%nU(TJpsVRxcp!w^)rHosC;313HY+KZePkVT?+K(Lb99nbIzPCb)kr zPSh+_d;0tD&x=zRvfYX2y?EO>A#YPR{BZ!{CO{o6!StdGzO%16iJ0jLtXNxG#$^@6mXJ=(}Jq`L+{0e z*K5*^6PWT+m3Gj&#&I&84)ddyJt!>;HFjN3Y25{<&PC0-3r%(0de0W;2;t_ar;S}>j*BDr*@cIFTkwsccy$WCZJHAsCFNkTd{nEwJ3>SW!wgKEh+mS0; zV5-F2onapdZD5o$(2<#Exr@0OjS{nMD0lUhG(a7L*e9~iOf^u^9uuo|)7g%Sve-;* zgV0^TkE5bFwym*=+8wB++zRD@Hlq`bqn&9;%>y))G>Rvu=q}?QNkumuNqjkYESW4* z5gWIa?K07kRHef)I1)y8cw-NHDyeK-!4pLGi6AG=XpG^AFc?w0AD^?ryP0J;CkgRL zkz-(=R-)X|tZ-^-5VBu~JeFoiJjCj!nsQPNt519R#!B{UQ)J$_cz}7r_LP%NIO8TBn$E#iU6eX?9EN% zepq!+?BTQcqfX#iL!r3Wl=ClHvmvr(W0udPIs2Afjn-dsm8Wv^u&wUlHM6s^rfIll z^ETk$d9fu#Jx6fBy2S6^e4#8zMLa;8akKs9aS|{1EZoFf`%nu_KDOLG=FCLWcJn{@ zv1Lcmi4LzEUKy&kDpqe*-(Aq@WtI|gCJ!@1HZnM139=eaz>Rh<#o#x1rJw~`cv?LKigi&!omt;?EToEQIn!Y}^=31GeaN Date: Thu, 23 Jun 2016 18:23:20 +0300 Subject: [PATCH 07/13] - host can respawn - respawn info texts - camera clamped to the the upper edge of the level - fixed submarinebody being generated from all walls (and not just the ones belonging to that specific sub) --- Subsurface/Content/Items/Engine/engine.xml | 2 +- Subsurface/Source/Camera.cs | 21 +-- .../Characters/AI/IndoorsSteeringManager.cs | 3 +- .../Source/Characters/AI/SteeringPath.cs | 5 + Subsurface/Source/Items/Components/Door.cs | 19 +- Subsurface/Source/Map/Levels/Level.cs | 12 +- .../Source/Map/Levels/Ruins/RuinGenerator.cs | 2 + Subsurface/Source/Map/SubmarineBody.cs | 10 +- Subsurface/Source/Networking/GameClient.cs | 22 ++- Subsurface/Source/Networking/GameServer.cs | 16 +- .../Source/Networking/RespawnManager.cs | 164 +++++++++++++----- Subsurface/Source/Screens/GameScreen.cs | 2 +- 12 files changed, 204 insertions(+), 74 deletions(-) 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 ForceShuttleToPos(Vector2 position, float speed) @@ -171,15 +213,18 @@ namespace Barotrauma.Networking Vector2 displayVel = Vector2.Normalize(position - respawnShuttle.WorldPosition) * speed; respawnShuttle.SubBody.Body.LinearVelocity = ConvertUnits.ToSimUnits(displayVel); yield return CoroutineStatus.Running; + + if (respawnShuttle.SubBody == null) yield return CoroutineStatus.Success; } respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBodies[0]); + yield return CoroutineStatus.Success; } private void ResetShuttlePos() { - respawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f)); + respawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + respawnShuttle.Borders.Height)); respawnShuttle.Velocity = Vector2.Zero; } @@ -187,40 +232,81 @@ namespace Barotrauma.Networking 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.WriteRangedInteger(0, Enum.GetNames(typeof(State)).Length, (int)state); - msg.Write((byte)clients.Count); - for (int i = 0; i < clients.Count; i++) + switch (state) { - 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]); + case State.Transporting: + var clients = GetClientsToRespawn(); - GameMain.GameSession.CrewManager.characters.Add(clients[i].Character); + List characterInfos = clients.Select(c => c.characterInfo).ToList(); + if (server.Character != null && server.Character.IsDead) characterInfos.Add(server.CharacterInfo); - server.WriteCharacterData(msg, clients[i].Character.Name, clients[i].Character); + var waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, respawnShuttle); + + msg.Write((byte)characterInfos.Count); + for (int i = 0; i < characterInfos.Count; i++) + { + var character = Character.Create(characterInfos[i], waypoints[i].WorldPosition, true, false); + + if (i < clients.Count) + { + msg.Write((byte)clients[i].ID); + } + else + { + msg.Write((byte)0); + server.Character = character; + Character.Controlled = character; + } + + character.GiveJobItems(waypoints[i]); + + GameMain.GameSession.CrewManager.characters.Add(character); + + server.WriteCharacterData(msg, character.Name, character); + } + + break; + case State.Waiting: + msg.Write(respawnTimer); + break; } } public void ReadNetworkEvent(NetIncomingMessage inc) { - ResetShuttlePos(); + state = (State)inc.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length); - var client = networkMember as GameClient; - - int clientCount = inc.ReadByte(); - for (int i = 0; i Date: Sun, 26 Jun 2016 14:31:00 +0300 Subject: [PATCH 08/13] - multiple submarines can be "merged" into one file (to be used as escape vessels etc) - WIP docking ports --- Subsurface/Barotrauma.csproj | 5 + Subsurface/Content/Items/Door/dockingport.png | Bin 0 -> 28244 bytes Subsurface/Content/Items/Door/doors.xml | 25 ++ .../Characters/AI/IndoorsSteeringManager.cs | 2 +- .../Source/Characters/Animation/Ragdoll.cs | 15 +- Subsurface/Source/GUI/GUIDropDown.cs | 2 +- .../Source/Items/Components/DockingPort.cs | 367 ++++++++++++++++++ Subsurface/Source/Items/Item.cs | 4 +- Subsurface/Source/Map/Gap.cs | 4 +- Subsurface/Source/Map/Hull.cs | 23 +- Subsurface/Source/Map/MapEntity.cs | 18 +- Subsurface/Source/Map/MapEntityPrefab.cs | 15 +- Subsurface/Source/Map/Structure.cs | 4 +- Subsurface/Source/Map/Submarine.cs | 51 ++- Subsurface/Source/Map/SubmarineBody.cs | 77 +--- Subsurface/Source/Map/SubmarineLink.cs | 171 ++++++++ Subsurface/Source/Map/WayPoint.cs | 4 +- Subsurface/Source/Screens/EditMapScreen.cs | 26 +- Subsurface/Source/Utils/MathUtils.cs | 35 ++ 19 files changed, 740 insertions(+), 108 deletions(-) create mode 100644 Subsurface/Content/Items/Door/dockingport.png create mode 100644 Subsurface/Source/Items/Components/DockingPort.cs create mode 100644 Subsurface/Source/Map/SubmarineLink.cs diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 23966ab7d..75e2e93c9 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -118,6 +118,7 @@ + @@ -143,6 +144,7 @@ + @@ -492,6 +494,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Subsurface/Content/Items/Door/dockingport.png b/Subsurface/Content/Items/Door/dockingport.png new file mode 100644 index 0000000000000000000000000000000000000000..86d928cdae6fa9fa02f91f6cc8c2ed488f0a82eb GIT binary patch literal 28244 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 AivR!s literal 0 HcmV?d00001 diff --git a/Subsurface/Content/Items/Door/doors.xml b/Subsurface/Content/Items/Door/doors.xml index e628549ff..7834d3d90 100644 --- a/Subsurface/Content/Items/Door/doors.xml +++ b/Subsurface/Content/Items/Door/doors.xml @@ -82,4 +82,29 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index d8107f9d5..872c6b697 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -103,7 +103,7 @@ namespace Barotrauma private Vector2 DiffToCurrentNode() { - if (currentPath == null) return Vector2.Zero; + if (currentPath == null || currentPath.Finished) return Vector2.Zero; if (currentPath.Finished) { diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index b84831684..e25b591b2 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -616,20 +616,7 @@ namespace Barotrauma while (ce != null && ce.Contact != null) { ce.Contact.Enabled = false; - //if (ce.Contact.IsTouching && ce.Contact.Enabled && - // ((inToOut && ce.Contact.FixtureA.Body.UserData is Structure) || (!inToOut && ce.Contact.FixtureA.Body.UserData is Submarine))) - //{ - // Vector2 normal; - // FarseerPhysics.Common.FixedArray2 worldPoints; - // ce.Contact.GetWorldManifold(out normal, out worldPoints); - // foreach (Limb limb2 in Limbs) - // { - // limb2.body.FarseerBody.ApplyLinearImpulse(limb2.Mass * normal); - // } - - // return false; - //} ce = ce.Next; } } @@ -639,7 +626,7 @@ namespace Barotrauma limb.body.LinearVelocity += velocityChange; } - character.Stun = 0.1f; + //character.Stun = 0.1f; character.DisableImpactDamageTimer = 0.25f; SetPosition(refLimb.SimPosition + moveAmount); diff --git a/Subsurface/Source/GUI/GUIDropDown.cs b/Subsurface/Source/GUI/GUIDropDown.cs index 01fd79766..a6bd02787 100644 --- a/Subsurface/Source/GUI/GUIDropDown.cs +++ b/Subsurface/Source/GUI/GUIDropDown.cs @@ -34,7 +34,7 @@ namespace Barotrauma if (parent != null) parent.AddChild(this); - button = new GUIButton(Rectangle.Empty, "", Color.White, Alignment.TopLeft, Alignment.TopLeft, null, this); + button = new GUIButton(Rectangle.Empty, text, Color.White, Alignment.TopLeft, Alignment.TopLeft, null, this); button.TextColor = Color.White; button.Color = Color.Black * 0.8f; diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs new file mode 100644 index 000000000..69347b7bc --- /dev/null +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -0,0 +1,367 @@ +using FarseerPhysics; +using FarseerPhysics.Dynamics; +using FarseerPhysics.Dynamics.Joints; +using FarseerPhysics.Factories; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Barotrauma.Items.Components +{ + + class DockingPort : ItemComponent, IDrawableComponent + { + private static List list = new List(); + + private Sprite overlaySprite; + + private Vector2 distanceTolerance; + + private DockingPort dockingTarget; + + private float dockingState; + + private Joint joint; + + private int dockingDir; + + private Hull[] hulls; + + private Body[] bodies; + + private Gap gap; + + [HasDefaultValue("32.0,32.0", false)] + public string DistanceTolerance + { + get { return ToolBox.Vector2ToString(distanceTolerance); } + set { distanceTolerance = ToolBox.ParseToVector2(value); } + } + + [HasDefaultValue(32.0f, false)] + public float DockedDistance + { + get; + set; + } + + [HasDefaultValue(true, false)] + public bool IsHorizontal + { + get; + set; + } + + public override bool IsActive + { + get + { + return base.IsActive; + } + set + { + if (!IsActive && value) + { + if (dockingTarget == null) AttemptDock(); + if (dockingTarget == null) return; + + base.IsActive = value; + } + else if (IsActive && !value) + { + Undock(); + } + + //base.IsActive = value; + } + } + + public DockingPort(Item item, XElement element) + : base(item, element) + { + // isOpen = false; + foreach (XElement subElement in element.Elements()) + { + string texturePath = ToolBox.GetAttributeString(subElement, "texture", ""); + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "sprite": + overlaySprite = new Sprite(subElement, texturePath.Contains("/") ? "" : Path.GetDirectoryName(item.Prefab.ConfigFile)); + break; + } + } + + list.Add(this); + } + + private void AttemptDock() + { + foreach (DockingPort port in list) + { + if (port == this || port.item.Submarine == item.Submarine) continue; + + if (Math.Abs(port.item.WorldPosition.X - item.WorldPosition.X) > distanceTolerance.X) continue; + if (Math.Abs(port.item.WorldPosition.Y - item.WorldPosition.Y) > distanceTolerance.Y) continue; + + Dock(port); + return; + + } + } + + private void Dock(DockingPort target) + { + if (dockingTarget!=null) + { + Undock(); + } + + dockingTarget = target; + dockingTarget.dockingTarget = this; + dockingTarget.IsActive = true; + + dockingDir = Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X); + dockingTarget.dockingDir = -dockingDir; + + CreateJoint(false); + } + + + private void CreateJoint(bool useWeldJoint) + { + Vector2 offset = (IsHorizontal ? + Vector2.UnitX * Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) : + Vector2.UnitY * Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y)); + offset *= DockedDistance * 0.5f; + + Vector2 pos1 = item.WorldPosition + offset; + + Vector2 pos2 = dockingTarget.item.WorldPosition - offset; + + if (useWeldJoint) + { + joint = JointFactory.CreateWeldJoint(GameMain.World, + item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body, + ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true); + + ((WeldJoint)joint).FrequencyHz = 1.0f; + } + else + { + var distanceJoint = JointFactory.CreateDistanceJoint(GameMain.World, + item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body, + ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true); + + distanceJoint.Length = 0.01f; + distanceJoint.Frequency = 1.0f; + distanceJoint.DampingRatio = 0.8f; + + joint = distanceJoint; + } + + + joint.CollideConnected = true; + } + + private void CreateHull() + { + var hullRects = new Rectangle[] { item.WorldRect, dockingTarget.item.WorldRect }; + var subs = new Submarine[] { item.Submarine, dockingTarget.item.Submarine }; + + hulls = new Hull[2]; + bodies = new Body[4]; + if (IsHorizontal) + { + if (hullRects[0].Center.X > hullRects[1].Center.X) + { + hullRects = new Rectangle[] { dockingTarget.item.WorldRect, item.WorldRect }; + subs = new Submarine[] { dockingTarget.item.Submarine,item.Submarine }; + } + + + hullRects[0] = new Rectangle(hullRects[0].Center.X, hullRects[0].Y, ((int)DockedDistance / 2), hullRects[0].Height); + hullRects[1] = new Rectangle(hullRects[1].Center.X - ((int)DockedDistance / 2), hullRects[1].Y, ((int)DockedDistance / 2), hullRects[1].Height); + + + + for (int i = 0; i < 2;i++ ) + { + hullRects[i].Location -= (subs[i].WorldPosition - subs[i].HiddenSubPosition).ToPoint(); + hulls[i] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRects[i], subs[i]); + hulls[i].AddToGrid(subs[i]); + + + for (int j = 0; j < 2; j++) + { + bodies[i + j * 2] = BodyFactory.CreateEdge(GameMain.World, + ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X, hullRects[i].Y - hullRects[i].Height * j)), + ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Right, hullRects[i].Y - hullRects[i].Height * j))); + + //bodies[i + j * 2] = BodyFactory.CreateRectangle(GameMain.World, ConvertUnits.ToSimUnits(hullRects[i].Width), 0.1f, 5.0f); + //bodies[i + j * 2].SetTransform(ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Center.X, hullRects[i].Y - (hullRects[i].Height+5) * j)), 0.0f); + } + } + + gap = new Gap(new Rectangle(hullRects[0].Right-2, hullRects[0].Y, 4, hullRects[0].Height), true, item.Submarine); + gap.linkedTo.Clear(); + gap.linkedTo.Add(hulls[0]); + gap.linkedTo.Add(hulls[1]); + + //var hullRect1 = new Rectangle(hullRects.Min(h => h.Center.X), hullRect.Y, ((int)DockedDistance / 2), hullRects[0].Height); + //var hullRect2 = new Rectangle(hullRects.Max(h => h.Center.X), hullRect.Y, ((int)DockedDistance / 2), hullRects[0].Height); + + //var sub1 = hullRect.Center.X < targetRect.Center.X ? item.Submarine : dockingTarget.item.Submarine; + //var sub2 = hullRect.Center.X > targetRect.Center.X ? item.Submarine : dockingTarget.item.Submarine; + + // hullRect1.Location -= (sub1.WorldPosition - sub1.HiddenSubPosition).ToPoint(); + //hulls[0] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRect1, sub1); + //hulls[0].AddToGrid(sub1); + + //hullRect2.Location -= (sub2.WorldPosition - sub2.HiddenSubPosition).ToPoint(); + //hulls[1] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRect2, sub2); + //hulls[1].AddToGrid(sub2); + + + } + else + { + //hullRect = new Rectangle(hullRect.X, + // Math.Max(hullRect.Y - hullRect.Height / 2, targetRect.Y - targetRect.Height / 2), hullRect.Width, (int)DockedDistance); + } + + foreach (Body body in bodies) + { + body.BodyType = BodyType.Static; + body.Friction = 0.5f; + + body.CollisionCategories = Physics.CollisionWall; + } + + + } + + private void Undock() + { + if (dockingTarget == null) return; + + dockingTarget.dockingTarget = null; + dockingTarget.IsActive = false; + + dockingTarget = null; + + GameMain.World.RemoveJoint(joint); + joint = null; + + hulls[0].Remove(); + hulls[1].Remove(); + + gap.Remove(); + gap = null; + + foreach (Body body in bodies) + { + GameMain.World.RemoveBody(body); + } + bodies = null; + + + + //foreach (Gap g in hulls[0].ConnectedGaps) + //{ + // g.Remove(); + //} + + //foreach (Gap g in hulls[1].ConnectedGaps) + //{ + // g.Remove(); + //} + + + hulls = null; + } + + public override void Update(float deltaTime, Camera cam) + { + if (dockingTarget==null) + { + dockingState = MathHelper.Lerp(dockingState, 0.0f, deltaTime * 10.0f); + if (dockingState < 0.01f) base.IsActive = false; + } + else + { + if (joint is DistanceJoint && Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f) + { + GameMain.World.RemoveJoint(joint); + + CreateJoint(true); + CreateHull(); + } + + dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f); + } + } + + public void Draw(SpriteBatch spriteBatch, bool editing) + { + if (dockingState == 0.0f) return; + + Vector2 drawPos = item.DrawPosition; + drawPos.Y = -drawPos.Y; + + var rect = overlaySprite.SourceRect; + drawPos.Y -= rect.Height / 2; + + if (IsHorizontal) + { + if (dockingDir == 1) + { + spriteBatch.Draw(overlaySprite.Texture, + drawPos, + new Rectangle( + rect.Center.X + (int)(rect.Width / 2 * (1.0f - dockingState)), rect.Y, + (int)(rect.Width / 2 * dockingState), rect.Height), Color.White); + + } + else + { + spriteBatch.Draw(overlaySprite.Texture, + drawPos - Vector2.UnitX * (rect.Width / 2 * dockingState), + new Rectangle( + rect.X, rect.Y, + (int)(rect.Width / 2 * dockingState), rect.Height), Color.Red); + } + } + else + { + if (dockingDir == 1) + { + spriteBatch.Draw(overlaySprite.Texture, + drawPos, + new Rectangle( + rect.X, rect.Y + rect.Height/2 + (int)(rect.Height / 2 * (1.0f - dockingState)), + rect.Width, (int)(rect.Height / 2 * dockingState)), Color.White); + + } + else + { + spriteBatch.Draw(overlaySprite.Texture, + drawPos - Vector2.UnitY * (rect.Height / 2 * dockingState), + new Rectangle( + rect.X, rect.Y, + rect.Width, (int)(rect.Height / 2 * dockingState)), Color.Red); + } + } + } + + protected override void RemoveComponentSpecific() + { + list.Remove(this); + } + } +} diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 2243aef2e..836cbec2f 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -1432,7 +1432,7 @@ namespace Barotrauma return true; } - public override XElement Save(XDocument doc) + public override XElement Save(XElement parentElement) { XElement element = new XElement("Item"); @@ -1475,7 +1475,7 @@ namespace Barotrauma ic.Save(element); } - doc.Root.Add(element); + parentElement.Add(element); return element; } diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index 31452a2ca..621b15049 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -639,7 +639,7 @@ namespace Barotrauma FindHulls(); } - public override XElement Save(XDocument doc) + public override XElement Save(XElement parentElement) { XElement element = new XElement("Gap"); @@ -663,7 +663,7 @@ namespace Barotrauma // } //} - doc.Root.Add(element); + parentElement.Add(element); return element; } diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index d124b5305..f0f2c8793 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -260,6 +260,21 @@ namespace Barotrauma } } + public void AddToGrid(Submarine submarine) + { + foreach (EntityGrid grid in entityGrids) + { + if (grid.Submarine != submarine) continue; + + rect.Location -= submarine.HiddenSubPosition.ToPoint(); + + grid.InsertEntity(this); + + rect.Location += submarine.HiddenSubPosition.ToPoint(); + return; + } + } + public override bool IsMouseOn(Vector2 position) { if (!GameMain.DebugDraw && !ShowHulls) return false; @@ -295,6 +310,7 @@ namespace Barotrauma public override void Remove() { base.Remove(); + hullList.Remove(this); if (Submarine == null || !Submarine.Loading) { @@ -324,7 +340,6 @@ namespace Barotrauma } - hullList.Remove(this); } public void AddFireSource(FireSource fireSource, bool createNetworkEvent = true) @@ -712,7 +727,7 @@ namespace Barotrauma // return gaps; //} - public override XElement Save(XDocument doc) + public override XElement Save(XElement parentElement) { XElement element = new XElement("Hull"); @@ -725,8 +740,8 @@ namespace Barotrauma rect.Width + "," + rect.Height), new XAttribute("water", volume) ); - - doc.Root.Add(element); + + parentElement.Add(element); return element; } diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index ed9051a21..958655ce0 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -596,7 +596,7 @@ namespace Barotrauma } - public virtual XElement Save(XDocument doc) + public virtual XElement Save(XElement parentElement) { DebugConsole.ThrowError("Saving entity " + GetType() + " failed."); return null; @@ -625,15 +625,29 @@ namespace Barotrauma if (linked != null) e.linkedTo.Add(linked); } } + + List linkedSubs = new List(); for (int i = 0; i false + + Submarine sub = new Submarine(ToolBox.GetAttributeString(element, "name", "")); + sub.Load(unloadPrevious, element); + + return sub; } public static Submarine Load(string fileName, bool unloadPrevious) @@ -851,7 +880,7 @@ namespace Barotrauma string path = string.IsNullOrWhiteSpace(folder) ? fileName : System.IO.Path.Combine(SavePath, fileName); Submarine sub = new Submarine(path); - sub.Load(false); + sub.Load(unloadPrevious); //Entity.dictionary.Add(int.MaxValue, sub); diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index 1cc21f166..2802e4fd0 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -125,30 +125,16 @@ namespace Barotrauma Body, this); } - //foreach (Hull hull in Hull.hullList) - //{ - // Rectangle rect = hull.Rect; - // foreach (Structure wall in Structure.WallList) - // { - // if (!Submarine.RectsOverlap(wall.Rect, hull.Rect)) continue; - - // Rectangle wallRect = wall.IsHorizontal ? - // new Rectangle(hull.Rect.X, wall.Rect.Y, hull.Rect.Width, wall.Rect.Height) : - // new Rectangle(wall.Rect.X, hull.Rect.Y, wall.Rect.Width, hull.Rect.Height); - - // rect = Rectangle.Union( - // new Rectangle(wallRect.X, wallRect.Y - wallRect.Height, wallRect.Width, wallRect.Height), - // new Rectangle(rect.X, rect.Y - rect.Height, rect.Width, rect.Height)); - // rect.Y = rect.Y + rect.Height; - // } - - // FixtureFactory.AttachRectangle( - // ConvertUnits.ToSimUnits(rect.Width), - // ConvertUnits.ToSimUnits(rect.Height), - // 5.0f, - // ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)), - // body, this); - //} + foreach (Hull hull in Hull.hullList) + { + Rectangle rect = hull.Rect; + FixtureFactory.AttachRectangle( + ConvertUnits.ToSimUnits(rect.Width), + ConvertUnits.ToSimUnits(rect.Height), + 5.0f, + ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)), + Body, this); + } } @@ -183,50 +169,17 @@ namespace Barotrauma List points = new List(); - Vector2 leftMost = Vector2.Zero; - foreach (Structure wall in Structure.WallList) { if (wall.Submarine != submarine) continue; - for (int x = -1; x <= 1; x += 2) - { - for (int y = -1; y <= 1; y += 2) - { - Vector2 corner = new Vector2(wall.Rect.X + wall.Rect.Width / 2.0f, wall.Rect.Y - wall.Rect.Height / 2.0f); - corner.X += x * wall.Rect.Width / 2.0f; - corner.Y += y * wall.Rect.Height / 2.0f; - - if (points.Contains(corner)) continue; - - points.Add(corner); - if (leftMost == Vector2.Zero || corner.X < leftMost.X) leftMost = corner; - } - } + points.Add(new Vector2(wall.Rect.X, wall.Rect.Y)); + points.Add(new Vector2(wall.Rect.X + wall.Rect.Width, wall.Rect.Y)); + points.Add(new Vector2(wall.Rect.X, wall.Rect.Y - wall.Rect.Height)); + points.Add(new Vector2(wall.Rect.X + wall.Rect.Width, wall.Rect.Y - wall.Rect.Height)); } - List hullPoints = new List(); - - Vector2 currPoint = leftMost; - Vector2 endPoint; - do - { - hullPoints.Add(currPoint); - endPoint = points[0]; - - for (int i = 1; i < points.Count; i++) - { - if ((currPoint == endPoint) - || (MathUtils.VectorOrientation(currPoint, endPoint, points[i]) == -1)) - { - endPoint = points[i]; - } - } - - currPoint = endPoint; - - } - while (endPoint != hullPoints[0]); + List hullPoints = MathUtils.GiftWrap(points); return hullPoints; } diff --git a/Subsurface/Source/Map/SubmarineLink.cs b/Subsurface/Source/Map/SubmarineLink.cs new file mode 100644 index 000000000..68f671656 --- /dev/null +++ b/Subsurface/Source/Map/SubmarineLink.cs @@ -0,0 +1,171 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Barotrauma +{ + + class LinkedSubmarinePrefab : MapEntityPrefab + { + public readonly Submarine mainSub; + + public LinkedSubmarinePrefab(Submarine submarine) + { + this.mainSub = submarine; + } + + protected override void CreateInstance(Rectangle rect) + { + System.Diagnostics.Debug.Assert(Submarine.MainSub != null); + + LinkedSubmarine.Create(Submarine.MainSub, mainSub.FilePath, rect.Location.ToVector2()); + } + } + + class LinkedSubmarine : MapEntity + { + private List wallVertices; + + private string filePath; + + private XElement saveElement; + + public LinkedSubmarine(Submarine submarine) + : base(null, submarine) + { + InsertToList(); + } + + public static LinkedSubmarine Create(Submarine mainSub, string filePath, Vector2 position) + { + LinkedSubmarine sl = new LinkedSubmarine(mainSub); + sl.filePath = filePath; + + XDocument doc = Submarine.OpenFile(filePath); + if (doc == null || doc.Root == null) return null; + + sl.GenerateWallVertices(doc.Root); + + //for (int i = 0; i < sl.wallVertices.Count; i++) + //{ + // sl.wallVertices[i] = sl.wallVertices[i] += position; + //} + + sl.Rect = new Rectangle( + (int)sl.wallVertices.Min(v => v.X + position.X), + (int)sl.wallVertices.Max(v => v.Y + position.Y), + (int)sl.wallVertices.Max(v => v.X + position.X), + (int)sl.wallVertices.Min(v => v.Y + position.Y)); + + sl.rect = new Rectangle(sl.rect.X, sl.rect.Y, sl.rect.Width - sl.rect.X, sl.rect.Y - sl.rect.Height); + + return sl; + } + + public override bool IsMouseOn(Vector2 position) + { + return Vector2.Distance(position, WorldPosition) < 50.0f; + } + + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) + { + if (!editing || wallVertices == null) return; + + Color color = (isHighlighted) ? Color.Orange : Color.Green; + if (isSelected) color = Color.Red; + + Vector2 pos = new Vector2(rect.X + rect.Width/2, rect.Y - rect.Height/2); + + for (int i = 0; i < wallVertices.Count; i++) + { + Vector2 startPos = wallVertices[i] + pos; + startPos.Y = -startPos.Y; + + Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos; + endPos.Y = -endPos.Y; + + GUI.DrawLine(spriteBatch, + startPos, + endPos, + color, 0.0f, 5); + } + + pos.Y = -pos.Y; + GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color, 0.0f, 5); + GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color, 0.0f, 5); + + } + + private void GenerateWallVertices(XElement rootElement) + { + List points = new List(); + + var wallPrefabs = + MapEntityPrefab.list.FindAll(mp => (mp is StructurePrefab) && ((StructurePrefab)mp).HasBody); + + foreach (XElement element in rootElement.Elements()) + { + if (element.Name != "Structure") continue; + + string name = ToolBox.GetAttributeString(element, "name", ""); + if (!wallPrefabs.Any(wp => wp.Name == name)) continue; + + var rect = ToolBox.GetAttributeVector4(element, "rect", Vector4.Zero); + + points.Add(new Vector2(rect.X, rect.Y)); + points.Add(new Vector2(rect.X + rect.Z, rect.Y)); + points.Add(new Vector2(rect.X, rect.Y - rect.W)); + points.Add(new Vector2(rect.X + rect.Z, rect.Y - rect.W)); + } + + wallVertices = MathUtils.GiftWrap(points); + } + + public override XElement Save(XElement parentElement) + { + var doc = Submarine.OpenFile(filePath); + + doc.Root.Name = "LinkedSubmarine"; + + doc.Root.Add( + new XAttribute("filepath", filePath), + new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); + + parentElement.Add(doc.Root); + + return doc.Root; + } + + public static void Load(XElement element, Submarine submarine) + { + Vector2 pos = ToolBox.GetAttributeVector2(element, "pos", Vector2.Zero); + + if (Screen.Selected == GameMain.EditMapScreen) + { + string filePath = ToolBox.GetAttributeString(element, "filepath", ""); + + Create(submarine, filePath, pos); + + return; + } + + var ls = new LinkedSubmarine(submarine); + ls.saveElement = element; + + ls.rect.Location = pos.ToPoint(); + } + + public override void OnMapLoaded() + { + if (saveElement == null) return; + var sub = Submarine.Load(saveElement, false); + sub.SetPosition(WorldPosition - Submarine.WorldPosition); + sub.Submarine = Submarine; + } + } +} diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index a5f9a49c4..1a0f77b70 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -718,7 +718,7 @@ namespace Barotrauma } } - public override XElement Save(XDocument doc) + public override XElement Save(XElement parentElement) { if (MoveWithLevel) return null; XElement element = new XElement("WayPoint"); @@ -739,7 +739,7 @@ namespace Barotrauma if (ConnectedGap != null) element.Add(new XAttribute("gap", ConnectedGap.ID)); if (Ladders != null) element.Add(new XAttribute("ladders", Ladders.Item.ID)); - doc.Root.Add(element); + parentElement.Add(element); if (linkedTo != null) { diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index fa3599308..3d84d432f 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -94,13 +94,23 @@ namespace Barotrauma button = new GUIButton(new Rectangle(310,0,70,20), "Save", GUI.Style, topPanel); button.OnClicked = SaveSub; - new GUITextBlock(new Rectangle(400, 0, 100, 20), "Description: ", GUI.Style, topPanel); + new GUITextBlock(new Rectangle(390, 0, 100, 20), "Description: ", GUI.Style, topPanel); - descriptionBox = new GUITextBox(new Rectangle(500, 0, 200, 20), null, null, Alignment.TopLeft, + descriptionBox = new GUITextBox(new Rectangle(490, 0, 200, 20), null, null, Alignment.TopLeft, Alignment.TopLeft, GUI.Style, topPanel); descriptionBox.Wrap = true; descriptionBox.OnSelected += ExpandDescriptionBox; descriptionBox.OnTextChanged = ChangeSubDescription; + + + //new GUITextBlock(new Rectangle(390, 0, 100, 20), "Link ", GUI.Style, topPanel); + + var linkedSubBox = new GUIDropDown(new Rectangle(750,0,200,20), "Add submarine", GUI.Style, topPanel); + foreach (Submarine sub in Submarine.SavedSubmarines) + { + linkedSubBox.AddItem(sub.Name, sub); + } + linkedSubBox.OnSelected += SelectLinkedSub; leftPanel = new GUIFrame(new Rectangle(0, 30, 150, GameMain.GraphicsHeight-30), GUI.Style); leftPanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); @@ -524,6 +534,18 @@ namespace Barotrauma return frame; } + private bool SelectLinkedSub(GUIComponent selected) + { + var submarine = selected.UserData as Submarine; + if (submarine == null) return false; + + var prefab = new LinkedSubmarinePrefab(submarine); + + MapEntityPrefab.SelectPrefab(prefab); + + return true; + } + private bool SelectWire(GUIComponent component, object userData) { if (dummyCharacter == null) return false; diff --git a/Subsurface/Source/Utils/MathUtils.cs b/Subsurface/Source/Utils/MathUtils.cs index 37fc9339f..cb0b98697 100644 --- a/Subsurface/Source/Utils/MathUtils.cs +++ b/Subsurface/Source/Utils/MathUtils.cs @@ -288,6 +288,41 @@ namespace Barotrauma return triangles; } + public static List GiftWrap(List points) + { + Vector2 leftMost = points[0]; + foreach (Vector2 point in points) + { + if (point.X < leftMost.X) leftMost = point; + } + + List wrappedPoints = new List(); + + Vector2 currPoint = leftMost; + Vector2 endPoint; + do + { + wrappedPoints.Add(currPoint); + endPoint = points[0]; + + for (int i = 1; i < points.Count; i++) + { + if (points[i] == currPoint) continue; + if (currPoint == endPoint || + MathUtils.VectorOrientation(currPoint, endPoint, points[i]) == -1) + { + endPoint = points[i]; + } + } + + currPoint = endPoint; + + } + while (endPoint != leftMost); + + return wrappedPoints; + } + public static List GenerateJaggedLine(Vector2 start, Vector2 end, int generations, float offsetAmount) { List segments = new List(); From 38c525100544b707f0d3f990ee129c70f0b4307e Mon Sep 17 00:00:00 2001 From: Regalis Date: Mon, 27 Jun 2016 17:48:20 +0300 Subject: [PATCH 09/13] Vertical docking port, docking sounds, water flows properly between horizontally docked hulls, falseoutput of signal check components can be changed, lighting and FOW works between hulls (todo: some logic for determining when to update light.HullsInRange when two subs are moving relative to each other) --- Subsurface/Barotrauma.csproj | 9 + Subsurface/Content/Items/Door/dockingport.png | Bin 28244 -> 32289 bytes .../Content/Items/Door/dockingport1.ogg | Bin 0 -> 39057 bytes .../Content/Items/Door/dockingport2.ogg | Bin 0 -> 23118 bytes .../Content/Items/Door/dockingport2.png | Bin 0 -> 12926 bytes Subsurface/Content/Items/Door/doors.xml | 35 ++- Subsurface/Content/Items/Reactor/reactor.xml | 9 +- .../Animation/HumanoidAnimController.cs | 11 +- .../Source/Items/Components/DockingPort.cs | 217 +++++++++++------- .../Components/Signal/SignalCheckComponent.cs | 13 +- Subsurface/Source/Items/Item.cs | 3 +- Subsurface/Source/Map/Gap.cs | 44 ++-- Subsurface/Source/Map/Hull.cs | 26 ++- Subsurface/Source/Map/Lights/ConvexHull.cs | 13 +- Subsurface/Source/Map/Lights/LightManager.cs | 1 + Subsurface/Source/Map/Lights/LightSource.cs | 18 +- Subsurface/Source/Map/Structure.cs | 8 + Subsurface/Submarines/Shuttle Mark I.sub | Bin 2333 -> 3220 bytes Subsurface/Submarines/Vellamo.sub | Bin 15524 -> 15970 bytes 19 files changed, 291 insertions(+), 116 deletions(-) create mode 100644 Subsurface/Content/Items/Door/dockingport1.ogg create mode 100644 Subsurface/Content/Items/Door/dockingport2.ogg create mode 100644 Subsurface/Content/Items/Door/dockingport2.png diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 75e2e93c9..09cabeebc 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -497,6 +497,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -1092,6 +1095,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Subsurface/Content/Items/Door/dockingport.png b/Subsurface/Content/Items/Door/dockingport.png index 86d928cdae6fa9fa02f91f6cc8c2ed488f0a82eb..6538ddf087bde3b5abd4ed29db092767c3d2601c 100644 GIT binary patch literal 32289 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 =GW+h&Ox7INpQ zTRAAxorqos)Tqb84x4FXU0pA&=mZ2DRb~9qz9&BP7V=c#6k%x9U~9hEe%?J_1!}qR z)?RCcsP4#Hx#J=gL^Ni=8)vb@&okn{qyEOO*gYa~Jl*(G%cIQv`S05lpT{z~>HWEz zw->>*GV3sEGN>;%^YsWah6-qE^9;_YPX7wpo*m@!?t0duPOt{4WM@$yU+3^A(t6mm z+S#f;3uK2*)-3#43}0+Q*9g@84||psA!+*v+P0AU3_7g^NNlV=Zo6I{rv_iBfk-MYLw=DWwdpDf+8Sl z=zcrt)Y0N(n&!j!wBK*F(u=DcJ4Fjya@Y~IwRfJ?NUVGgFMLy%l>g~yUcLZ5z<({D zKUhM?pJ2EP0QoO_^qN=#tE`K|ok=AV77Vdly>CG{WxNqVv`{ zaykp0N#O|6#kozo7GXr*GmykK_95GxSBU&@YdGwA)X_3!LW76Npfq4=kcvQa7 z#`%&^&OejZJ$|d~g6ezA9T%^?T5tF70@Fwk#-!-fQ!>&z@TdI$isHG-Tbg9UG zjS9b{hB7=I&LtWyZ>xdvvY8ubBA43@4uc&Wd_ao`+la!jnRgq`t4ibVAHJDBsztl|5lo&?>kCB&HHa_)>C~%7B|sA7nV2W3;4ZWL(!F#8RPR>`Qq*Vhg7S`3v;K^yTlFkrfP+2cqG&ev$kV z%8`Lf{jAn`r;`F2J2A>$*;hI}3P9CpFnHG#x`dyd#Z{qnO470X6iR`dQwCc_cRoRk zjvupx{QfwPmdJyJ2mD z%>Xx>GsWk$0&e9NozDsLhzDk|3Ujqan-JWEjo1b#)Mtv+?Qfj`U$6=Eq%JShbbXDc zyYW}%)=^E8*Yn1YpmnU|_hA~*;A}M;U|Wd!4`AccyKo|0^)V2%887noCHB+4($=ld zPLDg)&Vg2Vr4szoF^`wAhld9jE3Q3Hk1p52{=RkZE6VHr)#oF}_F_$};q3A?}6Bj3bNr8Xd%X|izvsCl9y8|5T8Qe=iNfqDxkE8!wdTkr^wxM6gSsVja z+x9Lm{d){;A6HO9q1k5Dvhni|ZZ7(LOpJ7Ob#)(qI)GDfY5HUAQ<<=8bhi80y$&O8 z!#`@_HbXP&_;E_tV>v7mBr^B8@P>GZa1;1z8?kH8{1H1#PBly`4;@os<-ZSTAiCY! z8A@SCsUE_CEl7RXZzNKr9 zNHi;a3-PF~?V{1Uevbf;iR0yZB))B?oVH(=zf*IMNsr2Y9UbN1!mpiXyxlore8#j` z2ro+LO0XzgA232U52_g^g8q@x_HH&wln%yFt_gN}E5jTkzD)a21%X*!tY>Fc(3gma z2>a>aB6!mIXU=2tfD4d)RVVC`y%wm*>b&V5eD;huP3D8}&@-|Ef`_rA8n7c$uh;&9 zr-Ipw=vDMcR^H>K%$dgCHb*qotKHx&+;!6l%_0>t2)*Q(1Far8BD(|{=QKA&Z^*pY zJ`fQR&E+$4I~B z-9-l*b?Df=uU^I+q}0+HE$jdA`!9(`5BN}VB%82`n*@YGK=644#Z%YY;p@rA>E0H!RUbBJh{0M3-hvr; zt%FHPO&>R~7a|xLJdODhrgk~3a~ifzOZ#eE#5Tk6CexP*8&)r!h4^u)S_*m^=?Uci}q~@HBp%pa^-IW!wKgYp}&sDmriQ z$`^8D8}cGH-G1S8HiHmqJDvCXuNehL4fNdX)|S`IQfgOx7!&qu6aCyUq2=;S3&3i; z+_>Tt%fW$(;APxBjQvD(@ld?8Y060c_4p<3yrnklui*79Y5EQMSw17T^$ufT{-D{q zG0?pIRyX;~lwOnAygWbKAF!9iw(-IN0OwOs&F$>VjbxZ*$8t2Dbsma*e|@?ot=H~1 z0LLm7EE=>6>^DQ^+BHGFC_fb8o4XAG0N2AhI7_Ivo%{iNa_?w)o=x;GF}K4=YtQOSyE&-24OA4`!C3Vts57$suO zD$ZFxnhBN4Jvr}REUKL8thaFdxAr3+xy><)s9Zm5u-jl#fs*kO;Osd;Nr28CJh>%M z83`Rb7>>SFI@a8M9Z20yTBs=$a1JQt*?N7s?da*ryJ3Rex&1$@jpqU;S{o zry11~%!#UrXE`BszF-!q`9E7)^IJR1nm!9Vb3nj`m_@#s+m<(RrOd1@eF6)VCXu$IM|J=2tKzg zTjTcK{3o^5u2ny!){zfzy32UJHi!rt`=g}8;xkIEk3n+Uw=WY%iHVNVBnj(b95S9u zwCQE}iUJ$G4-GHq#k^=^(k6<%1t&eZ$uQ9PQN(dUrNZo9zqNHVLlHNDj~ z0&eTNpDw(b>{V3`tECmyah-MLjW*yE^JMZd)Nea{E|?E5X5V zeFE*m{CcVo?ayEAArFr)3f1X=vMvd*INnvtIPu1cSF($q^J^pp8^ANj4OG)+;xIEw7gikUIRjl(fss=q*~^D z=)yBJ3MxrE>jt&cPpHB5Qq1JSzLYzXC5S-ArK3*R+tu8CCDgfdQu`&Jt`ECE4iC|~ zP7~kC*ywWnf*$Db^|FqyuU*XVX|1e4JRM|Js=$C5SJQIRl<6)9%($U5d_Rz>2kYb* z)!Lb`T6&&;JE$kw5(V>VzP?tJirw$-ypmSD4nlZeqb}BhB$L0$`2L_oKb~$Wp8l|^ zCQJ?~YFuLD#E&$iQlD9W4Bm7&KoiZkZ{cr3NqPq0$`o+if&2GZv3dgOyGtjm27pw5 zlAX+;E<+j*klbbTu!yUV_*5nFU9Ee*P>oJ9H=LcKS;NR8kgBruq4Ccz-)ZT>L{TVa zWL0UFQewS|*gdc^}dO8 zrtp0}LP{bR`Mr4TK`!dsryBBrCwhNp8T@c>`*dphWcc0x0z4V4+DkD?OfD??%clN5 z>T}Rg{fll$X2|R3SG;=DuNdnL3J7yN1Svn>B>T32h`oS4$_vG7{p+1ced^2j*1dHg z*?Bj=!HLiAu7KXsUB4O+Yn{Oin;|rY%kl#_waqwTP3#J zLP@vTSqOy6Aaq-8Dr^NSI%OfCil;Vns{NVpMBQRhVnufU=f9W*nq1CYBf77IW4LyhvNT^+?*M&8$RrH;eO% zkl*_azTo&~zSCPN^Xbp$7v$5+1}76q%r8&`5UKe9>)uM{WR1`o3NE0ktjvYXOLI0R zZydH8^-g?RlTee&nu6==f+tgp>`7 zDC~}Nyxn4T;x;Dps;cZ)Gx)C%MbJGp@&XX)({pdT&)^x4%7*QRtN$@~nn!hhqrw*9 zkdn^^Qfr6V+kORo-m8-kyL zfF0ph!(VnRDxDFZk<@z;S!REKH)ctA8va?>PhOiR@M*V^`zr_`8GnpXosZzS81JFZ zvUltJZWgWFcI069uv27zpYNnCfHV6Pmc|o_iFNkM*s^9k%j?+l+->VwL$YfOjNPu{F`9Dk)p;SwRn9= z`t>zs>a|$T_Ptsy^&M#3CRxyMlbqTYEihpvVPCm%g&rKjc6d1E9a?CT9{>+k)gn(bWE!?N`2Np!}4YYnTup8W3ag$uql zeO|+GAD|Q=a%TN(();WBc$qt1jLtS{mIuvvA>pt8C&?0OBNQs>9;dhY6AcBJC6qZc zMH@w|j(;~|R3mXDV8TF1!bzz+vrgcb>pbo0^CQ5Qub*?!pr6uL^Y3uIE~O240imT- zuuaHSs>Pr!^%a0;5<9AFe#V6J%-C69xb@j9^Z6n#BAkUVJy3+4mzOt_{(#$NZiW_A zv7B&G$}ym!X*M?5WPEW?e?0p$dcNwkOpYw%XXfK6hNQ}xfQn2D zFh*?`-qXs-qg#@KiPexF%o+L-n%c}bndqwYYi-+Z*Lxl$+Lk0?0+%5)Yrza^Qw3nE zN+sHzDiX^mSFXLGhAq{2ewx9VCTD(8L21&7i+;Ftk2hNgrbAFZB8OMAfX_>*eRDyN zwA(`;4F{1mL=i|0FJJSLMAtZ&Ypu0kXZb0xMh4jAK*H5Ak_fBpYBh+gGa@DKVC;`B z((eDuEML;jj{wm*>B`HjH|4_okl*V&=F+}jo-bnQ6ELYN7Q&|SYfxN1o2=Lshf-}p z$>sn>0p8+MMQB#}c9A;_SdkOmS=soH_r=Kr?c9a1m?7W)(^qo{QmyNfg)&w@O)S}= zPHqaNbh>eOV9cqifTnInS_BfvP-TgybzYd?fn&+lU9WL%y}%hu9l#=Bt-;W;vE$po zUF*(UQZvJm+(H-{*J^i0{4nZr{_g|#8Wiq(d?}C^S(Qy*$a2?{4;@T6l(iWBr9OFX zSCR9DIfrt7|8}Eqv5Y3B@4Bq~HYGk6?wD*}S19njq{a$bfi4=2+P(30L*g;i)Q zNc|%cgJ+`FwGqM(UR%J~D*X1rHo!U3TrOL^N;oAvhKwV->7x_7%FVU5{Zl2pfU*Dv zRL|PmSXJdq-SHUcU24HtCzYB&JcmQkN21ik&d}-0Zg{eB@mL+qm%KX`)LnU1Z;X zUvE`k5ggXDMez59dprk~$IqNtg8|&Od%12U|E@_sA-O4axPXO4glIYU9y`Yw8*sLO zFgk-HqM#pmzK|fLiO3fRQqiLMCWk1xTVfLqUk+4TO12PZu1Jt1)oUk6_u^JblPqbC z&WfUAu#sU&s&p0@OTVH8w;?en#}11BKtPXZjO#wLKBT)kd3+8;nS49g`&3DQKUPFe zH7TW1TWQ|C6g8liLO;?`8tVBbET!cn%|+K8A9Q`7>bFS-xVK_Kqkoj)%}gs3>DA)+ zU0fnXOqT#9h*`oNW2k?;lPLpdjk@8Ugr-(Xoa4%WgU~yNt!#e&A2;$-?$i%EMWtYi zMsn>^I7k~%$ie(0lp`utIR*ER9pYr?{m$#M&fIbk;+`5kbQm?}?v zyJI4PXG$BtNzgAAGP9RpTCWp$nIOlqibN5#!>GJ=IVP7>xt60U`cQFFZ=2Ie{g9WO zR`3)zf7`_>;Mdf)TZ5r0PR)o4M@{UEHLlIiM*}B@Xjq@K^()9w-`6{=7h zFF!MUD;2T;rpEy8Ol7$~*&NC*8#2=0Xs2PfLVzKB1zF3tFhD$WtS|*0BisY_PCf%z zgmKIy*nT$(x1x3?Hs93g?qo%g(0Q_%Xxe@aDPJUDY$bwAG~gxt^YZ{bH6;lsJEeq_ zvQ*mQK&U074`M<6Q8o5mK7MCaiAOTtl2)_XK8i)}gX8PAVma6RctMNh@|MPNT&Hn? zm&LM|q+M=6&Det1M0v;)y>zNyg&(I~ZrQh`-V zc`a3@8KvQFoL+K7tG1mLg?M2_%^x%U2;Lf!c%3iBUI+|1AgQU7+W>I&8^Hea`!aR% zG~-$#UPI=d-ZzZWmfhf88e*Y3prwtctj*ehW9`u;28G^K@N4$0Y^-B-+_+8?wCw+Z z+4cBW?W$fFfI9k#+SL?GKp8`*B(jmPn!BvFvMOg|lDroGEiItZ>f{q}c(BhQb zRFqUlw76xgkA3+ZdMmONJ6h?HQI4Zp$*k-9ilOb>xdR+U;wwmIp@oII<+u?2JnLEs z5Cu%^e)>AalBqnmXrVl%lmlF~182~+r=?j2|H`FMBrd}0$9X!KSDh^@ts@#L*?a{g zH#J;Fk$q7YJe$xS9xx!B$Uwotw#&&V`Jlpl^N6*pG`~=jOORg8A9NSHvB>OB9wqSs zrdQR;#*+mmtgRk3-?r*5)30x+D>@TgU41u!-=~c&CT%fQ0gY@>BGQU`jd+V3#xOX)#!KB6TeX~cNNQeR|d?ufPhevaNCy678#mUwyzzjX) zb=H6Q;xMjlPMBX5{=N3zDB^?4yUsAHgc<2QX{9gD`}&_q^SXT#wDX1ycEA?h1_h8Z z=g1bvRugp|*5m6qC|CPe`qjMVy*SLj!6yIC|GLx6_rJt-FvhK*)X16%52#U zEzC(_q&rG@@kCR!ulgh**xBs*ju%whgMGzva!}F0Q3tQlaBb3SVsE!EOXq&E)g2Csz*@^m&dk6D--#8cuAddtCH(F zdFy`n^_p_;*xk#;SVD>U?t34XB=&$jZPK%wR<3#=IS@Him-YcJfpLHeJ&I8m5-N>} zZY^#&h--O>I8njCaRwiVy0k!G%KJ6DHKVMKO2&I5W0i;Ba&{aSPdM-iZPSM(2Wc&a z-pHuOe8sNHCJN_6_t_ZZ&s$NzK~3n;c7QuCcRH19$_+Zwc`;`cMjv4uCep{^wKzZHL#X47g`hy63Vdt8mob;BP+S8 z7md5J?y}-?bJEU}p`UXm)ev&u)$4I#J)gZ;m)(LNI2+v3CYeheYxq%3mXU4K$koGR z3@79&`)bH2q1r+1;S#|P-lnQdHf2;ct(8FV=vf?<+?xBNJ=htYjW6@Ul-jn!h?q1w zl!H^<*Q0r-e{kr2FFIl{ta>dGx_x9b;?rYK--l$SfhrDLOkBS%!5tg8?+;#{b@uj* zuw9nB2^wL?yrU|b(qUQ6&bpLp*m{k4ed5a?Jgvq7Ad@T?IV*#TzGg}moCzB!BB-n( zLq0|);{VkOL?WP5$+9Rq6PfVtFGis+z5j0pX&Gh4y*}*NRSUgAy#$q_+Ci!!dGs(EVFOe|8ZZ6sFbl1c(;6~#L{-m7tza65b1 z7k{Bjm9?0|G+>sLzj|Ir$U1#)t0zanMPSzb1*Wl*!XEgZmfG+<%A0}buJRY??=c0e z=GWsTtH~T*F`wlX_Pa`M(?35r0hiU?!*;k@s{LF&rBz(NJH7RcB4d_s-8}$Hb%Rax zV(#5g=Cv=f%t{-hl4|FuD1Lp9c|m+{_Q9Lp`^pm4H+&s!EQb0=WughkstHt5GS21| z4rO0Or_a}5$<2vhOI%ySl4_S@9G0CV&2Z5CS3VZ3Zk_34oofWSI_-*bQB)dQMu376%zNT^N>87Qrfw%rjw|^F+{hnmB z^>>t`apN|btInMkUze}lXx%C5iHgo0G;mdf$!Mcwqk$Z*Wj7?FAWu3m+u#4c(k&i< z&P`i7rhuU?N4Th8%mdSj>QapqH%__gq=ElXaTML=%waIL>A6;vZavG!F57IRfZSj( zK9JN*h;?#ns4vUZ98`+M=&ym9{9b{Xib7!ky9y#4tOAF%;6jctbrZa%+lvwU9^_ig zu-DV@Y!xS{`b85&kW=Osq~ZCjflsgvu_)A;v$j;z3)CE6m>SEWBX(q-$xup~uVNt> z`<4v-(vLx9H)Tb^E)bS7GAoFuP3ZPcdmiU31nvA(mHf4B)&P}Bi<((k(p=4|6yskG z8`Se{5B4kSq3kvh)9==r^44$Wzuf-|5$-wT@@j>7fj541dq+}+JXQAzTe+r2UB;35LW zDrmm5>f|%MmO3KuTcVdJ$F&wqP)hBrSNP7S=Xvb2fbP49@8!FF_s6_9pv4ziD*JFOcxI*38&R zDhDwlRd`LaxWZp(ACV0-W+CV_$tmR0+{BhVW8Yr`0d)rEzx$Gc?@s5{UEqe2M+HVxAxxad)~(kQyNkJ}2&e$%wI-8#H&~%EOfbQjC>05q z(8y!=CiLJzM4gEcH1tFqoC+ zJWy!fEH}YhlGcb}EZh!<)@r-HmY`=q6q1tfgp`VBfOhgt^DKlU$9({0+NFKx>Mr!U zs?hkuZzHMpu3so(cT!B2?5l+dlEsa@7*?d?hhN9ZhchRt`ThfgO-bKm6u~pxSO)qK z=TM28%T_k!kDoN*XokMH&q;S~BvSMW#*p2=+^YDxy+rF0>5`GL_yzgNG#gz$OwuJ$ zi0mHS5bA~uTpxR+Qs`0S&0ytSH~l_2!LP;d$`#Spo^N4wJ3w2-9S;tdJQ%e?S9jUG z-GCIiScP96J;k}`6|%X+N`3l{$%rRa;-1be-x}LgMqOIgB3W7={XdJa1aocegLW5U zS0tj9jQ9>ja*qX_3BbfPBs>U#d7oTMQO7TV{Ohi>(v%93h=++w%tL zt8IfMl?n;Xdi!c13^WDsF7)kSVnG=d>&T?Clri7D1OK=PH8p9Zc<=WU_wjA3{2)Gj z67%;&MsLwZ3>lp5kBewVn%UknBT_+rgKyNEOoDN3ywsI1bpMVfZ{QF^v!nqfYbbT5 zJ<{cf2KW)GDpRO9D*CkT`~M%(w`BRftKfeRSoNm8W%^Hy0?gn#1-rLkqe100QkDSnvJz^_ z|501?n2S(gM+#(AAE##mrcCoaJpAID2#X1l$jL4eRLSSBMIP(QD>0>diDpzXum-N1 z_I^d+9aa4q+d<*>8cvh5)tb6Ezska;=0I$*mqFx~u>k+X1QA2r>{taO2SxGCaT9b1 zDNvwGZ<J86plNk^m7{iIYKn7Rg z*%xy_>Fkp7g!o1s&2TLFEv}RD&g%b?6$qdtlEP|F*Cx;)QXqZ%UOOXN{bO2c!OUCW zW89Y!Ba}W)&n`A>;`jq2y^9Y5qxI(Z4yw{0i;K~n-k4I;HtjU_=pM;(j>L*s&uXcm zCTegOiILKKU=B4NEH6#Ved9OAMcyaG3unooNN>HNlW9$99ZQTXHmZ?49=S~wA8dx1 z$L@R7R>YZoVC7cYMnE6qxLWo5z$`(>)z>vtC$6|ys;0FjgOvlZi30Um?Fy}QVa7np z-e8Xfo>mY!bqQXrk?=HX$deB*{KtQq@jF1b5SP4%OvG%ANd-$nVjH|>o&&+BLUISS zB*+ktjLpK`Q-*0oLeMw}e|+O_i%ql%PvY0TIQ<+n;N4}r>=$-xU>t|uhk9=}Rq!Tg zQy~56A0;s1z5=Q#C+EzXC*ig?9B}CZUj*U_^DBxSRuE>Ypi@e5;v96NvB|&LUAqs_ zq(+K3YH*Uy%?Im_&p8@a{sO<-HgDis{xiR|I$1*xJ^cYRg@cnpaJo*J%&zJnDu=NyC-!PAncJz{jQcY z`prQl&^E>!2%QR>AEYZh^KZ$dbA!p-;6@S6{EUM>&L!ig z7eKl759<*U-P`iR{)_$xt$5mW@;}Ne+qU-W>$~A_j6Qg%0O19%x#OiCDD{u@5a?S_ zHqQXbZ(%6Q){F?<$^pFC?Z+U7v`|FQkhljGyml0|(mwU7`sQ7~9OXMHCKjgSVBBBgrTsvBR841)3_}U~I4v<%PE!_Ma}Jb`z-A4?qcA2-1)~)D!vLPDz;Emz z{S;M#erOw)EW)7x009H9F#GY8WuwGja8V^}cFwnV-@qbXk$yrI6O&&w;?`Lv0VS%Srum!!|D(+Dp7>-lnURHw7s%|_vYX%Ijy`X|MmAJxgU?Z%^II5A*vA{iJFoFOEOvKJu&~a-pC`|ZuaFC22UScn;0eOCf zq!t9@`XAR&#)yL?V9B)EgjWcne&D79+PkQg&5-}4cLM)CM%BJ_g2iN$!I^Hug-~UVzP6$|r!Kzem+gmDok+yTx}E!KK9?J@ouJv`Nw%EdxwHj0uG5T#3Ga z9IfJ6@ZLmz!ab=j;F>s)EUP*@rw0*G8vTEg+A>@2|KCCFvk(AasIo~0(t%gjR72#r zIvid+NT5wa@4sf}{q}|kvaWt7w*B^=^aeNZxWaK{%sgHrr`Su`Sb!YLGFxY{fm#Y# zdQb`C&oGs~S9L@~)YosRrn1-g8<|yPyp0+Oag}W}skc45$NfK<9hFY&(r>B0m@v7d z#5Y)(ym*wX8giGf*UFq1eEC5mu0>f9^dzkr}ED zG@SL>eoXB7_w8Mokh-Kou}im!dPm&G3s0u5P$D*7=5l~aqR8hu@4(BHKQ?0WTB^i` z0&^}H^2o`G57r4(AE~HXmr`0kIvz@xF;@wic~HX0+q0I##1I{i;{JpG28x=?$<$pg zil-#+2G!kPMgH%2ofx3NEq&)g&UOf(?A)lWj5(K%5iHIazl7|FSyxw%Cqy)>R%&)m zu2z$Y@pQ=1TFoycQfN;?{#8WWa3U?n){c$~;#S49pe^Z839(=Zf(r$9FIbM_j{Y=i znP{QAV;v0U3z$YRd%g4t+5bIJ##L?1WzTqLUSRJ~Q;P^+kI(qg;u2W;&DW!Ua*|H$ zY1Ve`*qx`YO5$+hjU`%fs_0t(C>yO>Fc2in>oBsZM0UhylsBbJm-(s{tS=?MyRZ{v zwuNO?`}0&N9OuM4KtpML)1^E?RGUN?^hF714f$5_fl(If#=x48cYvaCe$s`NYdqp| zVE(OicJM@mBJ}x%;%UFPvBl0b0#jTqkSSu3q#TQpRvvynf#WxH;k2;fzC=0&6Yr4i zm@K_|7L+o_BlStpOVk&vjwz*jg}`ycfM3^iXY%L!svbBk@w51>mq>bZS zJt-TT$^0WgA*JQdc|no>q zk|Q!2>KXNt?{PWKnnI%u6(!7Fc4ROeE!i9}y0S_b)cX5=&|4O5nPoMnswwa#jp(~@ zFLjv`b{N%_3@3|a3$vP4A!WXE+wDrvgR?lbsEp*6)Md%GHGZlDk=qm$kC8U)#b$P| zS@us69*^DuB~svz6aQa?-&e4%sNB1+8EU_+V&veKjtXRu;5;S!UOe&iqqMX--F%e~ zv$oeDp?gAD8h6)V`ypMt+2_uB6q z1w;``Fyfip>YEb+a$21PW ziAR&E>o+BqfD7KWilNS>f&bjhHRjQ#3Q?mu1qYbMr}Ma@N* z)y3C!LocUR?J06GwdwRxv*G`-RF95!Hnq@=?`z&Wsr=)d`A@~&0t!aq+;L&X&MX`l z3UY6Z&uaci^g>QnTnI!!ubX4c*FXxN?xjbA)bG$yQpsGy;VCt3G3(xS3`Fk%^Z{9g zQ1x>{%aW7gL_^;bnz1gIro(BDDz>`9|KR=4*k^?+So@1OTh60TP|0@8zV!QRB30hZ*me#wtsPvAl(D_>js(?6-XGGV&QoN zb|ZL`m$eMrf;3j8=v3|%Mp)*55VHP5%7lO>T&jiIk_Ul=A#})ssh&T&dD5ulK4OJJ z*{WWQBcTsA&t03guG+nXb{4Ujm2*-!_v z2?N`1*Z$w>2Vm~(YLQ~5$bO_wb`8GQMnOgYfr7LaAv;rx+g1;CwfXPgOaCSzejY-jqCRm0n+2@1IFhWvf=T2PePtIY+q8ZjFSTJ7Awg zC+7czdY!JcwB~B5!sYU93YBlxiO1I2EQoiVQdJ}kNNvj7_~-wE^em=YCR&q2?N;)2 zXj{BWAPS=9>kL!+4&HS1JfM~*PU2F6|GN|su0SG5C?iN5K;GT7L)&lUXrE6iG4)2g zJ=YaVX~N7W6iVy|=8*l&w>-@4Z@b2=l(c;_{T&pk#g=al5?xMiDt&t6df!#0w~AW_ zS4mFSGgWE?)?(D)8RVss)N}B;kR@JAE7)O$U|E{AP#BmsREr-Dv{8qMm1O}Fl+x7K zh%TG6V+~ z?m{Np{p8jY*6LoNl6ffby#PvfB7-lCiYJyA{`1s~R;A z4BKxk$oA&{a0T781t0Y@g4{ojD4`ZQeIN`+d8f@Vl=vQ164SjY^HS51ivGhePy@UR z)c=1~c9v0bL~FWk+}+)!k>D2G2~OjUyE`Pf1$PLL;MzDOXaWQcPH+nl+(SqM!GeTa z$vHFU%&fV0*8Rf|V0BgPy{mfH`#sGmY;)>(_Ejr*>23aHxXV%su|TUe5Y=OBl0ZBq*xsI7O>k;QToY8BiK-C~I{T zKjv$pI|hPJGX1JPs&?uO#_9pgD9^C(B=yZm^1E$O#@n`T4uRL&VKg+oNw2F-aufZ0 zS~?9HJ10S>%*7UsiSrwD4g00b;2o+|Q87uTp^<5~4;||O&rg0^C^)jM{kb3izI)aE zh2m=6udD0ObdM0N=BJ{&v0)d=5~5I@w{(R4v};^nTpPUfU#gBwR>*mh^Nk)Zo@U{@ zOkS-!fGAc)3m-0oR?Vii0+UfQ`7Y#%8MMq=5cG`u^v~f@TtAaqKg=eCEd4ycbiu`i zN`;+eRG6L5O%-~5G(Vf0D*6f30Hf$o5%ryJMFk8iWQRD zzCcfj|2!Z5jHEVZ_6fsVp0@i7wyEk?ScBj4==+vhlvp&ET$p{k?}dDZCa+zkbgE>8 z+?bKECN3$vo0##^yynl%szIYqqgI3NJ}=vZ6e?U9Z^OY8bzm62JMWhv=htMLLbw^AJ5Rj0-tvFZJ6GDJ1{b~I-W^qY~Xj~tn_ljX&}^Akw$*<#3SDLu=mAX z*E_Tl1sx$|y~(<4PFg8Zm@^b`E0~_g8IE;Hs`mH4l~D>6`y{GCUzUZQR4!Q4j5(un znp1KeMeouJX3iI8w9Q4S`m?hE`J=u1(a14COM&@~s6L9DJX%0A+be0vi2;!hHZIYC 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
    ;aTH2ZUZD4#aXR`edddO&N};&1q;ARJ{lV zWK&(P_XWpESo!EKg&aw8+?}-k92Sk*Kcv`~O!UWUcoJjuDvx?aa^R-Se__P0rkJ zzhhc*WkUErxyv}JS$xEc+C0-aG-QkO`8#gApm)ozRju4A80$M-X>%W_8f*T3R2CG4 z8%f?-&7^Wd)9uLF2@bEAat00Y6R<^*uUco+5ZCW8W@Bas!JEbZt_kHr1opUti;Frp z{@KWEIkFIwLTKVqGd3`A>p_}^4mbGI`La==3k-U4p1YaqMRuSeU@ox+p76WA$Chti z!YpxUUVqo#4m0>W+FUT=m288Rd~W_HZqa!Y+)_&am<0ac&}x4=FU>>i*q;QRq6Gi= zErWjxaZ7lTz;&yEAdB_;el(BU?E6QL4a9K-?3 zr@qQQU$n+R;f>_A-p|7!mp{{xSZ+YG>LTfPFHsLYZKQ)QTmKzAVGu|(b$F|^3{ect z+83E8Gym`TL%=M$s&duyGcShGl(}=Pz5v=Qw(rQF4^q~cOqiB3*3l-8&USZ!!L|Oe zSbWV=Z&WGUZt!OyB?b^@$!lOK;`ADwvxPH~)aW&=2gl+SmJkcSr&{?CA{0UjN*Y`Q z`6?%!!r@_?Z!N+!JR_qD$%>>Z6C+mFEdQQbmarileJcteInS0IdIrU(-mQhBUq2uO z{o@YHJqet+yxwRELNmAYy9FUwzb`$;goyl|dA-mNE9dV$x|s&hZW`EN++el_j~Aw9 zJv-gwuD~EQfQEE@&MqQ>t?up;kGZy&t9ye{z2?ouD~q$;qvj)o$-lP|!34!bR^Bn^ zy4l9NZ!77i4`3CUAMG>yz`cZONqvoguhfIHw>*deZM)xgNM&b9?YznV$Fe{fb{~-l zyw9BKxsO|WE{~ml;`tI!yXB44IB?yJDfvsTZSZN1fgi{R;-zpEr{b#IZj_%z2q1?2 X%kWYv2M-|L9rR35Q=vi5GV=cb?hX5+ literal 28244 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 AivR!s diff --git a/Subsurface/Content/Items/Door/dockingport1.ogg b/Subsurface/Content/Items/Door/dockingport1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3d9aea42e78d243ff10de94ee59fc0d444ed75cb GIT binary patch literal 39057 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�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 literal 0 HcmV?d00001 diff --git a/Subsurface/Content/Items/Door/dockingport2.ogg b/Subsurface/Content/Items/Door/dockingport2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8795bf1fb26c65b179880d97adddd289c40f8a38 GIT binary patch literal 23118 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 SG5ei`SZ`kg==|w$61V`<8ca(7 literal 0 HcmV?d00001 diff --git a/Subsurface/Content/Items/Door/dockingport2.png b/Subsurface/Content/Items/Door/dockingport2.png new file mode 100644 index 0000000000000000000000000000000000000000..2862aaf626fb6b3f4d67565f661cfcb5837e01fb GIT binary patch literal 12926 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 literal 0 HcmV?d00001 diff --git a/Subsurface/Content/Items/Door/doors.xml b/Subsurface/Content/Items/Door/doors.xml index 7834d3d90..3b709c5e1 100644 --- a/Subsurface/Content/Items/Door/doors.xml +++ b/Subsurface/Content/Items/Door/doors.xml @@ -88,11 +88,12 @@ linkable="true" pickdistance="150.0"> - + - - + + + @@ -105,6 +106,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Subsurface/Content/Items/Reactor/reactor.xml b/Subsurface/Content/Items/Reactor/reactor.xml index c1d0cab82..7561565af 100644 --- a/Subsurface/Content/Items/Reactor/reactor.xml +++ b/Subsurface/Content/Items/Reactor/reactor.xml @@ -67,8 +67,7 @@ - - + - - + @@ -100,8 +98,7 @@ - - + diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs index ca39e4aee..71835eebe 100644 --- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs @@ -734,6 +734,10 @@ namespace Barotrauma { ladderSimPos += character.SelectedConstruction.Submarine.SimPosition; } + else if (currentHull.Submarine != null && currentHull.Submarine != character.SelectedConstruction.Submarine) + { + ladderSimPos += character.SelectedConstruction.Submarine.SimPosition - currentHull.Submarine.SimPosition; + } MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, head.SimPosition.Y + 0.05f), 10.5f); MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, torso.SimPosition.Y), 10.5f); @@ -742,7 +746,9 @@ namespace Barotrauma Vector2 handPos = new Vector2( ladderSimPos.X, - head.SimPosition.Y + 0.0f + movement.Y * 0.1f - ladderSimPos.Y); + head.SimPosition.Y + movement.Y * 0.1f - ladderSimPos.Y); + + handPos.Y = Math.Min(-0.5f, handPos.Y); MoveLimb(leftHand, new Vector2(handPos.X, @@ -815,8 +821,7 @@ namespace Barotrauma // - moving sideways // - reached the top or bottom of the ladder if (notClimbing || - (TargetMovement.Y < 0.0f && ConvertUnits.ToSimUnits(trigger.Height) + handPos.Y < HeadPosition * 1.5f) || - (TargetMovement.Y > 0.0f && handPos.Y > 0.1f)) + (TargetMovement.Y < 0.0f && ConvertUnits.ToSimUnits(trigger.Height) + handPos.Y < HeadPosition * 1.5f)) { Anim = Animation.None; character.SelectedConstruction = null; diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index 69347b7bc..43c5bda4f 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -20,23 +20,24 @@ namespace Barotrauma.Items.Components private static List list = new List(); private Sprite overlaySprite; - + private Vector2 distanceTolerance; private DockingPort dockingTarget; private float dockingState; + private int dockingDir; private Joint joint; - private int dockingDir; - private Hull[] hulls; private Body[] bodies; private Gap gap; + private bool docked; + [HasDefaultValue("32.0,32.0", false)] public string DistanceTolerance { @@ -58,22 +59,22 @@ namespace Barotrauma.Items.Components set; } - public override bool IsActive + public bool Docked { get { - return base.IsActive; + return docked; } set { - if (!IsActive && value) + if (!docked && value) { if (dockingTarget == null) AttemptDock(); if (dockingTarget == null) return; - base.IsActive = value; + docked = true; } - else if (IsActive && !value) + else if (docked && !value) { Undock(); } @@ -97,10 +98,12 @@ namespace Barotrauma.Items.Components } } + IsActive = true; + list.Add(this); } - private void AttemptDock() + private DockingPort FindAdjacentPort() { foreach (DockingPort port in list) { @@ -109,24 +112,41 @@ namespace Barotrauma.Items.Components if (Math.Abs(port.item.WorldPosition.X - item.WorldPosition.X) > distanceTolerance.X) continue; if (Math.Abs(port.item.WorldPosition.Y - item.WorldPosition.Y) > distanceTolerance.Y) continue; - Dock(port); - return; - + return port; } + + return null; + } + + private void AttemptDock() + { + var adjacentPort = FindAdjacentPort(); + if (adjacentPort != null) Dock(adjacentPort); } private void Dock(DockingPort target) { - if (dockingTarget!=null) + if (dockingTarget != null) { Undock(); } + PlaySound(ActionType.OnUse, item.WorldPosition); + + dockingTarget = target; dockingTarget.dockingTarget = this; - dockingTarget.IsActive = true; + dockingTarget.Docked = true; - dockingDir = Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X); + if (Character.Controlled != null && + (Character.Controlled.Submarine == dockingTarget.item.Submarine || Character.Controlled.Submarine == item.Submarine)) + { + GameMain.GameScreen.Cam.Shake = Vector2.Distance(dockingTarget.item.Submarine.Velocity, item.Submarine.Velocity); + } + + dockingDir = IsHorizontal ? + Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) : + Math.Sign(item.WorldPosition.Y - dockingTarget.item.WorldPosition.Y); dockingTarget.dockingDir = -dockingDir; CreateJoint(false); @@ -184,59 +204,62 @@ namespace Barotrauma.Items.Components subs = new Submarine[] { dockingTarget.item.Submarine,item.Submarine }; } - hullRects[0] = new Rectangle(hullRects[0].Center.X, hullRects[0].Y, ((int)DockedDistance / 2), hullRects[0].Height); hullRects[1] = new Rectangle(hullRects[1].Center.X - ((int)DockedDistance / 2), hullRects[1].Y, ((int)DockedDistance / 2), hullRects[1].Height); - - for (int i = 0; i < 2;i++ ) { hullRects[i].Location -= (subs[i].WorldPosition - subs[i].HiddenSubPosition).ToPoint(); hulls[i] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRects[i], subs[i]); hulls[i].AddToGrid(subs[i]); - for (int j = 0; j < 2; j++) { bodies[i + j * 2] = BodyFactory.CreateEdge(GameMain.World, ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X, hullRects[i].Y - hullRects[i].Height * j)), ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Right, hullRects[i].Y - hullRects[i].Height * j))); - - //bodies[i + j * 2] = BodyFactory.CreateRectangle(GameMain.World, ConvertUnits.ToSimUnits(hullRects[i].Width), 0.1f, 5.0f); - //bodies[i + j * 2].SetTransform(ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Center.X, hullRects[i].Y - (hullRects[i].Height+5) * j)), 0.0f); } } - gap = new Gap(new Rectangle(hullRects[0].Right-2, hullRects[0].Y, 4, hullRects[0].Height), true, item.Submarine); - gap.linkedTo.Clear(); - gap.linkedTo.Add(hulls[0]); - gap.linkedTo.Add(hulls[1]); - - //var hullRect1 = new Rectangle(hullRects.Min(h => h.Center.X), hullRect.Y, ((int)DockedDistance / 2), hullRects[0].Height); - //var hullRect2 = new Rectangle(hullRects.Max(h => h.Center.X), hullRect.Y, ((int)DockedDistance / 2), hullRects[0].Height); - - //var sub1 = hullRect.Center.X < targetRect.Center.X ? item.Submarine : dockingTarget.item.Submarine; - //var sub2 = hullRect.Center.X > targetRect.Center.X ? item.Submarine : dockingTarget.item.Submarine; - - // hullRect1.Location -= (sub1.WorldPosition - sub1.HiddenSubPosition).ToPoint(); - //hulls[0] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRect1, sub1); - //hulls[0].AddToGrid(sub1); - - //hullRect2.Location -= (sub2.WorldPosition - sub2.HiddenSubPosition).ToPoint(); - //hulls[1] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRect2, sub2); - //hulls[1].AddToGrid(sub2); - + gap = new Gap(new Rectangle(hullRects[0].Right-2, hullRects[0].Y, 4, hullRects[0].Height), true, subs[0]); } else { - //hullRect = new Rectangle(hullRect.X, - // Math.Max(hullRect.Y - hullRect.Height / 2, targetRect.Y - targetRect.Height / 2), hullRect.Width, (int)DockedDistance); + if (hullRects[0].Center.Y > hullRects[1].Center.Y) + { + hullRects = new Rectangle[] { dockingTarget.item.WorldRect, item.WorldRect }; + subs = new Submarine[] { dockingTarget.item.Submarine, item.Submarine }; + } + + hullRects[0] = new Rectangle(hullRects[0].X, hullRects[0].Y + (int)(-hullRects[0].Height+DockedDistance)/2, hullRects[0].Width, ((int)DockedDistance / 2)); + hullRects[1] = new Rectangle(hullRects[1].X, hullRects[1].Y - hullRects[1].Height/2, hullRects[1].Width, ((int)DockedDistance / 2)); + + for (int i = 0; i < 2; i++) + { + hullRects[i].Location -= (subs[i].WorldPosition - subs[i].HiddenSubPosition).ToPoint(); + hulls[i] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRects[i], subs[i]); + hulls[i].AddToGrid(subs[i]); + + //for (int j = 0; j < 2; j++) + //{ + // bodies[i + j * 2] = BodyFactory.CreateEdge(GameMain.World, + // ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X + hullRects[i].Width * j, hullRects[i].Y)), + // ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X + hullRects[i].Width * j, hullRects[i].Y-hullRects[i].Height))); + //} + } + + gap = new Gap(new Rectangle(hullRects[0].X, hullRects[0].Y+2, hullRects[0].Width, 4), true, subs[0]); + } + gap.linkedTo.Clear(); + gap.linkedTo.Add(hulls[0]); + gap.linkedTo.Add(hulls[1]); + foreach (Body body in bodies) { + if (body == null) continue; body.BodyType = BodyType.Static; body.Friction = 0.5f; @@ -248,62 +271,83 @@ namespace Barotrauma.Items.Components private void Undock() { - if (dockingTarget == null) return; + if (dockingTarget == null || !docked) return; - dockingTarget.dockingTarget = null; - dockingTarget.IsActive = false; + PlaySound(ActionType.OnUse, item.WorldPosition); + docked = false; + + dockingTarget.Undock(); dockingTarget = null; - GameMain.World.RemoveJoint(joint); - joint = null; - - hulls[0].Remove(); - hulls[1].Remove(); - - gap.Remove(); - gap = null; - - foreach (Body body in bodies) + if (joint != null) { - GameMain.World.RemoveBody(body); + GameMain.World.RemoveJoint(joint); + joint = null; } - bodies = null; + if (hulls != null) + { + hulls[0].Remove(); + hulls[1].Remove(); + hulls = null; + } - - //foreach (Gap g in hulls[0].ConnectedGaps) - //{ - // g.Remove(); - //} + if (gap != null) + { + gap.Remove(); + gap = null; + } - //foreach (Gap g in hulls[1].ConnectedGaps) - //{ - // g.Remove(); - //} + if (bodies!=null) + { + foreach (Body body in bodies) + { + if (body == null) continue; + GameMain.World.RemoveBody(body); + } + bodies = null; + } - - hulls = null; } public override void Update(float deltaTime, Camera cam) { - if (dockingTarget==null) + + + if (dockingTarget == null) { dockingState = MathHelper.Lerp(dockingState, 0.0f, deltaTime * 10.0f); - if (dockingState < 0.01f) base.IsActive = false; + if (dockingState < 0.01f) docked = false; + + item.SendSignal(0, "0", "state_out"); + + item.SendSignal(0, (FindAdjacentPort() != null) ? "1" : "0", "proximity_sensor"); + } else { - if (joint is DistanceJoint && Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f) + if (joint is DistanceJoint) { - GameMain.World.RemoveJoint(joint); + item.SendSignal(0, "0", "state_out"); - CreateJoint(true); - CreateHull(); + if (Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f) + { + GameMain.World.RemoveJoint(joint); + + PlaySound(ActionType.OnSecondaryUse, item.WorldPosition); + + CreateJoint(true); + CreateHull(); + } + dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f); } + else + { + item.SendSignal(0, "1", "state_out"); - dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f); + dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f); + } } } @@ -315,10 +359,11 @@ namespace Barotrauma.Items.Components drawPos.Y = -drawPos.Y; var rect = overlaySprite.SourceRect; - drawPos.Y -= rect.Height / 2; - + if (IsHorizontal) { + drawPos.Y -= rect.Height / 2; + if (dockingDir == 1) { spriteBatch.Draw(overlaySprite.Texture, @@ -339,6 +384,8 @@ namespace Barotrauma.Items.Components } else { + drawPos.X -= rect.Width / 2; + if (dockingDir == 1) { spriteBatch.Draw(overlaySprite.Texture, @@ -363,5 +410,19 @@ namespace Barotrauma.Items.Components { list.Remove(this); } + + public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f) + { + switch (connection.Name) + { + case "toggle": + Docked = !docked; + break; + case "set_active": + case "set_state": + Docked = signal != "0"; + break; + } + } } } diff --git a/Subsurface/Source/Items/Components/Signal/SignalCheckComponent.cs b/Subsurface/Source/Items/Components/Signal/SignalCheckComponent.cs index b2e4133d9..82b7fa423 100644 --- a/Subsurface/Source/Items/Components/Signal/SignalCheckComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/SignalCheckComponent.cs @@ -4,7 +4,7 @@ namespace Barotrauma.Items.Components { class SignalCheckComponent : ItemComponent { - private string output; + private string output, falseOutput; private string targetSignal; @@ -14,6 +14,12 @@ namespace Barotrauma.Items.Components get { return output; } set { output = value; } } + [InGameEditable, HasDefaultValue("0", true)] + public string FalseOutput + { + get { return falseOutput; } + set { falseOutput = value; } + } [InGameEditable, HasDefaultValue("", true)] public string TargetSignal @@ -32,7 +38,10 @@ namespace Barotrauma.Items.Components switch (connection.Name) { case "signal_in": - item.SendSignal(stepsTaken, (signal == targetSignal) ? output : "0", "signal_out"); + string signalOut = (signal == targetSignal) ? output : falseOutput; + + if (string.IsNullOrWhiteSpace(signalOut)) return; + item.SendSignal(stepsTaken, signalOut, "signal_out"); break; case "set_output": diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 836cbec2f..2f79d7a0a 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -19,7 +19,7 @@ namespace Barotrauma public enum ActionType { - Always, OnPicked, OnUse, + Always, OnPicked, OnUse, OnSecondaryUse, OnWearing, OnContaining, OnContained, OnActive, OnFailure, OnBroken, OnFire, InWater, @@ -1248,6 +1248,7 @@ namespace Barotrauma { picked = true; ic.ApplyStatusEffects(ActionType.OnPicked, 1.0f, picker); + ic.PlaySound(ActionType.OnPicked, picker.WorldPosition); if (picker==Character.Controlled) GUIComponent.MouseOn = null; diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index 621b15049..a908aed27 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -173,8 +173,6 @@ namespace Barotrauma { Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height/ 2.0f)); - - GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y)/10.0f, Color.Red); GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, Color.Orange); @@ -329,6 +327,18 @@ namespace Barotrauma if (linkedTo.Count < 2) return; Hull hull1 = (Hull)linkedTo[0]; Hull hull2 = (Hull)linkedTo[1]; + + Vector2 subOffset = Vector2.Zero; + if (hull1.Submarine != Submarine) + { + subOffset =Submarine.Position - hull1.Submarine.Position; + } + else if (hull2.Submarine != Submarine) + { + + subOffset = hull2.Submarine.Position - Submarine.Position; + + } if (hull1.Volume == 0.0 && hull2.Volume == 0.0) return; @@ -341,13 +351,14 @@ namespace Barotrauma //horizontal gap (such as a regular door) if (isHorizontal) { - higherSurface = Math.Max(hull1.Surface,hull2.Surface); - float delta=0.0f; + higherSurface = Math.Max(hull1.Surface, hull2.Surface + subOffset.Y); + float delta=0.0f; + //water level is above the lower boundary of the gap - if (Math.Max(hull1.Surface+hull1.WaveY[hull1.WaveY.Length - 1], hull2.Surface+hull2.WaveY[0]) > rect.Y - size) + if (Math.Max(hull1.Surface+hull1.WaveY[hull1.WaveY.Length - 1], hull2.Surface + subOffset.Y +hull2.WaveY[0]) > rect.Y - size) { - int dir = (hull1.Pressure > hull2.Pressure) ? 1 : -1; + int dir = (hull1.Pressure > hull2.Pressure+subOffset.Y) ? 1 : -1; //water flowing from the righthand room to the lefthand room if (dir == -1) @@ -360,38 +371,42 @@ namespace Barotrauma flowTargetHull = hull1; //make sure not to move more than what the room contains - delta = Math.Min((hull2.Pressure - hull1.Pressure) * 5.0f * sizeModifier, Math.Min(hull2.Volume, hull2.FullVolume)); + delta = Math.Min(((hull2.Pressure + subOffset.Y) - hull1.Pressure) * 5.0f * sizeModifier, Math.Min(hull2.Volume, hull2.FullVolume)); //make sure not to place more water to the target room than it can hold delta = Math.Min(delta, hull1.FullVolume + Hull.MaxCompress - (hull1.Volume)); hull1.Volume += delta; hull2.Volume -= delta; if (hull1.Volume > hull1.FullVolume) - hull1.Pressure = Math.Max(hull1.Pressure, (hull1.Pressure + hull2.Pressure) / 2); + { + hull1.Pressure = Math.Max(hull1.Pressure, (hull1.Pressure + hull2.Pressure+subOffset.Y) / 2); + } flowForce = new Vector2(-delta, 0.0f); } else if (dir == 1) { if (!(hull1.Volume > 0.0f)) return; - lowerSurface = hull2.Surface - hull2.WaveY[1]; + //lowerSurface = hull2.Surface - hull2.WaveY[1]; flowTargetHull = hull2; //make sure not to move more than what the room contains - delta = Math.Min((hull1.Pressure - hull2.Pressure) * 5.0f * sizeModifier, Math.Min(hull1.Volume, hull1.FullVolume)); + delta = Math.Min((hull1.Pressure - (hull2.Pressure + subOffset.Y)) * 5.0f * sizeModifier, Math.Min(hull1.Volume, hull1.FullVolume)); //make sure not to place more water to the target room than it can hold delta = Math.Min(delta, hull2.FullVolume + Hull.MaxCompress - (hull2.Volume)); hull1.Volume -= delta; hull2.Volume += delta; if (hull2.Volume > hull2.FullVolume) - hull2.Pressure = Math.Max(hull2.Pressure, (hull1.Pressure + hull2.Pressure) / 2); + { + hull2.Pressure = Math.Max(hull2.Pressure, ((hull1.Pressure-subOffset.Y) + hull2.Pressure) / 2); + } flowForce = new Vector2(delta, 0.0f); } - if (delta>100.0f) + if (delta>100.0f && subOffset == Vector2.Zero) { float avg = (hull1.Surface + hull2.Surface) / 2.0f; //float avgVel = (hull2.WaveVel[1] + hull1.WaveVel[hull1.WaveY.Length - 2]) / 2.0f; @@ -625,10 +640,9 @@ namespace Barotrauma GapList.Remove(this); - foreach (MapEntity entity in linkedTo) + foreach (Hull hull in Hull.hullList) { - var hull = entity as Hull; - if (hull.ConnectedGaps.Contains(this)) hull.ConnectedGaps.Remove(this); + hull.ConnectedGaps.Remove(this); } } diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index f0f2c8793..ff79a1a69 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -53,6 +53,7 @@ namespace Barotrauma private bool update; + private Sound currentFlowSound; private int soundIndex; private float soundVolume; @@ -392,12 +393,24 @@ namespace Barotrauma foreach (Gap gap in ConnectedGaps) { float gapFlow = gap.LerpedFlowForce.Length(); + +#if DEBUG + var asd = MapEntity.FindEntityByID(gap.ID); + + if (asd != gap) + { + int adslkmfdlasfk = 9; + } +#endif + + if (gapFlow > strongestFlow) { strongestFlow = gapFlow; } } + if (strongestFlow>0.1f) { soundVolume = soundVolume + ((strongestFlow < 100.0f) ? -deltaTime * 0.5f : deltaTime * 0.5f); @@ -406,13 +419,24 @@ namespace Barotrauma int index = (int)Math.Floor(strongestFlow / 100.0f); index = Math.Min(index, 2); - soundIndex = SoundPlayer.flowSounds[index].Loop(soundIndex, soundVolume, WorldPosition, 2000.0f); + var flowSound = SoundPlayer.flowSounds[index]; + if (flowSound != currentFlowSound && soundIndex > -1) + { + Sounds.SoundManager.Stop(soundIndex); + currentFlowSound = null; + soundIndex = -1; + } + + currentFlowSound = flowSound; + + soundIndex = currentFlowSound.Loop(soundIndex, soundVolume, WorldPosition, 2000.0f); } else { if (soundIndex > -1) { Sounds.SoundManager.Stop(soundIndex); + currentFlowSound = null; soundIndex = -1; } } diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index 7453f2246..f9312bf65 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -375,7 +375,18 @@ namespace Barotrauma.Lights Vector2 lightSourcePos = light.Position; - if (light.Submarine==null && parentEntity != null && parentEntity.Submarine != null) lightSourcePos -= parentEntity.Submarine.Position; + if (parentEntity != null && parentEntity.Submarine != null) + { + if (light.Submarine == null) + { + lightSourcePos -= parentEntity.Submarine.Position; + } + else if (light.Submarine != parentEntity.Submarine) + { + lightSourcePos += (light.Submarine.Position-parentEntity.Submarine.Position); + } + + } CachedShadow cachedShadow = null; if (!cachedShadows.TryGetValue(light, out cachedShadow) || diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index 21093cc70..cde8e7f5c 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -95,6 +95,7 @@ namespace Barotrauma.Lights foreach (LightSource light in lights) { if (light.Color.A < 0.01f || light.Range < 1.0f) continue; + //!!!!!!!!!!!!!!!! if (light.hullsInRange == null) light.UpdateHullsInRange(); if (!light.hullsInRange.Any() || !MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index 46e04bf90..030f7e8e2 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -86,7 +86,7 @@ namespace Barotrauma.Lights { range = MathHelper.Clamp(value, 0.0f, 2048.0f); - if (Math.Abs(prevHullUpdateRange - range) < 5.0f) return; + if (Math.Abs(prevHullUpdateRange - range) < 10.0f) return; UpdateHullsInRange(); prevHullUpdateRange = range; @@ -143,18 +143,24 @@ namespace Barotrauma.Lights foreach (ConvexHull ch in ConvexHull.list) { - if (Submarine == null && ch.ParentEntity.Submarine != null) + Vector2 lightPos = position; + + if (Submarine==null) { - if (MathUtils.CircleIntersectsRectangle(position - ch.ParentEntity.Submarine.Position, range, ch.BoundingBox)) + if (ch.ParentEntity.Submarine != null) { - hullsInRange.Add(ch); + lightPos -= ch.ParentEntity.Submarine.Position; } } - else if (MathUtils.CircleIntersectsRectangle(position, range, ch.BoundingBox)) + else if (ch.ParentEntity.Submarine != null && ch.ParentEntity.Submarine != Submarine) + { + lightPos -= (ch.ParentEntity.Submarine.Position - Submarine.Position); + } + + if (MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)) { hullsInRange.Add(ch); } - } } diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 7a91e11a3..49f9d5219 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -349,6 +349,14 @@ namespace Barotrauma GameMain.World.RemoveBody(b); } + foreach (WallSection s in sections) + { + if (s.gap != null) + { + s.gap.Remove(); + s.gap = null; + } + } if (convexHulls != null) convexHulls.ForEach(x => x.Remove()); } diff --git a/Subsurface/Submarines/Shuttle Mark I.sub b/Subsurface/Submarines/Shuttle Mark I.sub index 68dfd9d4945cff8c480d57c64d8524143e08dfec..1de548faab143c6053a95cfc3ebb55b1c7903d5e 100644 GIT binary patch literal 3220 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 GX8-`QPFSb_ literal 2333 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 QO8>Y24`nVOy}o(^00(V!Z literal 15524 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 From aae24b2b2c39e5ecafc97ee25519751472783843 Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 30 Jun 2016 17:50:02 +0300 Subject: [PATCH 10/13] Better logic for determining which convex hulls are in the range of a lightsource (separate convexhull lists for each sub) --- Subsurface/Source/Characters/Limb.cs | 2 +- .../Items/Components/Signal/LightComponent.cs | 4 +- Subsurface/Source/Map/Lights/ConvexHull.cs | 46 ++++- Subsurface/Source/Map/Lights/LightManager.cs | 34 ++-- Subsurface/Source/Map/Lights/LightSource.cs | 179 +++++++++++++++--- Subsurface/Source/Utils/MathUtils.cs | 20 +- 6 files changed, 218 insertions(+), 67 deletions(-) diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs index 2a77e3192..049c30f8d 100644 --- a/Subsurface/Source/Characters/Limb.cs +++ b/Subsurface/Source/Characters/Limb.cs @@ -428,7 +428,7 @@ namespace Barotrauma { if (LightSource != null) { - LightSource.Submarine = body.Submarine; + LightSource.ParentSub = body.Submarine; LightSource.Position = Position; } diff --git a/Subsurface/Source/Items/Components/Signal/LightComponent.cs b/Subsurface/Source/Items/Components/Signal/LightComponent.cs index 4fa63fdd7..a761383d3 100644 --- a/Subsurface/Source/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/LightComponent.cs @@ -102,7 +102,7 @@ namespace Barotrauma.Items.Components : base (item, element) { light = new LightSource(element); - light.Submarine = item.CurrentHull == null ? null : item.CurrentHull.Submarine; + light.ParentSub = item.CurrentHull == null ? null : item.CurrentHull.Submarine; light.Position = item.Position; light.CastShadows = castShadows; @@ -121,7 +121,7 @@ namespace Barotrauma.Items.Components { base.Update(deltaTime, cam); - light.Submarine = item.Submarine; + light.ParentSub = item.Submarine; ApplyStatusEffects(ActionType.OnActive, deltaTime); diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index f9312bf65..73e791966 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -42,9 +42,21 @@ namespace Barotrauma.Lights } } + class ConvexHullList + { + public readonly Submarine Submarine; + public List List; + + public ConvexHullList(Submarine submarine) + { + Submarine = submarine; + List = new List(); + } + } + class ConvexHull { - public static List list = new List(); + public static List HullLists = new List(); static BasicEffect shadowEffect; static BasicEffect penumbraEffect; @@ -116,15 +128,20 @@ namespace Barotrauma.Lights Enabled = true; - foreach (ConvexHull ch in list) + var chList = HullLists.Find(x => x.Submarine == parent.Submarine); + if (chList == null) + { + chList = new ConvexHullList(parent.Submarine); + HullLists.Add(chList); + } + + foreach (ConvexHull ch in chList.List) { UpdateIgnoredEdges(ch); ch.UpdateIgnoredEdges(this); } - - list.Add(this); - + chList.List.Add(this); } private void UpdateIgnoredEdges(ConvexHull ch) @@ -219,7 +236,7 @@ namespace Barotrauma.Lights { foreach (KeyValuePair cachedShadow in cachedShadows) { - cachedShadow.Key.NeedsHullUpdate(); + cachedShadow.Key.NeedsHullUpdate = true; cachedShadow.Value.Dispose(); } cachedShadows.Clear(); @@ -377,13 +394,13 @@ namespace Barotrauma.Lights if (parentEntity != null && parentEntity.Submarine != null) { - if (light.Submarine == null) + if (light.ParentSub == null) { lightSourcePos -= parentEntity.Submarine.Position; } - else if (light.Submarine != parentEntity.Submarine) + else if (light.ParentSub != parentEntity.Submarine) { - lightSourcePos += (light.Submarine.Position-parentEntity.Submarine.Position); + lightSourcePos += (light.ParentSub.Position-parentEntity.Submarine.Position); } } @@ -467,7 +484,16 @@ namespace Barotrauma.Lights { ClearCachedShadows(); - list.Remove(this); + var chList = HullLists.Find(x => x.Submarine == parentEntity.Submarine); + + if (chList != null) + { + chList.List.Remove(this); + if (chList.List.Count == 0) + { + HullLists.Remove(chList); + } + } } diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index cde8e7f5c..7281cf055 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -73,7 +73,7 @@ namespace Barotrauma.Lights { foreach (LightSource light in lights) { - light.UpdateHullsInRange(); + light.NeedsHullUpdate = true; } } @@ -94,10 +94,8 @@ namespace Barotrauma.Lights foreach (LightSource light in lights) { - if (light.Color.A < 0.01f || light.Range < 1.0f) continue; - //!!!!!!!!!!!!!!!! - if (light.hullsInRange == null) light.UpdateHullsInRange(); - if (!light.hullsInRange.Any() || !MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; + if (light.Color.A < 0.01f || light.Range < 1.0f || !light.CastShadows) continue; + if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; //clear alpha to 1 ClearAlphaToOne(graphics, spriteBatch); @@ -107,12 +105,7 @@ namespace Barotrauma.Lights graphics.RasterizerState = RasterizerState.CullNone; graphics.BlendState = CustomBlendStates.WriteToAlpha; - foreach (ConvexHull ch in light.hullsInRange) - { - //if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, ch.BoundingBox)) continue; - //draw shadow - ch.DrawShadows(graphics, cam, light, shadowTransform, false); - } + light.DrawShadows(graphics, cam, shadowTransform); //draw the light shape //where Alpha is 0, nothing will be written @@ -131,7 +124,7 @@ namespace Barotrauma.Lights foreach (LightSource light in lights) { - if (light.hullsInRange==null || light.hullsInRange.Any() || light.Color.A < 0.01f) continue; + if (light.Color.A < 0.01f || light.Range < 1.0f || light.CastShadows) continue; //if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; light.Draw(spriteBatch); @@ -186,13 +179,18 @@ namespace Barotrauma.Lights Matrix shadowTransform = cam.ShaderTransform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - foreach (ConvexHull convexHull in ConvexHull.list) - { - if (!convexHull.Intersects(camView)) continue; - //if (!camView.Intersects(convexHull.BoundingBox)) continue; + var convexHulls = LightSource.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine); - convexHull.DrawShadows(graphics, cam, pos, shadowTransform); - } + if (convexHulls != null) + { + foreach (ConvexHull convexHull in convexHulls) + { + if (!convexHull.Intersects(camView)) continue; + //if (!camView.Intersects(convexHull.BoundingBox)) continue; + + convexHull.DrawShadows(graphics, cam, pos, shadowTransform); + } + } } graphics.SetRenderTarget(null); } diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index 030f7e8e2..0542cd359 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -12,7 +12,7 @@ namespace Barotrauma.Lights { private static Texture2D lightTexture; - public List hullsInRange; + private List hullsInRange; private Color color; @@ -24,7 +24,7 @@ namespace Barotrauma.Lights private Sprite overrideLightTexture; - public Entity Submarine; + public Entity ParentSub; public bool CastShadows; @@ -33,6 +33,8 @@ namespace Barotrauma.Lights private Vector2 prevHullUpdatePosition; + public bool NeedsHullUpdate; + private Vector2 position; public Vector2 Position { @@ -43,8 +45,8 @@ namespace Barotrauma.Lights position = value; if (Vector2.Distance(prevHullUpdatePosition, position) < 5.0f) return; - - UpdateHullsInRange(); + + NeedsHullUpdate = true; prevHullUpdatePosition = position; } } @@ -57,7 +59,7 @@ namespace Barotrauma.Lights public Vector2 WorldPosition { - get { return (Submarine == null) ? position : position + Submarine.Position; } + get { return (ParentSub == null) ? position : position + ParentSub.Position; } } public static Texture2D LightTexture @@ -87,8 +89,8 @@ namespace Barotrauma.Lights range = MathHelper.Clamp(value, 0.0f, 2048.0f); if (Math.Abs(prevHullUpdateRange - range) < 10.0f) return; - - UpdateHullsInRange(); + + NeedsHullUpdate = true; prevHullUpdateRange = range; } } @@ -117,9 +119,9 @@ namespace Barotrauma.Lights public LightSource(Vector2 position, float range, Color color, Submarine submarine) { - hullsInRange = new List(); + hullsInRange = new List(); - this.Submarine = submarine; + this.ParentSub = submarine; this.position = position; this.range = range; @@ -132,43 +134,166 @@ namespace Barotrauma.Lights GameMain.LightManager.AddLight(this); } - public void UpdateHullsInRange() + public void DrawShadows(GraphicsDevice graphics, Camera cam, Matrix shadowTransform) { if (!CastShadows) return; - - if (hullsInRange == null) hullsInRange = new List(); - - hullsInRange.Clear(); if (range < 1.0f || color.A < 0.01f) return; - foreach (ConvexHull ch in ConvexHull.list) + foreach (Submarine sub in Submarine.Loaded) { - Vector2 lightPos = position; + var hulls = GetHullsInRange(sub); - if (Submarine==null) + if (hulls == null) continue; + + foreach ( ConvexHull ch in hulls) { - if (ch.ParentEntity.Submarine != null) + ch.DrawShadows(graphics, cam, this, shadowTransform, false); + } + } + + var outsideHulls = GetHullsInRange(null); + + NeedsHullUpdate = false; + + if (outsideHulls == null) return; + foreach (ConvexHull ch in outsideHulls) + { + ch.DrawShadows(graphics, cam, this, shadowTransform, false); + } + } + + private List GetHullsInRange(Submarine sub) + { + var chList = hullsInRange.Find(x => x.Submarine == sub); + + if (chList == null) + { + chList = new ConvexHullList(sub); + hullsInRange.Add(chList); + } + List list = chList.List; + + + Vector2 lightPos = position; + if (ParentSub == null) + { + //light and the convexhull are both outside + if (sub == null) + { + if (NeedsHullUpdate) { - lightPos -= ch.ParentEntity.Submarine.Position; + var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub); + + list = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)); + chList.List = list; } } - else if (ch.ParentEntity.Submarine != null && ch.ParentEntity.Submarine != Submarine) + //light is outside, convexhull inside a sub + else { - lightPos -= (ch.ParentEntity.Submarine.Position - Submarine.Position); - } + //todo: check + lightPos -= sub.Position; - if (MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)) - { - hullsInRange.Add(ch); + Rectangle subBorders = sub.Borders; + subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height); + + //only draw if the light overlaps with the sub + if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) return null; + + var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub); + list = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)); } } + else + { + //light is inside, convexhull outside + if (sub == null) return null; + + //light and convexhull are both inside the same sub + if (sub == ParentSub) + { + if (NeedsHullUpdate) + { + var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub); + + list = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)); + chList.List = list; + } + } + //light and convexhull are inside different subs + else + { + lightPos -= (sub.Position - ParentSub.Position); + + Rectangle subBorders = sub.Borders; + subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height); + + //only draw if the light overlaps with the sub + if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) return null; + + var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub); + list = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)); + } + } + + return list; } - public void NeedsHullUpdate() + public static List GetHullsInRange(Vector2 position, float range, Submarine ParentSub) { - hullsInRange = null; + List list = new List(); + + foreach (ConvexHullList chList in ConvexHull.HullLists) + { + Vector2 lightPos = position; + if (ParentSub == null) + { + //light and the convexhull are both outside + if (chList.Submarine == null) + { + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + + } + //light is outside, convexhull inside a sub + else + { + if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, chList.Submarine.Borders)) continue; + + lightPos -= (chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition); + + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + } + } + else + { + //light is inside, convexhull outside + if (chList.Submarine == null) continue; + + //light and convexhull are both inside the same sub + if (chList.Submarine == ParentSub) + { + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + } + //light and convexhull are inside different subs + else + { + lightPos -= (chList.Submarine.Position - ParentSub.Position); + + Rectangle subBorders = chList.Submarine.Borders; + subBorders.Location += chList.Submarine.HiddenSubPosition.ToPoint() - new Point(0, chList.Submarine.Borders.Height); + + if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) continue; + + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + } + } + } + + + return list; } + public void Draw(SpriteBatch spriteBatch) { if (range > 1.0f) diff --git a/Subsurface/Source/Utils/MathUtils.cs b/Subsurface/Source/Utils/MathUtils.cs index cb0b98697..695be7904 100644 --- a/Subsurface/Source/Utils/MathUtils.cs +++ b/Subsurface/Source/Utils/MathUtils.cs @@ -241,20 +241,22 @@ namespace Barotrauma public static bool CircleIntersectsRectangle(Vector2 circlePos, float radius, Rectangle rect) { - Vector2 circleDistance = new Vector2(Math.Abs(circlePos.X - rect.Center.X), Math.Abs(circlePos.Y -rect.Center.Y)); + float xDist = Math.Abs(circlePos.X - rect.Center.X); + int halfWidth = rect.Width / 2; - if (circleDistance.X > (rect.Width / 2 + radius)) { return false; } - if (circleDistance.Y > (rect.Height / 2 + radius)) { return false; } + if (xDist > (halfWidth + radius)) { return false; } + if (xDist <= (halfWidth)) { return true; } - if (circleDistance.X <= (rect.Width / 2)) { return true; } - if (circleDistance.Y <= (rect.Height / 2)) { return true; } + float yDist = Math.Abs(circlePos.Y - rect.Center.Y); + int halfHeight = rect.Height / 2; - float distSqX = circleDistance.X - rect.Width / 2; - float distSqY = circleDistance.Y - rect.Height / 2; + if (yDist > (halfHeight + radius)) { return false; } + if (yDist <= (halfHeight)) { return true; } - float cornerDistanceSq = distSqX * distSqX + distSqY * distSqY; + float distSqX = xDist - halfWidth; + float distSqY = yDist - halfHeight; - return (cornerDistanceSq <= (radius * radius)); + return (distSqX * distSqX + distSqY * distSqY <= (radius * radius)); } /// From 17197a442d47e0448444855d9a5bf2b8a69a5662 Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 30 Jun 2016 18:37:10 +0300 Subject: [PATCH 11/13] Water can flow through vertical docking ports --- .../Source/Items/Components/DockingPort.cs | 31 ++++++++++++++++--- Subsurface/Source/Map/Gap.cs | 12 +++---- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index 43c5bda4f..6e73fe062 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -221,7 +221,20 @@ namespace Barotrauma.Items.Components } } - gap = new Gap(new Rectangle(hullRects[0].Right-2, hullRects[0].Y, 4, hullRects[0].Height), true, subs[0]); + gap = new Gap(new Rectangle(hullRects[0].Right - 2, hullRects[0].Y, 4, hullRects[0].Height), true, subs[0]); + + gap.linkedTo.Clear(); + if (hulls[0].WorldRect.X < hulls[1].WorldRect.X) + { + gap.linkedTo.Add(hulls[0]); + gap.linkedTo.Add(hulls[1]); + } + else + { + gap.linkedTo.Add(hulls[1]); + gap.linkedTo.Add(hulls[0]); + } + } else @@ -249,13 +262,21 @@ namespace Barotrauma.Items.Components //} } - gap = new Gap(new Rectangle(hullRects[0].X, hullRects[0].Y+2, hullRects[0].Width, 4), true, subs[0]); + gap = new Gap(new Rectangle(hullRects[0].X, hullRects[0].Y+2, hullRects[0].Width, 4), false, subs[0]); + gap.linkedTo.Clear(); + if (hulls[0].WorldRect.Y > hulls[1].WorldRect.Y) + { + gap.linkedTo.Add(hulls[0]); + gap.linkedTo.Add(hulls[1]); + } + else + { + gap.linkedTo.Add(hulls[1]); + gap.linkedTo.Add(hulls[0]); + } } - gap.linkedTo.Clear(); - gap.linkedTo.Add(hulls[0]); - gap.linkedTo.Add(hulls[1]); foreach (Body body in bodies) { diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index a908aed27..7c266cac7 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -434,11 +434,11 @@ namespace Barotrauma else { //lower room is full of water - if (hull2.Pressure > hull1.Pressure) + if ((hull2.Pressure + subOffset.Y) > hull1.Pressure) { float delta = Math.Min(hull2.Volume - hull2.FullVolume + Hull.MaxCompress / 2.0f, deltaTime * 8000.0f * sizeModifier); - flowForce = new Vector2(0.0f, Math.Min(hull2.Pressure - hull1.Pressure, 500.0f)); + flowForce = new Vector2(0.0f, Math.Min((hull2.Pressure + subOffset.Y) - hull1.Pressure, 500.0f)); delta = Math.Max(delta, 0.0f); hull1.Volume += delta; @@ -448,7 +448,7 @@ namespace Barotrauma if (hull1.Volume > hull1.FullVolume) { - hull1.Pressure = Math.Max(hull1.Pressure, (hull1.Pressure + hull2.Pressure) / 2); + hull1.Pressure = Math.Max(hull1.Pressure, (hull1.Pressure + (hull2.Pressure + subOffset.Y)) / 2); } } @@ -461,16 +461,16 @@ namespace Barotrauma float delta = Math.Min(hull1.Volume, deltaTime * 25000f * sizeModifier); //make sure not to place more water to the target room than it can hold delta = Math.Min(delta, (hull2.FullVolume + Math.Max(hull1.Volume - hull1.FullVolume, 0.0f)) - hull2.Volume + Hull.MaxCompress / 4.0f); - + hull1.Volume -= delta; hull2.Volume += delta; if (hull2.Volume > hull2.FullVolume) { - hull2.Pressure = Math.Max(hull2.Pressure, (hull1.Pressure + hull2.Pressure) / 2); + hull2.Pressure = Math.Max(hull2.Pressure, ((hull1.Pressure - subOffset.Y) + hull2.Pressure) / 2); } - flowForce = new Vector2(0.0f,-delta); + flowForce = new Vector2(0.0f, -delta); flowForce.X = hull1.WaveY[hull1.GetWaveIndex(rect.X)] - hull1.WaveY[hull1.GetWaveIndex(rect.Right)] * 10.0f; From cafeceb6d216e518a398aaa318b05af0a88f0d64 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 2 Jul 2016 14:59:49 +0300 Subject: [PATCH 12/13] WIP dockingport/multisub saving in single player mode --- Subsurface/Barotrauma.csproj | 2 +- .../GameSession/GameModes/SinglePlayerMode.cs | 35 +- .../Source/Items/Components/DockingPort.cs | 26 +- Subsurface/Source/Map/LinkedSubmarine.cs | 308 ++++++++++++++++++ Subsurface/Source/Map/MapEntity.cs | 1 - Subsurface/Source/Map/Submarine.cs | 52 +-- Subsurface/Source/Map/SubmarineLink.cs | 171 ---------- Subsurface/Source/Utils/SaveUtil.cs | 7 +- 8 files changed, 402 insertions(+), 200 deletions(-) create mode 100644 Subsurface/Source/Map/LinkedSubmarine.cs delete mode 100644 Subsurface/Source/Map/SubmarineLink.cs diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 09cabeebc..44af133a5 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -144,7 +144,7 @@ - + diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index db0c3801d..ce0f38c7f 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -53,7 +53,7 @@ namespace Barotrauma endShiftButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 220, 20, 200, 25), "End shift", Alignment.TopLeft, GUI.Style); endShiftButton.Font = GUI.SmallFont; - endShiftButton.OnClicked = EndShift; + endShiftButton.OnClicked = TryEndShift; for (int i = 0; i < 3; i++) { @@ -236,6 +236,39 @@ namespace Barotrauma Submarine.Unload(); } + private bool TryEndShift(GUIButton button, object obj) + { + int subsNotDocked = Submarine.Loaded.Count(s => s != Submarine.MainSub && !s.DockedTo.Contains(Submarine.MainSub)); + + if (subsNotDocked > 0) + { + string msg = ""; + if (subsNotDocked == 1) + { + msg = "One of of your vessels hasn't been docked to " + Submarine.MainSub.Name + + ". If you leave now, you will permanently lose it." + + " Do you want to leave the vessel behind?"; + } + else + { + msg = "Some of of your vessels hasn't been docked to " + Submarine.MainSub.Name + + ". If you leave now, you will permanently lose them." + + " Do you want to leave the vessels behind?"; + } + + var msgBox = new GUIMessageBox("Warning", msg, new string[] {"Yes", "No"}); + msgBox.Buttons[0].OnClicked += EndShift; + msgBox.Buttons[0].OnClicked += msgBox.Close; + msgBox.Buttons[1].OnClicked += msgBox.Close; + } + else + { + EndShift(button, obj); + } + + return true; + } + private bool EndShift(GUIButton button, object obj) { isRunning = false; diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index 6e73fe062..83cd58e32 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -17,7 +17,7 @@ namespace Barotrauma.Items.Components class DockingPort : ItemComponent, IDrawableComponent { - private static List list = new List(); + public static List list = new List(); private Sprite overlaySprite; @@ -124,7 +124,7 @@ namespace Barotrauma.Items.Components if (adjacentPort != null) Dock(adjacentPort); } - private void Dock(DockingPort target) + public void Dock(DockingPort target) { if (dockingTarget != null) { @@ -133,9 +133,15 @@ namespace Barotrauma.Items.Components PlaySound(ActionType.OnUse, item.WorldPosition); + item.linkedTo.Add(target.item); + + if (!target.item.Submarine.DockedTo.Contains(item.Submarine)) target.item.Submarine.DockedTo.Add(item.Submarine); + if (!item.Submarine.DockedTo.Contains(target.item.Submarine)) item.Submarine.DockedTo.Add(target.item.Submarine); dockingTarget = target; dockingTarget.dockingTarget = this; + + docked = true; dockingTarget.Docked = true; if (Character.Controlled != null && @@ -296,6 +302,11 @@ namespace Barotrauma.Items.Components PlaySound(ActionType.OnUse, item.WorldPosition); + dockingTarget.item.Submarine.DockedTo.Remove(item.Submarine); + item.Submarine.DockedTo.Remove(dockingTarget.item.Submarine); + + item.linkedTo.Clear(); + docked = false; dockingTarget.Undock(); @@ -432,6 +443,17 @@ namespace Barotrauma.Items.Components list.Remove(this); } + public override void OnMapLoaded() + { + if (!item.linkedTo.Any()) return; + + Item linkedItem = item.linkedTo.First() as Item; + if (linkedItem == null) return; + + DockingPort port = linkedItem.GetComponent(); + if (port != null) Dock(port); + } + public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f) { switch (connection.Name) diff --git a/Subsurface/Source/Map/LinkedSubmarine.cs b/Subsurface/Source/Map/LinkedSubmarine.cs new file mode 100644 index 000000000..9488dc9d1 --- /dev/null +++ b/Subsurface/Source/Map/LinkedSubmarine.cs @@ -0,0 +1,308 @@ +using Barotrauma.Items.Components; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Barotrauma +{ + + class LinkedSubmarinePrefab : MapEntityPrefab + { + public readonly Submarine mainSub; + + public LinkedSubmarinePrefab(Submarine submarine) + { + this.mainSub = submarine; + } + + protected override void CreateInstance(Rectangle rect) + { + System.Diagnostics.Debug.Assert(Submarine.MainSub != null); + + LinkedSubmarine.Create(Submarine.MainSub, mainSub.FilePath, rect.Location.ToVector2()); + } + } + + class LinkedSubmarine : MapEntity + { + private List wallVertices; + + private string filePath; + + private Submarine sub; + + private XElement saveElement; + + public override bool IsLinkable + { + get + { + return true; + } + } + + public LinkedSubmarine(Submarine submarine) + : base(null, submarine) + { + linkedTo = new System.Collections.ObjectModel.ObservableCollection(); + linkedToID = new List(); + + InsertToList(); + } + + public static LinkedSubmarine Create(Submarine mainSub, string filePath, Vector2 position) + { + LinkedSubmarine sl = new LinkedSubmarine(mainSub); + sl.filePath = filePath; + + XDocument doc = Submarine.OpenFile(filePath); + if (doc == null || doc.Root == null) return null; + + sl.GenerateWallVertices(doc.Root); + + //for (int i = 0; i < sl.wallVertices.Count; i++) + //{ + // sl.wallVertices[i] = sl.wallVertices[i] += position; + //} + + sl.Rect = new Rectangle( + (int)sl.wallVertices.Min(v => v.X + position.X), + (int)sl.wallVertices.Max(v => v.Y + position.Y), + (int)sl.wallVertices.Max(v => v.X + position.X), + (int)sl.wallVertices.Min(v => v.Y + position.Y)); + + sl.rect = new Rectangle(sl.rect.X, sl.rect.Y, sl.rect.Width - sl.rect.X, sl.rect.Y - sl.rect.Height); + + return sl; + } + + public override bool IsMouseOn(Vector2 position) + { + return Vector2.Distance(position, WorldPosition) < 50.0f; + } + + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) + { + if (!editing || wallVertices == null) return; + + Color color = (isHighlighted) ? Color.Orange : Color.Green; + if (isSelected) color = Color.Red; + + Vector2 pos = new Vector2(rect.X + rect.Width/2, rect.Y - rect.Height/2); + + for (int i = 0; i < wallVertices.Count; i++) + { + Vector2 startPos = wallVertices[i] + pos; + startPos.Y = -startPos.Y; + + Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos; + endPos.Y = -endPos.Y; + + GUI.DrawLine(spriteBatch, + startPos, + endPos, + color, 0.0f, 5); + } + + pos.Y = -pos.Y; + GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color, 0.0f, 5); + GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color, 0.0f, 5); + + + foreach (MapEntity e in linkedTo) + { + GUI.DrawLine(spriteBatch, + new Vector2(WorldPosition.X, -WorldPosition.Y), + new Vector2(e.WorldPosition.X, -e.WorldPosition.Y), + Color.Red * 0.3f); + } + } + + public override void DrawEditing(SpriteBatch spriteBatch, Camera cam) + { + if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this) + { + editingHUD = CreateEditingHUD(); + } + + editingHUD.Draw(spriteBatch); + editingHUD.Update((float)Physics.step); + + if (!PlayerInput.LeftButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) return; + + Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); + + foreach (MapEntity entity in mapEntityList) + { + if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) continue; + if (((Item)entity).GetComponent() == null) continue; + if (linkedTo.Contains(entity)) + { + linkedTo.Remove(entity); + } + else + { + linkedTo.Add(entity); + } + } + } + + + private GUIComponent CreateEditingHUD(bool inGame = false) + { + int width = 450; + int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10; + + editingHUD = new GUIFrame(new Rectangle(x, y, width, 100), GUI.Style); + editingHUD.Padding = new Vector4(10, 10, 0, 0); + editingHUD.UserData = this; + + new GUITextBlock(new Rectangle(0, 0, 100, 20), "Linked submarine", GUI.Style, + Alignment.TopLeft, Alignment.TopLeft, editingHUD, false, GUI.LargeFont); + + y += 20; + + if (!inGame) + { + new GUITextBlock(new Rectangle(0, 0, 0, 20), "Hold space to link to a docking port", + GUI.Style, Alignment.TopRight, Alignment.TopRight, editingHUD).Font = GUI.SmallFont; + y += 25; + + } + return editingHUD; + } + + + private void GenerateWallVertices(XElement rootElement) + { + List points = new List(); + + var wallPrefabs = + MapEntityPrefab.list.FindAll(mp => (mp is StructurePrefab) && ((StructurePrefab)mp).HasBody); + + foreach (XElement element in rootElement.Elements()) + { + if (element.Name != "Structure") continue; + + string name = ToolBox.GetAttributeString(element, "name", ""); + if (!wallPrefabs.Any(wp => wp.Name == name)) continue; + + var rect = ToolBox.GetAttributeVector4(element, "rect", Vector4.Zero); + + points.Add(new Vector2(rect.X, rect.Y)); + points.Add(new Vector2(rect.X + rect.Z, rect.Y)); + points.Add(new Vector2(rect.X, rect.Y - rect.W)); + points.Add(new Vector2(rect.X + rect.Z, rect.Y - rect.W)); + } + + wallVertices = MathUtils.GiftWrap(points); + } + + public override XElement Save(XElement parentElement) + { + XElement saveElement = null; + + if (sub == null) + { + var doc = Submarine.OpenFile(filePath); + saveElement = doc.Root; + + saveElement.Name = "LinkedSubmarine"; + + saveElement.Add(new XAttribute("filepath", filePath)); + + var linkedPort = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); + if (linkedPort != null) + { + saveElement.Add(new XAttribute("linkedto", linkedPort.ID)); + } + } + else + { + saveElement = new XElement("LinkedSubmarine"); + + sub.SaveToXElement(saveElement); + } + + saveElement.Add(new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); + + parentElement.Add(saveElement); + + return saveElement; + } + + public static void Load(XElement element, Submarine submarine) + { + Vector2 pos = ToolBox.GetAttributeVector2(element, "pos", Vector2.Zero); + + LinkedSubmarine linkedSub = null; + + if (Screen.Selected == GameMain.EditMapScreen) + { + string filePath = ToolBox.GetAttributeString(element, "filepath", ""); + + linkedSub = Create(submarine, filePath, pos); + } + else + { + linkedSub = new LinkedSubmarine(submarine); + linkedSub.saveElement = element; + + linkedSub.rect.Location = pos.ToPoint(); + } + + string linkedToString = ToolBox.GetAttributeString(element, "linkedto", ""); + if (linkedToString != "") + { + string[] linkedToIds = linkedToString.Split(','); + for (int i = 0; i < linkedToIds.Length; i++) + { + linkedSub.linkedToID.Add((ushort)int.Parse(linkedToIds[i])); + } + } + + } + + public override void OnMapLoaded() + { + if (saveElement == null) return; + + sub = Submarine.Load(saveElement, false); + sub.SetPosition(WorldPosition - Submarine.WorldPosition); + sub.Submarine = Submarine; + + var linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); + + if (linkedItem != null) + { + var linkedPort = ((Item)linkedItem).GetComponent(); + + DockingPort myPort = null; + float closestDistance = 0.0f; + + foreach (DockingPort port in DockingPort.list) + { + if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal) continue; + + float dist = Vector2.Distance(port.Item.WorldPosition, linkedPort.Item.WorldPosition); + if (myPort == null || dist < closestDistance) + { + myPort = port; + closestDistance = dist; + } + } + + if (myPort != null) + { + myPort.Dock(linkedPort); + } + } + } + } +} diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 958655ce0..f079fb7d9 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -620,7 +620,6 @@ namespace Barotrauma foreach (ushort i in e.linkedToID) { MapEntity linked = FindEntityByID(i) as MapEntity; - Debug.Assert(linked.Submarine == sub); if (linked != null) e.linkedTo.Add(linked); } diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 09f5b97c5..cc0d87b10 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -46,10 +46,12 @@ namespace Barotrauma private SubmarineBody subBody; + public readonly List DockedTo; + private static Vector2 lastPickedPosition; private static float lastPickedFraction; - Md5Hash hash; + private Md5Hash hash; private string filePath; private string name; @@ -57,8 +59,7 @@ namespace Barotrauma private Vector2 prevPosition; private float lastNetworkUpdate; - - + //properties ---------------------------------------------------- public string Name @@ -231,6 +232,8 @@ namespace Barotrauma } } + DockedTo = new List(); + ID = ushort.MaxValue; base.Remove(); @@ -538,14 +541,7 @@ namespace Barotrauma name = System.IO.Path.GetFileNameWithoutExtension(filePath); XDocument doc = new XDocument(new XElement("Submarine")); - doc.Root.Add(new XAttribute("name", name)); - doc.Root.Add(new XAttribute("description", Description == null ? "" : Description)); - - foreach (MapEntity e in MapEntity.mapEntityList) - { - if (e.MoveWithLevel ||e.Submarine != this) continue; - e.Save(doc.Root); - } + SaveToXElement(doc.Root); hash = new Md5Hash(doc); doc.Root.Add(new XAttribute("md5hash", hash.Hash)); @@ -563,6 +559,18 @@ namespace Barotrauma return true; } + public void SaveToXElement(XElement element) + { + element.Add(new XAttribute("name", name)); + element.Add(new XAttribute("description", Description == null ? "" : Description)); + + foreach (MapEntity e in MapEntity.mapEntityList) + { + if (e.MoveWithLevel || e.Submarine != this) continue; + e.Save(element); + } + } + public static bool SaveCurrent(string filePath) { if (Submarine.MainSub == null) @@ -853,7 +861,7 @@ namespace Barotrauma GameMain.LightManager.OnMapLoaded(); - ID = (ushort)(ushort.MaxValue - Submarine.loaded.Count); + ID = (ushort)(ushort.MaxValue - Submarine.loaded.IndexOf(this)); } public static Submarine Load(XElement element, bool unloadPrevious) @@ -862,7 +870,7 @@ namespace Barotrauma //tryload -> false - Submarine sub = new Submarine(ToolBox.GetAttributeString(element, "name", "")); + Submarine sub = new Submarine(ToolBox.GetAttributeString(element, "name", ""), "", false); sub.Load(unloadPrevious, element); return sub; @@ -898,27 +906,29 @@ namespace Barotrauma foreach (Submarine sub in loaded) { sub.Remove(); - sub.Clear(); } loaded.Clear(); - } - private void Clear() - { if (GameMain.GameScreen.Cam != null) GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; Entity.RemoveAll(); - - subBody = null; - - PhysicsBody.list.Clear(); + PhysicsBody.list.Clear(); + Ragdoll.list.Clear(); GameMain.World.Clear(); } + public override void Remove() + { + base.Remove(); + + subBody = null; + + DockedTo.Clear(); + } } } diff --git a/Subsurface/Source/Map/SubmarineLink.cs b/Subsurface/Source/Map/SubmarineLink.cs deleted file mode 100644 index 68f671656..000000000 --- a/Subsurface/Source/Map/SubmarineLink.cs +++ /dev/null @@ -1,171 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; - -namespace Barotrauma -{ - - class LinkedSubmarinePrefab : MapEntityPrefab - { - public readonly Submarine mainSub; - - public LinkedSubmarinePrefab(Submarine submarine) - { - this.mainSub = submarine; - } - - protected override void CreateInstance(Rectangle rect) - { - System.Diagnostics.Debug.Assert(Submarine.MainSub != null); - - LinkedSubmarine.Create(Submarine.MainSub, mainSub.FilePath, rect.Location.ToVector2()); - } - } - - class LinkedSubmarine : MapEntity - { - private List wallVertices; - - private string filePath; - - private XElement saveElement; - - public LinkedSubmarine(Submarine submarine) - : base(null, submarine) - { - InsertToList(); - } - - public static LinkedSubmarine Create(Submarine mainSub, string filePath, Vector2 position) - { - LinkedSubmarine sl = new LinkedSubmarine(mainSub); - sl.filePath = filePath; - - XDocument doc = Submarine.OpenFile(filePath); - if (doc == null || doc.Root == null) return null; - - sl.GenerateWallVertices(doc.Root); - - //for (int i = 0; i < sl.wallVertices.Count; i++) - //{ - // sl.wallVertices[i] = sl.wallVertices[i] += position; - //} - - sl.Rect = new Rectangle( - (int)sl.wallVertices.Min(v => v.X + position.X), - (int)sl.wallVertices.Max(v => v.Y + position.Y), - (int)sl.wallVertices.Max(v => v.X + position.X), - (int)sl.wallVertices.Min(v => v.Y + position.Y)); - - sl.rect = new Rectangle(sl.rect.X, sl.rect.Y, sl.rect.Width - sl.rect.X, sl.rect.Y - sl.rect.Height); - - return sl; - } - - public override bool IsMouseOn(Vector2 position) - { - return Vector2.Distance(position, WorldPosition) < 50.0f; - } - - public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) - { - if (!editing || wallVertices == null) return; - - Color color = (isHighlighted) ? Color.Orange : Color.Green; - if (isSelected) color = Color.Red; - - Vector2 pos = new Vector2(rect.X + rect.Width/2, rect.Y - rect.Height/2); - - for (int i = 0; i < wallVertices.Count; i++) - { - Vector2 startPos = wallVertices[i] + pos; - startPos.Y = -startPos.Y; - - Vector2 endPos = wallVertices[(i + 1) % wallVertices.Count] + pos; - endPos.Y = -endPos.Y; - - GUI.DrawLine(spriteBatch, - startPos, - endPos, - color, 0.0f, 5); - } - - pos.Y = -pos.Y; - GUI.DrawLine(spriteBatch, pos + Vector2.UnitY * 50.0f, pos - Vector2.UnitY * 50.0f, color, 0.0f, 5); - GUI.DrawLine(spriteBatch, pos + Vector2.UnitX * 50.0f, pos - Vector2.UnitX * 50.0f, color, 0.0f, 5); - - } - - private void GenerateWallVertices(XElement rootElement) - { - List points = new List(); - - var wallPrefabs = - MapEntityPrefab.list.FindAll(mp => (mp is StructurePrefab) && ((StructurePrefab)mp).HasBody); - - foreach (XElement element in rootElement.Elements()) - { - if (element.Name != "Structure") continue; - - string name = ToolBox.GetAttributeString(element, "name", ""); - if (!wallPrefabs.Any(wp => wp.Name == name)) continue; - - var rect = ToolBox.GetAttributeVector4(element, "rect", Vector4.Zero); - - points.Add(new Vector2(rect.X, rect.Y)); - points.Add(new Vector2(rect.X + rect.Z, rect.Y)); - points.Add(new Vector2(rect.X, rect.Y - rect.W)); - points.Add(new Vector2(rect.X + rect.Z, rect.Y - rect.W)); - } - - wallVertices = MathUtils.GiftWrap(points); - } - - public override XElement Save(XElement parentElement) - { - var doc = Submarine.OpenFile(filePath); - - doc.Root.Name = "LinkedSubmarine"; - - doc.Root.Add( - new XAttribute("filepath", filePath), - new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); - - parentElement.Add(doc.Root); - - return doc.Root; - } - - public static void Load(XElement element, Submarine submarine) - { - Vector2 pos = ToolBox.GetAttributeVector2(element, "pos", Vector2.Zero); - - if (Screen.Selected == GameMain.EditMapScreen) - { - string filePath = ToolBox.GetAttributeString(element, "filepath", ""); - - Create(submarine, filePath, pos); - - return; - } - - var ls = new LinkedSubmarine(submarine); - ls.saveElement = element; - - ls.rect.Location = pos.ToPoint(); - } - - public override void OnMapLoaded() - { - if (saveElement == null) return; - var sub = Submarine.Load(saveElement, false); - sub.SetPosition(WorldPosition - Submarine.WorldPosition); - sub.Submarine = Submarine; - } - } -} diff --git a/Subsurface/Source/Utils/SaveUtil.cs b/Subsurface/Source/Utils/SaveUtil.cs index cf4f714d1..154857dae 100644 --- a/Subsurface/Source/Utils/SaveUtil.cs +++ b/Subsurface/Source/Utils/SaveUtil.cs @@ -23,12 +23,13 @@ namespace Barotrauma string tempPath = Path.Combine(SaveFolder, "temp"); - if (!Directory.Exists(tempPath)) + if (Directory.Exists(tempPath)) { - Directory.CreateDirectory(tempPath); + Directory.Delete(tempPath, true); } + Directory.CreateDirectory(tempPath); - try + try { if (Submarine.MainSub != null) { From e74d5adef4f49446eeebdb36c09b46bbd5491b33 Mon Sep 17 00:00:00 2001 From: Regalis Date: Mon, 4 Jul 2016 17:31:07 +0300 Subject: [PATCH 13/13] Subs that aren't docked to the main sub aren't saved --- Subsurface/Source/Map/LinkedSubmarine.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Subsurface/Source/Map/LinkedSubmarine.cs b/Subsurface/Source/Map/LinkedSubmarine.cs index 9488dc9d1..90286dfb0 100644 --- a/Subsurface/Source/Map/LinkedSubmarine.cs +++ b/Subsurface/Source/Map/LinkedSubmarine.cs @@ -225,8 +225,10 @@ namespace Barotrauma } else { - saveElement = new XElement("LinkedSubmarine"); + if (!sub.DockedTo.Contains(Submarine.MainSub)) return null; + saveElement = new XElement("LinkedSubmarine"); + sub.SaveToXElement(saveElement); }