diff --git a/Subsurface/Content/Characters/Moloch/moloch.xml b/Subsurface/Content/Characters/Moloch/moloch.xml index c375b9689..bd7ebcbce 100644 --- a/Subsurface/Content/Characters/Moloch/moloch.xml +++ b/Subsurface/Content/Characters/Moloch/moloch.xml @@ -11,7 +11,7 @@ - + diff --git a/Subsurface/Content/Items/Medical/medical.xml b/Subsurface/Content/Items/Medical/medical.xml index 439778e0f..92edcca1d 100644 --- a/Subsurface/Content/Items/Medical/medical.xml +++ b/Subsurface/Content/Items/Medical/medical.xml @@ -51,7 +51,8 @@ name="Iron Powder" category="Material" Tags="smallitem,chem" - pickdistance="150"> + pickdistance="150" + price="5"> @@ -66,7 +67,8 @@ spritecolor="1.0,1.0,0.7,1.0" Tags="smallitem,chem,medical" pickdistance="150" - description="A mild stimulant which is used as an incredient in the manufacture of various medicines."> + description="A mild stimulant which is used as an incredient in the manufacture of various medicines." + price="10"> @@ -91,7 +93,8 @@ Tags="smallitem,chem,medical" pickdistance="150" canuseonself="true" - description="Most commonly used for treating oxygen deprivation."> + description="Most commonly used for treating oxygen deprivation." + price="50"> @@ -111,7 +114,8 @@ Tags="smallitem,chem,medical" pickdistance="150" canuseonself="true" - description="A hemostatic agent that slows down bleeding."> + description="A hemostatic agent that slows down bleeding." + price="50"> @@ -136,7 +140,8 @@ Tags="smallitem,chem,medical" pickdistance="150" canuseonself="true" - description="Highly effective at treating various types of physical trauma."> + description="Highly effective at treating various types of physical trauma." + price="50"> @@ -160,7 +165,8 @@ spritecolor="1.0,1.0,0.0,1.0" Tags="smallitem,chem,medical" pickdistance="150" - description="A highly potent corrigodone-based stimulant."> + description="A highly potent corrigodone-based stimulant." + price="150"> @@ -178,7 +184,8 @@ category="Material" spritecolor="1.0,1.0,1.0,0.6" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="20"> @@ -197,7 +204,8 @@ spritecolor="0.0,0.9,0.1,1.0" Tags="smallitem,chem,medical" canuseonself="true" - pickdistance="150"> + pickdistance="150" + price="20"> @@ -220,7 +228,8 @@ category="Material" spritecolor="0.7,0.7,0.7,1.0" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="20"> @@ -238,7 +247,8 @@ category="Material" spritecolor="0.8,0.8,0.8,1.0" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="20"> @@ -256,7 +266,8 @@ category="Material" spritecolor="0.1,0.1,0.1,1.0" Tags="smallitem,chem,explosive" - pickdistance="150"> + pickdistance="150" + price="50"> @@ -276,7 +287,8 @@ category="Material" spritecolor="1.0,1.0,1.0,0.8" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="20"> @@ -294,7 +306,8 @@ category="Material" spritecolor="0.5,0.0,0.0,1.0" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="20"> @@ -312,7 +325,8 @@ category="Material" spritecolor="0.5,0.0,0.0,1.0" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="50"> @@ -330,7 +344,8 @@ category="Material" spritecolor="0.2,0.35,0.06,1.0" Tags="smallitem,chem,medical" - pickdistance="150"> + pickdistance="150" + price="50"> @@ -349,7 +364,8 @@ spritecolor="0.8,0.3,0.8,1.0" Tags="smallitem,chem,medical" pickdistance="150" - description="A potent muscle stimulant."> + description="A potent muscle stimulant." + price="50"> @@ -368,7 +384,8 @@ spritecolor="0.0,0.0,0.0,1.0" Tags="smallitem,chem,medical" pickdistance="150" - description="A highly potent neurotoxin."> + description="A highly potent neurotoxin." + price="200"> @@ -387,7 +404,8 @@ spritecolor="0.0,0.0,0.0,1.0" Tags="smallitem,chem,medical" pickdistance="150" - description="Dormant eggs of the Europan lifeform colloquially referred to as 'husk parasite'."> + description="Dormant eggs of the Europan lifeform colloquially referred to as 'husk parasite'." + price="200"> @@ -406,7 +424,8 @@ spritecolor="0.0,0.0,0.0,1.0" Tags="smallitem,chem,medical" pickdistance="150" - description="An antiparasitic drug used in the treatment of husk parasite infections."> + description="An antiparasitic drug used in the treatment of husk parasite infections." + price="300"> diff --git a/Subsurface/Content/Items/Weapons/depthcharge.xml b/Subsurface/Content/Items/Weapons/depthcharge.xml index bdd2ef693..31f240caf 100644 --- a/Subsurface/Content/Items/Weapons/depthcharge.xml +++ b/Subsurface/Content/Items/Weapons/depthcharge.xml @@ -38,7 +38,7 @@ name="Depth Charge Shell" category="Misc" pickdistance="150" - price="50"> + price="200"> @@ -66,7 +66,7 @@ name="Nuclear Depth Charge" category="Misc" pickdistance="150" - price="50"> + price="500"> diff --git a/Subsurface/Content/Items/Weapons/railgun.xml b/Subsurface/Content/Items/Weapons/railgun.xml index 6e00a6e75..3540372e6 100644 --- a/Subsurface/Content/Items/Weapons/railgun.xml +++ b/Subsurface/Content/Items/Weapons/railgun.xml @@ -66,7 +66,7 @@ name="Railgun Shell" category="Misc" pickdistance="200" - price="100"> + price="200"> @@ -93,7 +93,7 @@ name="Nuclear Shell" category="Misc" pickdistance="200" - price="100"> + price="500"> diff --git a/Subsurface/Content/damageshader_opengl.xnb b/Subsurface/Content/damageshader_opengl.xnb new file mode 100644 index 000000000..7362ac53b Binary files /dev/null and b/Subsurface/Content/damageshader_opengl.xnb differ diff --git a/Subsurface/Data/ContentPackages/Vanilla 0.3.xml b/Subsurface/Data/ContentPackages/Vanilla 0.3.xml index 1d35a45ca..7f65c3b88 100644 --- a/Subsurface/Data/ContentPackages/Vanilla 0.3.xml +++ b/Subsurface/Data/ContentPackages/Vanilla 0.3.xml @@ -46,6 +46,7 @@ + diff --git a/Subsurface/Properties/AssemblyInfo.cs b/Subsurface/Properties/AssemblyInfo.cs index 019e0fc0a..8276e573b 100644 --- a/Subsurface/Properties/AssemblyInfo.cs +++ b/Subsurface/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.5.1.3")] -[assembly: AssemblyFileVersion("0.5.1.3")] +[assembly: AssemblyVersion("0.5.2.0")] +[assembly: AssemblyFileVersion("0.5.2.0")] diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs index 25c7d4022..c5099232b 100644 --- a/Subsurface/Source/Characters/AI/EnemyAIController.cs +++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs @@ -341,7 +341,7 @@ namespace Barotrauma { wallAttackPos = Vector2.Zero; limb.AttackTimer = 0.0f; - if (Vector2.Distance(limb.SimPosition, attackPosition)<5.0) coolDownTimer = attackCoolDown; + coolDownTimer = attackCoolDown; } } diff --git a/Subsurface/Source/ContentPackage.cs b/Subsurface/Source/ContentPackage.cs index f7d5bca65..b07b314ee 100644 --- a/Subsurface/Source/ContentPackage.cs +++ b/Subsurface/Source/ContentPackage.cs @@ -17,7 +17,7 @@ namespace Barotrauma Structure, Executable, LocationTypes, - LevelGenerationPresets, + LevelGenerationParameters, RandomEvents, Missions, BackgroundCreaturePrefabs, BackgroundSpritePrefabs diff --git a/Subsurface/Source/GUI/GUIComponent.cs b/Subsurface/Source/GUI/GUIComponent.cs index 70eaeddfb..dae94096f 100644 --- a/Subsurface/Source/GUI/GUIComponent.cs +++ b/Subsurface/Source/GUI/GUIComponent.cs @@ -286,9 +286,15 @@ namespace Barotrauma toolTipBlock.rect.Height = toolTipBlock.WrappedText.Split('\n').Length * 18; toolTipBlock.Color = Color.Black * 0.7f; toolTipBlock.userData = ToolTip; + } toolTipBlock.rect = new Rectangle(MouseOn.Rect.Center.X, MouseOn.rect.Bottom, toolTipBlock.rect.Width, toolTipBlock.rect.Height); + if (toolTipBlock.rect.Right > GameMain.GraphicsWidth - 10) + { + toolTipBlock.rect.Location -= new Point(toolTipBlock.rect.Right - (GameMain.GraphicsWidth - 10), 0); + } + toolTipBlock.Draw(spriteBatch); } diff --git a/Subsurface/Source/GUI/GUIListBox.cs b/Subsurface/Source/GUI/GUIListBox.cs index 21fc2f8ca..99e60be62 100644 --- a/Subsurface/Source/GUI/GUIListBox.cs +++ b/Subsurface/Source/GUI/GUIListBox.cs @@ -122,7 +122,7 @@ namespace Barotrauma } public GUIListBox(Rectangle rect, GUIStyle style, Alignment alignment, GUIComponent parent = null) - : this(rect, null, style, parent) + : this(rect, null, alignment, style, parent, false) { } diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index e36010d9c..f76525739 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -26,6 +26,11 @@ namespace Barotrauma private bool savedOnStart; + private List subsToLeaveBehind; + + private Submarine leavingSub; + private bool atEndPosition; + public override Mission Mission { get @@ -80,18 +85,28 @@ namespace Barotrauma public SinglePlayerMode(XElement element) : this(GameModePreset.list.Find(gm => gm.Name == "Single Player"), null) - { - string mapSeed = ToolBox.GetAttributeString(element, "mapseed", "a"); - - GenerateMap(mapSeed); - - Map.SetLocation(ToolBox.GetAttributeInt(element, "currentlocation", 0)); - + { foreach (XElement subElement in element.Elements()) { - if (subElement.Name.ToString().ToLowerInvariant() != "crew") continue; - - GameMain.GameSession.CrewManager = new CrewManager(subElement); + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "crew": + GameMain.GameSession.CrewManager = new CrewManager(subElement); + break; + case "map": + Map = Map.Load(subElement); + break; + } + } + + //backwards compatibility with older save files + if (Map==null) + { + string mapSeed = ToolBox.GetAttributeString(element, "mapseed", "a"); + + GenerateMap(mapSeed); + + Map.SetLocation(ToolBox.GetAttributeInt(element, "currentlocation", 0)); } savedOnStart = true; @@ -198,12 +213,6 @@ namespace Barotrauma } endShiftButton.Draw(spriteBatch); - //chatBox.Draw(spriteBatch); - //textBox.Draw(spriteBatch); - - //timerBar.Draw(spriteBatch); - - //if (Game1.Client == null) endShiftButton.Draw(spriteBatch); } public override void Update(float deltaTime) @@ -230,10 +239,17 @@ namespace Barotrauma public override void End(string endMessage = "") { - isRunning = false; - //if (endMessage != "" || this.endMessage == null) this.endMessage = endMessage; + if (subsToLeaveBehind == null || leavingSub == null) + { + DebugConsole.ThrowError("Leaving submarine not selected -> selecting the closest one"); + + leavingSub = GetLeavingSub(); + + subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); + } + bool success = CrewManager.characters.Any(c => !c.IsDead); @@ -241,19 +257,13 @@ namespace Barotrauma if (success) { - var leavingSub = GetLeavingSub(); - - if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) + if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { - System.Diagnostics.Debug.Assert(leavingSub != Submarine.MainSub); - Submarine oldMainSub = Submarine.MainSub; Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; - - List subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); - + foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); @@ -261,13 +271,11 @@ namespace Barotrauma } } - - if (Submarine.MainSub.AtEndPosition) + if (atEndPosition) { Map.MoveToNextLocation(); } - SaveUtil.SaveGame(GameMain.GameSession.SaveFile); } @@ -302,18 +310,18 @@ namespace Barotrauma private bool TryEndShift(GUIButton button, object obj) { - List subsNotDocked = new List(); - - var leavingSub = obj as Submarine; + leavingSub = obj as Submarine; if (leavingSub != null) { - subsNotDocked = GetSubsToLeaveBehind(leavingSub); + subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); } - if (subsNotDocked.Any()) + atEndPosition = leavingSub.AtEndPosition; + + if (subsToLeaveBehind.Any()) { string msg = ""; - if (subsNotDocked.Count==1) + if (subsToLeaveBehind.Count == 1) { msg = "One of your vessels isn't at the exit yet. Do you want to leave it behind?"; } @@ -325,7 +333,7 @@ namespace Barotrauma var msgBox = new GUIMessageBox("Warning", msg, new string[] {"Yes", "No"}); msgBox.Buttons[0].OnClicked += EndShift; msgBox.Buttons[0].OnClicked += msgBox.Close; - msgBox.Buttons[0].UserData = Submarine.Loaded.FindAll(s => !subsNotDocked.Contains(s)); + msgBox.Buttons[0].UserData = Submarine.Loaded.FindAll(s => !subsToLeaveBehind.Contains(s)); msgBox.Buttons[1].OnClicked += msgBox.Close; } @@ -343,7 +351,7 @@ namespace Barotrauma List leavingSubs = obj as List; if (leavingSubs == null) leavingSubs = new List() { GetLeavingSub() }; - + var cinematic = new TransitionCinematic(leavingSubs, GameMain.GameScreen.Cam, 5.0f); SoundPlayer.OverrideMusicType = CrewManager.characters.Any(c => !c.IsDead) ? "endshift" : "crewdead"; @@ -378,13 +386,14 @@ namespace Barotrauma //element.Add(new XAttribute("day", day)); XElement modeElement = new XElement("gamemode"); - modeElement.Add(new XAttribute("currentlocation", Map.CurrentLocationIndex)); - modeElement.Add(new XAttribute("mapseed", Map.Seed)); - + //modeElement.Add(new XAttribute("currentlocation", Map.CurrentLocationIndex)); + //modeElement.Add(new XAttribute("mapseed", Map.Seed)); + + CrewManager.Save(modeElement); + Map.Save(modeElement); element.Add(modeElement); - } } } diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs index 735077dc2..fd6270a7e 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs @@ -283,7 +283,7 @@ namespace Barotrauma.Tutorials infoBox = CreateInfoFrame("Steer the submarine downwards, heading further into the cavern."); - while (Submarine.MainSub.WorldPosition.Y > 24600.0f) + while (Submarine.MainSub.WorldPosition.Y > 31900.0f) { yield return CoroutineStatus.Running; } diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs index be13d3b06..d84ef4968 100644 --- a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs +++ b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs @@ -39,7 +39,7 @@ namespace Barotrauma.Tutorials 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"); + GameMain.GameSession.StartShift("tuto2"); GameMain.GameSession.TaskManager.Tasks.Clear(); diff --git a/Subsurface/Source/GameSettings.cs b/Subsurface/Source/GameSettings.cs index 4ad88572a..23a784404 100644 --- a/Subsurface/Source/GameSettings.cs +++ b/Subsurface/Source/GameSettings.cs @@ -25,10 +25,8 @@ namespace Barotrauma private KeyOrMouse[] keyMapping; - private bool unsavedSettings; - public GUIFrame SettingsFrame { get @@ -287,7 +285,7 @@ namespace Barotrauma private bool ChangeSoundVolume(GUIScrollBar scrollBar, float barScroll) { UnsavedSettings = true; - SoundVolume = MathHelper.Clamp(barScroll, 0.0f, 1.0f); + SoundVolume = barScroll; return true; } @@ -295,22 +293,11 @@ namespace Barotrauma private bool ChangeMusicVolume(GUIScrollBar scrollBar, float barScroll) { UnsavedSettings = true; - MusicVolume = MathHelper.Clamp(barScroll, 0.0f, 1.0f); + MusicVolume = barScroll; return true; } - - //private bool ToggleFullScreen(object userData) - //{ - // UnsavedSettings = true; - // FullScreenEnabled = !FullScreenEnabled; - - // GameMain.Graphics.IsFullScreen = FullScreenEnabled; - // GameMain.Graphics.ApplyChanges(); - - // return true; - //} - + public void ResetSettingsFrame() { settingsFrame = null; @@ -363,14 +350,16 @@ namespace Barotrauma y += 70; new GUITextBlock(new Rectangle(0, y, 100, 20), "Sound volume:", GUI.Style, settingsFrame); - GUIScrollBar soundScrollBar = new GUIScrollBar(new Rectangle(0, y+20, 150, 20), GUI.Style,0.1f, settingsFrame); + GUIScrollBar soundScrollBar = new GUIScrollBar(new Rectangle(0, y + 20, 150, 20), GUI.Style, 0.1f, settingsFrame); soundScrollBar.BarScroll = SoundVolume; soundScrollBar.OnMoved = ChangeSoundVolume; + soundScrollBar.Step = 0.05f; - new GUITextBlock(new Rectangle(0, y+40, 100, 20), "Music volume:", GUI.Style, settingsFrame); - GUIScrollBar musicScrollBar = new GUIScrollBar(new Rectangle(0, y+60, 150, 20), GUI.Style, 0.1f, settingsFrame); + new GUITextBlock(new Rectangle(0, y + 40, 100, 20), "Music volume:", GUI.Style, settingsFrame); + GUIScrollBar musicScrollBar = new GUIScrollBar(new Rectangle(0, y + 60, 150, 20), GUI.Style, 0.1f, settingsFrame); musicScrollBar.BarScroll = MusicVolume; musicScrollBar.OnMoved = ChangeMusicVolume; + musicScrollBar.Step = 0.05f; x = 200; y = 10; diff --git a/Subsurface/Source/Map/Levels/LevelGenerationParams.cs b/Subsurface/Source/Map/Levels/LevelGenerationParams.cs index 644c894c6..e55ea1242 100644 --- a/Subsurface/Source/Map/Levels/LevelGenerationParams.cs +++ b/Subsurface/Source/Map/Levels/LevelGenerationParams.cs @@ -133,33 +133,7 @@ namespace Barotrauma get { return bottomHoleProbability; } set { bottomHoleProbability = MathHelper.Clamp(value, 0.0f, 1.0f); } } - - //public LevelGenerationParams() - //{ - // Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); - - // width = 100000.0f; - // height = 50000.0f; - - // voronoiSiteInterval = 2000.0f; - // voronoiSiteVariance = new Vector2(voronoiSiteInterval, voronoiSiteInterval) * 0.4f; - - // mainPathNodeIntervalRange = new Vector2(5000.0f, 10000.0f); - - // float brightness = Rand.Range(1.0f, 1.3f, false); - // BackgroundColor = Color.Lerp(new Color(11, 18, 26), new Color(50, 46, 20), Rand.Range(0.0f, 1.0f, false)) * brightness; - // BackgroundColor = new Color(BackgroundColor, 1.0f); - - // smallTunnelCount = 5; - // smallTunnelLengthRange = new Vector2(5000.0f, 10000.0f); - - // ruinCount = 1; - - // bottomHoleProbability = Rand.Range(0.1f, 0.8f, false); - - // BackgroundSpriteAmount = (int)((new Vector2(width, height)).Length() / 100); - //} - + public static LevelGenerationParams GetRandom(string seed) { Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); @@ -194,7 +168,7 @@ namespace Barotrauma { presets = new List(); - var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.LevelGenerationPresets); + var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.LevelGenerationParameters); if (!files.Any()) { files.Add("Content/Map/LevelGenerationParameters.xml"); @@ -202,7 +176,6 @@ namespace Barotrauma foreach (string file in files) { - XDocument doc = ToolBox.TryLoadXml(file); if (doc == null || doc.Root == null) return; diff --git a/Subsurface/Source/Map/Map/Map.cs b/Subsurface/Source/Map/Map/Map.cs index ff70f8c7f..b876b3f2d 100644 --- a/Subsurface/Source/Map/Map/Map.cs +++ b/Subsurface/Source/Map/Map/Map.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Linq; +using System.Xml.Linq; using Voronoi2; namespace Barotrauma @@ -28,6 +29,8 @@ namespace Barotrauma private Location currentLocation; private Location selectedLocation; + private Location highlightedLocation; + private LocationConnection selectedConnection; public Location CurrentLocation @@ -55,6 +58,35 @@ namespace Barotrauma get { return seed; } } + public static Map Load(XElement element) + { + string mapSeed = ToolBox.GetAttributeString(element, "seed", "a"); + + int size = ToolBox.GetAttributeInt(element, "size", 500); + Map map = new Map(mapSeed, size); + + map.SetLocation(ToolBox.GetAttributeInt(element, "currentlocation", 0)); + + string discoveredStr = ToolBox.GetAttributeString(element, "discovered", ""); + + string[] discoveredStrs = discoveredStr.Split(','); + for (int i = 0; i < discoveredStrs.Length; i++ ) + { + int index = -1; + if (int.TryParse(discoveredStrs[i], out index)) map.locations[index].Discovered = true; + } + + string passedStr = ToolBox.GetAttributeString(element, "passed", ""); + string[] passedStrs = passedStr.Split(','); + for (int i = 0; i < passedStrs.Length; i++) + { + int index = -1; + if (int.TryParse(passedStrs[i], out index)) map.connections[index].Passed = true; + } + + return map; + } + public Map(string seed, int size) { this.seed = seed; @@ -67,15 +99,16 @@ namespace Barotrauma connections = new List(); - if (iceTexture==null) iceTexture = new Sprite("Content/Map/iceSurface.png", Vector2.Zero); + if (iceTexture == null) iceTexture = new Sprite("Content/Map/iceSurface.png", Vector2.Zero); if (iceCraters == null) iceCraters = TextureLoader.FromFile("Content/Map/iceCraters.png"); - if (iceCrack == null) iceCrack = TextureLoader.FromFile("Content/Map/iceCrack.png"); + if (iceCrack == null) iceCrack = TextureLoader.FromFile("Content/Map/iceCrack.png"); Rand.SetSyncedSeed(ToolBox.StringToInt(this.seed)); GenerateLocations(); currentLocation = locations[locations.Count / 2]; + currentLocation.Discovered = true; GenerateDifficulties(currentLocation, new List (connections), 10.0f); foreach (LocationConnection connection in connections) @@ -202,7 +235,10 @@ namespace Barotrauma public void MoveToNextLocation() { + selectedConnection.Passed = true; + currentLocation = selectedLocation; + currentLocation.Discovered = true; selectedLocation = null; } @@ -213,23 +249,18 @@ namespace Barotrauma DebugConsole.ThrowError("Location index out of bounds"); return; } + currentLocation = locations[index]; + currentLocation.Discovered = true; } - private Location highlightedLocation; public void Draw(SpriteBatch spriteBatch, Rectangle rect, float scale = 1.0f) { - //GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true); - Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y); Vector2 offset = -currentLocation.MapPosition; iceTexture.DrawTiled(spriteBatch, new Vector2(rect.X, rect.Y), new Vector2(rect.Width, rect.Height), Vector2.Zero, Color.White*0.8f); - GUI.DrawRectangle(spriteBatch, rect, Color.White); - //spriteBatch.Draw(iceTexture, offset, rect, null, null, 0f, null, Color.White, SpriteEffects.None, 0.0f); - - //Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size); - + float maxDist = 20.0f; float closestDist = 0.0f; highlightedLocation = null; @@ -248,10 +279,9 @@ namespace Barotrauma } } - foreach (LocationConnection connection in connections) { - Color crackColor = Color.White * Math.Max(connection.Difficulty/100.0f, 0.5f); + Color crackColor = Color.White * Math.Max(connection.Difficulty/100.0f, 1.5f); if (highlightedLocation != currentLocation && connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation)) @@ -267,29 +297,58 @@ namespace Barotrauma } } - if (selectedLocation != currentLocation && (connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation))) { crackColor = Color.Red; } - - foreach (Vector2[] segment in connection.CrackSegments) + else if (!connection.Passed) { - Vector2 start = rectCenter + (segment[0] + offset) * scale; - Vector2 end = rectCenter + (segment[1] + offset) * scale; - - if (!rect.Contains(start) || !rect.Contains(end)) continue; + crackColor *= 0.2f; + } + + for (int i = 0; i < connection.CrackSegments.Count; i++ ) + { + var segment = connection.CrackSegments[i]; + + Vector2 start = rectCenter + (segment[0] + offset) * scale; + Vector2 end = rectCenter + (segment[1] + offset) * scale; + + if (!rect.Contains(start) && !rect.Contains(end)) + { + continue; + } + else + { + Vector2? intersection = MathUtils.GetLineRectangleIntersection(start, end, new Rectangle(rect.X, rect.Y + rect.Height, rect.Width, rect.Height)); + if (intersection != null) + { + if (!rect.Contains(start)) + { + start = (Vector2)intersection; + } + else + { + end = (Vector2)intersection; + } + } + } float dist = Vector2.Distance(start, end); + int width = (int)(MathHelper.Clamp(connection.Difficulty, 2.0f, 20.0f) * scale); + spriteBatch.Draw(iceCrack, - new Rectangle((int)start.X, (int)start.Y, (int)dist+2, 30), - new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(end -start), + new Rectangle((int)start.X, (int)start.Y, (int)dist + 2, width), + new Rectangle(0, 0, iceCrack.Width, 60), crackColor, MathUtils.VectorToAngle(end - start), new Vector2(0, 30), SpriteEffects.None, 0.01f); } } + rect.Inflate(8, 8); + GUI.DrawRectangle(spriteBatch, rect, Color.Black, 8); + GUI.DrawRectangle(spriteBatch, rect, Color.LightGray); + for (int i = 0; i < locations.Count; i++) { Location location = locations[i]; @@ -304,7 +363,7 @@ namespace Barotrauma Color color = location.Connections.Find(c => c.Locations.Contains(currentLocation))==null ? Color.White : Color.Green; - color *= (location.Discovered) ? 0.8f : 0.4f; + color *= (location.Discovered) ? 0.8f : 0.2f; if (location == currentLocation) color = Color.Orange; @@ -344,15 +403,37 @@ namespace Barotrauma if (location == null) continue; Vector2 pos = rectCenter + (location.MapPosition + offset) * scale; - pos.X = (int)pos.X; - pos.Y = (int)pos.Y; - if (highlightedLocation == location) - { - spriteBatch.DrawString(GUI.Font, location.Name, pos + new Vector2(0, 50), Color.DarkRed, 0.0f, GUI.Font.MeasureString(location.Name)/2.0f, 1.0f, SpriteEffects.None, 0.0f); - } + pos.X = (int)(pos.X + location.Type.Sprite.SourceRect.Width*0.6f); + pos.Y = (int)(pos.Y - 10); + GUI.DrawString(spriteBatch, pos, location.Name, Color.White, Color.Black * 0.8f, 3); } } + + public void Save(XElement element) + { + XElement mapElement = new XElement("map"); + + mapElement.Add(new XAttribute("currentlocation", CurrentLocationIndex)); + mapElement.Add(new XAttribute("seed", Seed)); + mapElement.Add(new XAttribute("size", size)); + + List discoveredLocations = new List(); + for (int i = 0; i < locations.Count; i++ ) + { + if (locations[i].Discovered) discoveredLocations.Add(i); + } + mapElement.Add(new XAttribute("discovered", string.Join(",", discoveredLocations))); + + List passedConnections = new List(); + for (int i = 0; i < connections.Count; i++) + { + if (connections[i].Passed) passedConnections.Add(i); + } + mapElement.Add(new XAttribute("passed", string.Join(",", passedConnections))); + + element.Add(mapElement); + } } @@ -365,19 +446,21 @@ namespace Barotrauma public List CrackSegments; + public bool Passed; + private int missionsCompleted; private Mission mission; public Mission Mission { get - { - if (mission==null || mission.Completed) + { + if (mission == null || mission.Completed) { - if (mission !=null && mission.Completed) missionsCompleted++; + if (mission != null && mission.Completed) missionsCompleted++; long seed = (long)locations[0].MapPosition.X + (long)locations[0].MapPosition.Y * 100; - seed += (long)locations[1].MapPosition.X*10000 + (long)locations[1].MapPosition.Y * 1000000; + seed += (long)locations[1].MapPosition.X * 10000 + (long)locations[1].MapPosition.Y * 1000000; MTRandom rand = new MTRandom((int)((seed + missionsCompleted) % int.MaxValue)); @@ -390,8 +473,6 @@ namespace Barotrauma } } - - public Location[] Locations { get { return locations; } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index d57d0542e..e85d1d26d 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -46,13 +46,13 @@ namespace Barotrauma #if LINUX var blurEffect = content.Load("blurshader_opengl"); + damageEffect = content.Load("damageshader_opengl"); #else var blurEffect = content.Load("blurshader"); + damageEffect = content.Load("damageshader"); #endif damageStencil = TextureLoader.FromFile("Content/Map/walldamage.png"); - - damageEffect = content.Load("damageshader"); damageEffect.Parameters["xStencil"].SetValue(damageStencil); damageEffect.Parameters["aMultiplier"].SetValue(50.0f); damageEffect.Parameters["cMultiplier"].SetValue(200.0f); @@ -108,19 +108,16 @@ namespace Barotrauma GameMain.GameSession.Submarine.ApplyForce(targetMovement * GameMain.GameSession.Submarine.SubBody.Body.Mass * 100.0f); } #endif + if (GameMain.GameSession != null) GameMain.GameSession.Update((float)deltaTime); + + if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime); + + Character.UpdateAll(cam, (float)deltaTime); Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 6); //Physics.accumulator = Physics.step; while (Physics.accumulator >= Physics.step) { - - if (GameMain.GameSession != null) GameMain.GameSession.Update((float)Physics.step); - //EventManager.Update(gameTime); - - if (Level.Loaded != null) Level.Loaded.Update((float)Physics.step); - - Character.UpdateAll(cam, (float)Physics.step); - BackgroundCreatureManager.Update(cam, (float)Physics.step); GameMain.ParticleManager.Update((float)Physics.step); diff --git a/Subsurface/Source/Screens/LobbyScreen.cs b/Subsurface/Source/Screens/LobbyScreen.cs index 2eb6d1839..b37c1006f 100644 --- a/Subsurface/Source/Screens/LobbyScreen.cs +++ b/Subsurface/Source/Screens/LobbyScreen.cs @@ -9,7 +9,7 @@ namespace Barotrauma { class LobbyScreen : Screen { - enum PanelTab { Crew = 0, Map = 1, CurrentLocation = 2, Store = 3 } + enum PanelTab { Crew = 0, Map = 1, Store = 3 } private GUIFrame topPanel; private GUIFrame[] bottomPanel; @@ -72,19 +72,15 @@ namespace Barotrauma Alignment.BottomLeft, Alignment.BottomLeft, topPanel); moneyText.TextGetter = GetMoney; - GUIButton button = new GUIButton(new Rectangle(-360, 0, 100, 30), "Map", null, Alignment.BottomRight, GUI.Style, topPanel); + GUIButton button = new GUIButton(new Rectangle(-240, 0, 100, 30), "Map", null, Alignment.BottomRight, GUI.Style, topPanel); button.UserData = PanelTab.Map; button.OnClicked = SelectRightPanel; SelectRightPanel(button, button.UserData); - button = new GUIButton(new Rectangle(-240, 0, 100, 30), "Crew", null, Alignment.BottomRight, GUI.Style, topPanel); + button = new GUIButton(new Rectangle(-120, 0, 100, 30), "Crew", null, Alignment.BottomRight, GUI.Style, topPanel); button.UserData = PanelTab.Crew; button.OnClicked = SelectRightPanel; - - button = new GUIButton(new Rectangle(-120, 0, 100, 30), "Hire", null, Alignment.BottomRight, GUI.Style, topPanel); - button.UserData = PanelTab.CurrentLocation; - button.OnClicked = SelectRightPanel; - + button = new GUIButton(new Rectangle(0, 0, 100, 30), "Store", null, Alignment.BottomRight, GUI.Style, topPanel); button.UserData = PanelTab.Store; button.OnClicked = SelectRightPanel; @@ -106,7 +102,9 @@ namespace Barotrauma //new GUITextBlock(new Rectangle(0, 0, 200, 25), "Crew:", Color.Transparent, Color.White, Alignment.Left, GUI.Style, bottomPanel[(int)PanelTab.Crew]); int crewColumnWidth = Math.Min(300, (panelRect.Width - 40) / 2); - characterList = new GUIListBox(new Rectangle(0, 0, crewColumnWidth, 0), GUI.Style, bottomPanel[(int)PanelTab.Crew]); + + new GUITextBlock(new Rectangle(0, 0, 100, 20), "Crew:", GUI.Style, bottomPanel[(int)PanelTab.Crew], GUI.LargeFont); + characterList = new GUIListBox(new Rectangle(0, 40, crewColumnWidth, 0), GUI.Style, bottomPanel[(int)PanelTab.Crew]); characterList.OnSelected = SelectCharacter; //--------------------------------------- @@ -118,12 +116,7 @@ namespace Barotrauma Alignment.BottomRight, GUI.Style, bottomPanel[(int)PanelTab.Map]); startButton.OnClicked = StartShift; startButton.Enabled = false; - - //--------------------------------------- - - bottomPanel[(int)PanelTab.CurrentLocation] = new GUIFrame(panelRect, GUI.Style); - bottomPanel[(int)PanelTab.CurrentLocation].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); - + //--------------------------------------- bottomPanel[(int)PanelTab.Store] = new GUIFrame(panelRect, GUI.Style); @@ -131,13 +124,13 @@ namespace Barotrauma int sellColumnWidth = (panelRect.Width - 40) / 2 - 20; - selectedItemList = new GUIListBox(new Rectangle(0, 0, sellColumnWidth, 400), Color.White * 0.7f, GUI.Style, bottomPanel[(int)PanelTab.Store]); + selectedItemList = new GUIListBox(new Rectangle(0, 30, sellColumnWidth, 400), Color.White * 0.7f, GUI.Style, bottomPanel[(int)PanelTab.Store]); selectedItemList.OnSelected = DeselectItem; var costText = new GUITextBlock(new Rectangle(0, 0, 100, 25), "Cost: ", GUI.Style, Alignment.BottomLeft, Alignment.TopLeft, bottomPanel[(int)PanelTab.Store]); costText.TextGetter = CostTextGetter; - buyButton = new GUIButton(new Rectangle(sellColumnWidth + 20, 0, 100, 25), "Buy", Alignment.Bottom, GUI.Style, bottomPanel[(int)PanelTab.Store]); + buyButton = new GUIButton(new Rectangle(selectedItemList.Rect.Width - 100, 0, 100, 25), "Buy", Alignment.Bottom, GUI.Style, bottomPanel[(int)PanelTab.Store]); buyButton.OnClicked = BuyItems; storeItemList = new GUIListBox(new Rectangle(0, 30, sellColumnWidth, 400), Color.White * 0.7f, Alignment.TopRight, GUI.Style, bottomPanel[(int)PanelTab.Store]); @@ -158,10 +151,7 @@ namespace Barotrauma SelectItemCategory(categoryButton, category); } x += 110; - - } - - + } } public override void Select() @@ -170,49 +160,51 @@ namespace Barotrauma gameMode = GameMain.GameSession.gameMode as SinglePlayerMode; - foreach (GUIComponent component in topPanel.children) - { - var button = component as GUIButton; - if (button == null || button.Text != "Hire") continue; - - button.Enabled = GameMain.GameSession.Map.CurrentLocation.Type.HasHireableCharacters; - break; - } - UpdateCharacterLists(); } private void UpdateLocationTab(Location location) { topPanel.RemoveChild(topPanel.FindChild("locationtitle")); - topPanel.UserData = location; var locationTitle = new GUITextBlock(new Rectangle(0, 0, 200, 25), "Location: "+location.Name, Color.Transparent, Color.White, Alignment.TopLeft, GUI.Style, topPanel); locationTitle.UserData = "locationtitle"; locationTitle.Font = GUI.LargeFont; - - bottomPanel[(int)PanelTab.CurrentLocation].ClearChildren(); - bottomPanel[(int)PanelTab.CurrentLocation].UserData = location; - - if (location.HireManager != null) + + + if (hireList == null) { - hireList = new GUIListBox(new Rectangle(0, 0, 300, 0), GUI.Style, Alignment.Left, bottomPanel[(int)PanelTab.CurrentLocation]); + hireList = new GUIListBox(new Rectangle(0, 40, 300, 0), GUI.Style, Alignment.Right, bottomPanel[(int)PanelTab.Crew]); + new GUITextBlock(new Rectangle(0, 0, 300, 20), "Hire:", GUI.Style, Alignment.Right, Alignment.Left, bottomPanel[(int)PanelTab.Crew], false, GUI.LargeFont); + hireList.OnSelected = SelectCharacter; - - hireList.ClearChildren(); - foreach (CharacterInfo c in location.HireManager.availableCharacters) - { - var frame = c.CreateCharacterFrame(hireList, c.Name + " (" + c.Job.Name + ")", c); - - new GUITextBlock( - new Rectangle(0, 0, 0, 25), - c.Salary.ToString(), - null, null, - Alignment.TopRight, GUI.Style, frame); - } } + + if (location.HireManager == null) + { + hireList.ClearChildren(); + hireList.Enabled = false; + + new GUITextBlock(new Rectangle(0, 0, 0, 0), "No-one available for hire", Color.Transparent, Color.LightGray, Alignment.Center, Alignment.Center, GUI.Style, hireList); + return; + } + + hireList.Enabled = true; + hireList.ClearChildren(); + + foreach (CharacterInfo c in location.HireManager.availableCharacters) + { + var frame = c.CreateCharacterFrame(hireList, c.Name + " (" + c.Job.Name + ")", c); + + new GUITextBlock( + new Rectangle(0, 0, 0, 25), + c.Salary.ToString(), + null, null, + Alignment.TopRight, GUI.Style, frame); + } + } @@ -273,6 +265,8 @@ namespace Barotrauma frame.HoverColor = Color.Gold * 0.2f; frame.SelectedColor = Color.Gold * 0.5f; + frame.ToolTip = ep.Description; + SpriteFont font = listBox.Rect.Width < 280 ? GUI.SmallFont : GUI.Font; GUITextBlock textBlock = new GUITextBlock( @@ -283,6 +277,7 @@ namespace Barotrauma null, frame); textBlock.Font = font; textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); + textBlock.ToolTip = ep.Description; if (ep.sprite != null) { @@ -297,6 +292,7 @@ namespace Barotrauma null, null, Alignment.TopLeft, Alignment.TopLeft, GUI.Style, frame); textBlock.Font = font; + textBlock.ToolTip = ep.Description; } @@ -342,7 +338,6 @@ namespace Barotrauma selectedItemList.RemoveChild(child); } - return false; } @@ -360,7 +355,6 @@ namespace Barotrauma public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) { - if (characterList.CountChildren != CrewManager.characterInfos.Count) { UpdateCharacterLists(); @@ -426,12 +420,7 @@ namespace Barotrauma private bool SelectItemCategory(GUIButton button, object selection) { - if (!(selection is MapEntityCategory)) return false; - //var existingList = bottomPanel[(int)PanelTab.Store].children.Find(c => c is GUIListBox && c.UserData is MapEntityCategory); - //if (existingList != null) bottomPanel[(int)PanelTab.Store].RemoveChild(existingList); - - //bottomPanel[(int)PanelTab.Store].AddChild(storeItemLists[(int)selection]); storeItemList.ClearChildren(); @@ -480,27 +469,32 @@ namespace Barotrauma CharacterInfo characterInfo = selection as CharacterInfo; if (characterInfo == null) return false; + characterList.Deselect(); + hireList.Deselect(); + if (Character.Controlled != null && characterInfo == Character.Controlled.Info) return false; if (previewFrame == null || previewFrame.UserData != characterInfo) { - previewFrame = new GUIFrame(new Rectangle(bottomPanel[(int)PanelTab.Crew].Rect.Width/2, 60, Math.Min(300,bottomPanel[(int)PanelTab.Crew].Rect.Width/2 - 40), 300), + int width = Math.Min(300, bottomPanel[(int)PanelTab.Crew].Rect.Width - hireList.Rect.Width - characterList.Rect.Width - 50); + + previewFrame = new GUIFrame(new Rectangle(0, 60, width, 300), new Color(0.0f, 0.0f, 0.0f, 0.8f), - Alignment.Top, GUI.Style, bottomPanel[selectedRightPanel]); + Alignment.TopCenter, GUI.Style, bottomPanel[selectedRightPanel]); previewFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); previewFrame.UserData = characterInfo; characterInfo.CreateInfoFrame(previewFrame); } - if (selectedRightPanel == (int)PanelTab.CurrentLocation) + if (component.Parent == hireList) { GUIButton hireButton = new GUIButton(new Rectangle(0,0, 100, 20), "Hire", Alignment.BottomCenter, GUI.Style, previewFrame); hireButton.UserData = characterInfo; hireButton.OnClicked = HireCharacter; } - return false; + return true; } private bool HireCharacter(GUIButton button, object selection) @@ -511,6 +505,8 @@ namespace Barotrauma if (gameMode.TryHireCharacter(GameMain.GameSession.Map.CurrentLocation.HireManager, characterInfo)) { UpdateLocationTab(GameMain.GameSession.Map.CurrentLocation); + + SelectCharacter(null,null); } diff --git a/Subsurface/Source/Utils/SaveUtil.cs b/Subsurface/Source/Utils/SaveUtil.cs index 093e7dc35..3a4a3a5bb 100644 --- a/Subsurface/Source/Utils/SaveUtil.cs +++ b/Subsurface/Source/Utils/SaveUtil.cs @@ -23,21 +23,14 @@ namespace Barotrauma string tempPath = Path.Combine(SaveFolder, "temp"); - if (Directory.Exists(tempPath)) - { - Directory.Delete(tempPath, true); - } Directory.CreateDirectory(tempPath); try { - - - if (Submarine.MainSub != null) { Submarine.MainSub.FilePath = Path.Combine(tempPath, Submarine.MainSub.Name + ".sub"); - Submarine.MainSub.SaveAs(Submarine.MainSub.FilePath); + Submarine.MainSub.SaveAs(Submarine.MainSub.FilePath); } } catch (Exception e) diff --git a/Subsurface/changelog.txt b/Subsurface/changelog.txt index 5e8767ab3..2f5fc428e 100644 --- a/Subsurface/changelog.txt +++ b/Subsurface/changelog.txt @@ -1,3 +1,25 @@ +--------------------------------------------------------------------------------------------------------- +v0.5.2.0 +--------------------------------------------------------------------------------------------------------- + +Level generation improvements: + - customizable level generation parameters (see Content/Map/LevelGenerationParameters.xml) + - different "level types" - each uses a different set of parameters, resulting in more varied levels + - more vegetation & other decorative background sprites + - the entrances and exits of the levels have more variety (not always straight vertical tunnels) + +Improved MiniMap (now called "Status Monitor"): + - shows hull integrity and oxygen levels + - can be configured to only show oxygen/water levels if the rooms have detectors installed + +- improved wall damage visuals +- the single player map shows which locations have been visited and the passageways that have been used +- minor visual improvements to the single player campaign menus +- huskification bugfixes +- oxygen isn't distributed through gaps or vents that are underwater (i.e. air pockets can form when the +sub is flooding) +- molochs (or other large creatures) can't push the sub around as easily anymore + --------------------------------------------------------------------------------------------------------- v0.5.1.3 ---------------------------------------------------------------------------------------------------------