From f8fec7978502c4878b9936c5fdff45c4ed5fb4fa Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 16 Jul 2016 16:14:51 +0300 Subject: [PATCH] Parts of the submarine that are left behind in the level will stay there, it's possible to leave the level without the main sub (e.g. in an escape shuttle) --- .../GameSession/GameModes/SinglePlayerMode.cs | 22 ++++++- Subsurface/Source/GameSession/GameSession.cs | 3 +- Subsurface/Source/Map/LinkedSubmarine.cs | 62 ++++++++++++++++--- Subsurface/Source/Map/Submarine.cs | 1 + Subsurface/Source/Map/SubmarineBody.cs | 5 +- Subsurface/Source/Sounds/SoundPlayer.cs | 2 +- Subsurface/Source/Utils/SaveUtil.cs | 6 +- 7 files changed, 87 insertions(+), 14 deletions(-) diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index ce0f38c7f..f88e4b74d 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -145,12 +145,12 @@ namespace Barotrauma if (Submarine.MainSub == null) return; - if (Submarine.MainSub.AtEndPosition) + if (Submarine.Loaded.Any(s=> s.AtEndPosition)) { endShiftButton.Text = "Enter " + Map.SelectedLocation.Name; endShiftButton.Draw(spriteBatch); } - else if (Submarine.MainSub.AtStartPosition) + else if (Submarine.Loaded.Any(s => s.AtStartPosition)) { endShiftButton.Text = "Enter " + Map.CurrentLocation.Name; endShiftButton.Draw(spriteBatch); @@ -204,6 +204,24 @@ namespace Barotrauma Map.MoveToNextLocation(); } + if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) + { + Submarine newMainSub = Submarine.Loaded.Find(s => s.AtEndPosition || s.AtStartPosition); + Submarine oldMainSub = Submarine.MainSub; + Submarine.MainSub = newMainSub; + + GameMain.GameSession.Submarine = newMainSub; + + List subsToLeaveBehind = Submarine.Loaded.FindAll(s => s != Submarine.MainSub && !Submarine.MainSub.DockedTo.Contains(s)); + + foreach (Submarine sub in subsToLeaveBehind) + { + MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); + LinkedSubmarine.CreateDummy(newMainSub, sub); + } + } + + SaveUtil.SaveGame(GameMain.GameSession.SaveFile); } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index 27794163d..eaac483c1 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -54,6 +54,7 @@ namespace Barotrauma public Submarine Submarine { get { return submarine; } + set { submarine = value; } } public string SaveFile @@ -124,7 +125,7 @@ namespace Barotrauma DebugConsole.ThrowError("Couldn't start game session, submarine not selected"); return; } - + if (reloadSub || Submarine.MainSub != submarine) submarine.Load(true); Submarine.MainSub = submarine; diff --git a/Subsurface/Source/Map/LinkedSubmarine.cs b/Subsurface/Source/Map/LinkedSubmarine.cs index c5437ae16..68e3ec05e 100644 --- a/Subsurface/Source/Map/LinkedSubmarine.cs +++ b/Subsurface/Source/Map/LinkedSubmarine.cs @@ -36,6 +36,7 @@ namespace Barotrauma private string filePath; + private bool loadSub; private Submarine sub; private XElement saveElement; @@ -56,6 +57,14 @@ namespace Barotrauma InsertToList(); } + + public static LinkedSubmarine CreateDummy(Submarine mainSub, Submarine linkedSub) + { + LinkedSubmarine sl = new LinkedSubmarine(mainSub); + sl.sub = linkedSub; + + return sl; + } public static LinkedSubmarine CreateDummy(Submarine mainSub, string filePath, Vector2 position) { @@ -280,15 +289,32 @@ namespace Barotrauma } else { - if (!sub.DockedTo.Contains(Submarine.MainSub)) return null; saveElement = new XElement("LinkedSubmarine"); - + + sub.SaveToXElement(saveElement); } + + if (sub != null) + { + if (!sub.DockedTo.Contains(Submarine.MainSub)) + { + saveElement.Add(new XAttribute("location", Level.Loaded.Seed)); + saveElement.Add(new XAttribute("worldpos", ToolBox.Vector2ToString(sub.SubBody.Position))); + + } + else + { + if (saveElement.Attribute("location") != null) saveElement.Attribute("location").Remove(); + if (saveElement.Attribute("worldpos") != null) saveElement.Attribute("worldpos").Remove(); + } - if (saveElement.Attribute("pos") != null) saveElement.Attribute("pos").Remove(); - saveElement.Add(new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); + if (saveElement.Attribute("pos") != null) saveElement.Attribute("pos").Remove(); + saveElement.Add(new XAttribute("pos", ToolBox.Vector2ToString(Position - Submarine.HiddenSubPosition))); + } + + parentElement.Add(saveElement); @@ -313,6 +339,15 @@ namespace Barotrauma linkedSub = new LinkedSubmarine(submarine); linkedSub.saveElement = element; + string levelSeed = ToolBox.GetAttributeString(element, "location", ""); + if (!string.IsNullOrWhiteSpace(levelSeed) && GameMain.GameSession.Level != null && GameMain.GameSession.Level.Seed != levelSeed) + { + linkedSub.loadSub = false; + return; + } + + linkedSub.loadSub = true; + linkedSub.rect.Location = pos.ToPoint(); } @@ -332,11 +367,22 @@ namespace Barotrauma public override void OnMapLoaded() { - if (Screen.Selected == GameMain.EditMapScreen) return; + if (!loadSub) return; - sub = Submarine.Load(saveElement, false); - sub.SetPosition(WorldPosition - Submarine.WorldPosition); - sub.Submarine = Submarine; + sub = Submarine.Load(saveElement, false); + + Vector2 worldPos = ToolBox.GetAttributeVector2(saveElement, "worldpos", Vector2.Zero); + if (worldPos != Vector2.Zero) + { + sub.SetPosition(worldPos); + } + else + { + sub.SetPosition(WorldPosition - Submarine.WorldPosition); + sub.Submarine = Submarine; + } + + var linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null); diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 8715664e2..a3988789c 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -191,6 +191,7 @@ namespace Barotrauma public string FilePath { get { return filePath; } + set { filePath = value; } } public bool AtDamageDepth diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index 633074961..f63bf7021 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -390,7 +390,10 @@ namespace Barotrauma damagePos += submarine.Position + submarine.HiddenSubPosition; SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f, damagePos, 10000.0f); - GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f; + if (Character.Controlled != null && Character.Controlled.Submarine == submarine) + { + GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f; + } Explosion.RangedStructureDamage(damagePos, depth * PressureDamageMultiplier * 50.0f, depth * PressureDamageMultiplier); //SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, Rand.Range(0.0f, 100.0f), damagePos, 5000.0f); diff --git a/Subsurface/Source/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs index 5266dbf48..a48e0d3e4 100644 --- a/Subsurface/Source/Sounds/SoundPlayer.cs +++ b/Subsurface/Source/Sounds/SoundPlayer.cs @@ -346,7 +346,7 @@ namespace Barotrauma { Vector2 bodyPosition = body.DrawPosition; - PlayDamageSound(damageType, damage, bodyPosition); + PlayDamageSound(damageType, damage, bodyPosition, 800.0f); } public static void PlayDamageSound(DamageSoundType damageType, float damage, Vector2 position, float range = 2000.0f) diff --git a/Subsurface/Source/Utils/SaveUtil.cs b/Subsurface/Source/Utils/SaveUtil.cs index 154857dae..58d9b48a1 100644 --- a/Subsurface/Source/Utils/SaveUtil.cs +++ b/Subsurface/Source/Utils/SaveUtil.cs @@ -31,9 +31,13 @@ namespace Barotrauma try { + + + if (Submarine.MainSub != null) { - Submarine.MainSub.SaveAs(Path.Combine(tempPath, Submarine.MainSub.Name+".sub")); + Submarine.MainSub.FilePath = Path.Combine(tempPath, Submarine.MainSub.Name + ".sub"); + Submarine.MainSub.SaveAs(Submarine.MainSub.FilePath); } } catch (Exception e)