diff --git a/Subsurface/Characters/Character.cs b/Subsurface/Characters/Character.cs index cb5f938dc..b84404b8a 100644 --- a/Subsurface/Characters/Character.cs +++ b/Subsurface/Characters/Character.cs @@ -79,7 +79,7 @@ namespace Subsurface protected float soundInterval; private float bleeding; - private float blood; + //private float blood; private Sound[] sounds; //which AIstate each sound is for @@ -152,15 +152,15 @@ namespace Subsurface } } - public float Blood - { - get { return blood; } - set - { - blood = MathHelper.Clamp(value, 0.0f, 100.0f); - if (blood == 0.0f) Kill(); - } - } + //public float Blood + //{ + // get { return blood; } + // set + // { + // blood = MathHelper.Clamp(value, 0.0f, 100.0f); + // if (blood == 0.0f) Kill(); + // } + //} public Item[] SelectedItems { @@ -286,20 +286,20 @@ namespace Subsurface IsNetworkPlayer = isNetworkPlayer; oxygen = 100.0f; - blood = 100.0f; + //blood = 100.0f; aiTarget = new AITarget(this); properties = ObjectProperty.GetProperties(this); + info = characterInfo==null ? new CharacterInfo(file) : characterInfo; + XDocument doc = ToolBox.TryLoadXml(file); if (doc == null) return; - + speciesName = ToolBox.GetAttributeString(doc.Root, "name", "Unknown"); isHumanoid = ToolBox.GetAttributeBool(doc.Root, "humanoid", false); - - info = characterInfo ?? new CharacterInfo(file); - + if (isHumanoid) { animController = new HumanoidAnimController(this, doc.Root.Element("ragdoll")); @@ -427,7 +427,11 @@ namespace Subsurface /// public void ControlLocalPlayer(Camera cam, bool moveCam = true) { - if (isDead) return; + //if (isDead) + //{ + + // return; + //} Limb head = animController.GetLimb(LimbType.Head); @@ -522,7 +526,16 @@ namespace Subsurface public void Update(Camera cam, float deltaTime) { - if (isDead) return; + if (isDead) + { + if (controlled == this) + { + cam.Zoom = MathHelper.Lerp(cam.Zoom, 1.5f, 0.1f); + cam.TargetPos = ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition); + cam.OffsetAmount = 0.0f; + } + return; + } if (PressureProtection==0.0f && (animController.CurrentHull == null || animController.CurrentHull.LethalPressure >= 100.0f)) @@ -568,7 +581,7 @@ namespace Subsurface //foreach (Limb limb in animController.limbs) //{ - Blood = blood - bleeding * deltaTime; + Health = health - bleeding * deltaTime; //} if (aiController != null) aiController.Update(deltaTime); @@ -591,18 +604,24 @@ namespace Subsurface aiTarget.SightRange += torso.LinearVelocity.Length() * 500.0f; } } - + public void Draw(SpriteBatch spriteBatch) { animController.Draw(spriteBatch); if (IsNetworkPlayer) { - Vector2 pos = new Vector2(Position.X, -Position.Y - 50.0f) - GUI.font.MeasureString(info.name) * 0.5f; - spriteBatch.DrawString(GUI.font, info.name, pos - new Vector2(1.0f, 1.0f), Color.Black); - spriteBatch.DrawString(GUI.font, info.name, pos, Color.White); + Vector2 namePos = new Vector2(Position.X, -Position.Y - 80.0f) - GUI.font.MeasureString(info.name) * 0.5f; + spriteBatch.DrawString(GUI.font, info.name, namePos - new Vector2(1.0f, 1.0f), Color.Black); + spriteBatch.DrawString(GUI.font, info.name, namePos, Color.White); } + if (this == Character.controlled) return; + + Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.0f); + GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X-2, (int)healthBarPos.Y-2, 100+4, 15+4), Color.Black, false); + GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f*(health/maxHealth)), 15), Color.Red, true); + //spriteBatch.DrawString(GUI.font, ID.ToString(), ConvertUnits.ToDisplayUnits(animController.limbs[0].Position), Color.White); //GUI.DrawLine(spriteBatch, ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y), // ConvertUnits.ToDisplayUnits(animController.limbs[0].SimPosition.X, animController.limbs[0].SimPosition.Y) + @@ -610,7 +629,7 @@ namespace Subsurface } - private static GUIProgressBar drowningBar, bloodBar; + private static GUIProgressBar drowningBar, healthBar; public void DrawHud(SpriteBatch spriteBatch, Camera cam) { if (drowningBar==null) @@ -618,19 +637,16 @@ namespace Subsurface int width = 100, height = 20; drowningBar = new GUIProgressBar(new Rectangle(20, Game1.GraphicsHeight/2, width, height), Color.Blue, 1.0f); - bloodBar = new GUIProgressBar(new Rectangle(20, Game1.GraphicsHeight / 2 + 30, width, height), Color.Red, 1.0f); + healthBar = new GUIProgressBar(new Rectangle(20, Game1.GraphicsHeight / 2 + 30, width, height), Color.Red, 1.0f); } drowningBar.BarSize = Controlled.Oxygen / 100.0f; - if (drowningBar.BarSize < 1.0f) - drowningBar.Draw(spriteBatch); + if (drowningBar.BarSize < 0.95f) drowningBar.Draw(spriteBatch); - bloodBar.BarSize = Blood / 100.0f; - if (bloodBar.BarSize < 1.0f) - bloodBar.Draw(spriteBatch); + healthBar.BarSize = health / maxHealth; + if (healthBar.BarSize < 1.0f) healthBar.Draw(spriteBatch); - if (Controlled.Inventory != null) - Controlled.Inventory.Draw(spriteBatch); + if (Controlled.Inventory != null) Controlled.Inventory.Draw(spriteBatch); if (closestItem!=null) { @@ -773,29 +789,6 @@ namespace Subsurface { if (isDead) return; - //if the game is run by a client, characters are only killed when the server says so - if (Game1.Client != null) - { - if (networkMessage) - { - new NetworkEvent(NetworkEventType.KillCharacter, ID, true); - } - else - { - return; - } - } - - if (Game1.Server != null) - { - new NetworkEvent(NetworkEventType.KillCharacter, ID, false); - } - - if (Game1.GameSession!=null && Game1.GameSession.crewManager != null) - { - Game1.GameSession.crewManager.KillCharacter(this); - } - isDead = true; animController.movement = Vector2.Zero; animController.TargetMovement = Vector2.Zero; @@ -820,6 +813,30 @@ namespace Subsurface joint.MotorEnabled = false; joint.MaxMotorTorque = 0.0f; } + + + //if the game is run by a client, characters are only killed when the server says so + if (Game1.Client != null) + { + if (networkMessage) + { + new NetworkEvent(NetworkEventType.KillCharacter, ID, true); + } + else + { + return; + } + } + + if (Game1.Server != null) + { + new NetworkEvent(NetworkEventType.KillCharacter, ID, false); + } + + if (Game1.GameSession != null) + { + Game1.GameSession.KillCharacter(this); + } } public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data) diff --git a/Subsurface/Characters/CharacterInfo.cs b/Subsurface/Characters/CharacterInfo.cs index 17f4177e2..c6c583cce 100644 --- a/Subsurface/Characters/CharacterInfo.cs +++ b/Subsurface/Characters/CharacterInfo.cs @@ -89,12 +89,16 @@ namespace Subsurface public CharacterInfo(XElement element) { - name = element.Name.ToString(); + name = ToolBox.GetAttributeString(element, "name", "unnamed"); string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower(); gender = (genderStr == "male") ? Gender.Male : Gender.Female; + file = ToolBox.GetAttributeString(element, "file", ""); + salary = ToolBox.GetAttributeInt(element, "salary", 1000); + + headSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1); } public virtual XElement Save(XElement parentElement) @@ -103,6 +107,7 @@ namespace Subsurface componentElement.Add( new XAttribute("name", name), + new XAttribute("file", file), new XAttribute("gender", gender == Gender.Male ? "male" : "female"), new XAttribute("salary", salary), new XAttribute("headspriteid", headSpriteId)); diff --git a/Subsurface/Content/Characters/Crawler/crawler.xml b/Subsurface/Content/Characters/Crawler/crawler.xml index c2151cd42..dd5fce2a4 100644 --- a/Subsurface/Content/Characters/Crawler/crawler.xml +++ b/Subsurface/Content/Characters/Crawler/crawler.xml @@ -26,7 +26,7 @@ - + diff --git a/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml b/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml index 321b558a0..6a0aae69a 100644 --- a/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml +++ b/Subsurface/Content/Characters/TigerThresher/tigerthresher.xml @@ -15,7 +15,7 @@ - + diff --git a/Subsurface/Content/Items/Fabricators/fabricator.png b/Subsurface/Content/Items/Fabricators/fabricator.png new file mode 100644 index 000000000..e82943efb Binary files /dev/null and b/Subsurface/Content/Items/Fabricators/fabricator.png differ diff --git a/Subsurface/Content/Items/Fabricators/fabricators.xml b/Subsurface/Content/Items/Fabricators/fabricators.xml new file mode 100644 index 000000000..ee84049cd --- /dev/null +++ b/Subsurface/Content/Items/Fabricators/fabricators.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Subsurface/Content/Items/railgun.ogg b/Subsurface/Content/Items/Weapons/railgun.ogg similarity index 100% rename from Subsurface/Content/Items/railgun.ogg rename to Subsurface/Content/Items/Weapons/railgun.ogg diff --git a/Subsurface/Content/Items/railgun.xml b/Subsurface/Content/Items/Weapons/railgun.xml similarity index 100% rename from Subsurface/Content/Items/railgun.xml rename to Subsurface/Content/Items/Weapons/railgun.xml diff --git a/Subsurface/Content/Items/railgunbarrel.png b/Subsurface/Content/Items/Weapons/railgunbarrel.png similarity index 100% rename from Subsurface/Content/Items/railgunbarrel.png rename to Subsurface/Content/Items/Weapons/railgunbarrel.png diff --git a/Subsurface/Content/Items/railgunbase.png b/Subsurface/Content/Items/Weapons/railgunbase.png similarity index 100% rename from Subsurface/Content/Items/railgunbase.png rename to Subsurface/Content/Items/Weapons/railgunbase.png diff --git a/Subsurface/Content/Items/railguncontroller.png b/Subsurface/Content/Items/Weapons/railguncontroller.png similarity index 100% rename from Subsurface/Content/Items/railguncontroller.png rename to Subsurface/Content/Items/Weapons/railguncontroller.png diff --git a/Subsurface/Content/Items/railgunloader.png b/Subsurface/Content/Items/Weapons/railgunloader.png similarity index 100% rename from Subsurface/Content/Items/railgunloader.png rename to Subsurface/Content/Items/Weapons/railgunloader.png diff --git a/Subsurface/Content/Items/railgunshell.png b/Subsurface/Content/Items/Weapons/railgunshell.png similarity index 100% rename from Subsurface/Content/Items/railgunshell.png rename to Subsurface/Content/Items/Weapons/railgunshell.png diff --git a/Subsurface/Content/Items/Weapons/weapons.xml b/Subsurface/Content/Items/Weapons/weapons.xml index fe3d8c847..d73e3941c 100644 --- a/Subsurface/Content/Items/Weapons/weapons.xml +++ b/Subsurface/Content/Items/Weapons/weapons.xml @@ -11,7 +11,7 @@ - + diff --git a/Subsurface/DebugConsole.cs b/Subsurface/DebugConsole.cs index b47e4a30f..660b7f103 100644 --- a/Subsurface/DebugConsole.cs +++ b/Subsurface/DebugConsole.cs @@ -148,8 +148,13 @@ namespace Subsurface { WayPoint spawnPoint = WayPoint.GetRandom(WayPoint.SpawnType.Human); Character.Controlled = new Character("Content/Characters/Human/human.xml", (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition); - if (Game1.GameSession != null) Game1.GameSession.crewManager.AddCharacter(Character.Controlled); - if (Game1.GameSession != null) Game1.GameSession.crewManager.SelectCharacter(Character.Controlled); + if (Game1.GameSession != null) + { + SinglePlayerMode mode = Game1.GameSession.gameMode as SinglePlayerMode; + if (mode == null) break; + mode.crewManager.AddCharacter(Character.Controlled); + mode.crewManager.SelectCharacter(Character.Controlled); + } } else { diff --git a/Subsurface/GUI/GUIComponent.cs b/Subsurface/GUI/GUIComponent.cs index bea9cc29b..a2fbf255c 100644 --- a/Subsurface/GUI/GUIComponent.cs +++ b/Subsurface/GUI/GUIComponent.cs @@ -133,6 +133,16 @@ namespace Subsurface keyboardDispatcher = new KeyboardDispatcher(window); } + public T GetChild() + { + foreach (GUIComponent child in children) + { + if (child is T) return (T)(object)child; + } + + return default(T); + } + public GUIComponent GetChild(object obj) { foreach (GUIComponent child in children) @@ -242,7 +252,7 @@ namespace Subsurface if (children.Contains(child)) children.Remove(child); } - public void ClearChildren() + public virtual void ClearChildren() { children.Clear(); } diff --git a/Subsurface/GUI/GUIListBox.cs b/Subsurface/GUI/GUIListBox.cs index 8f5db6ddc..92e1ff62a 100644 --- a/Subsurface/GUI/GUIListBox.cs +++ b/Subsurface/GUI/GUIListBox.cs @@ -28,7 +28,10 @@ namespace Subsurface public object SelectedData { - get { return (selected == null) ? null : selected.UserData; } + get + { + return (selected == null) ? null : selected.UserData; + } } public int SelectedIndex @@ -166,12 +169,19 @@ namespace Subsurface } + public override void ClearChildren() + { + base.ClearChildren(); + selected = null; + } + public override void RemoveChild(GUIComponent child) { base.RemoveChild(child); - UpdateScrollBarSize(); - + if (selected == child) selected = null; + + UpdateScrollBarSize(); } private void ShowScrollBar() diff --git a/Subsurface/GUI/GUIMessageBox.cs b/Subsurface/GUI/GUIMessageBox.cs index 1676c778f..de5f4dfd8 100644 --- a/Subsurface/GUI/GUIMessageBox.cs +++ b/Subsurface/GUI/GUIMessageBox.cs @@ -13,12 +13,12 @@ namespace Subsurface //public OnClickedHandler OnClicked; //GUIFrame frame; - GUIButton[] buttons; + public GUIButton[] Buttons; public GUIMessageBox(string header, string text) : this(header, text, new string[] {"OK"}) { - this.buttons[0].OnClicked = OkClicked; + this.Buttons[0].OnClicked = Close; } public GUIMessageBox(string header, string text, string[] buttons, Alignment textAlignment = (Alignment.Left | Alignment.Top)) @@ -37,22 +37,21 @@ namespace Subsurface new GUITextBlock(new Rectangle(0, 30, 0, DefaultHeight - 70), text, Color.Transparent, Color.White, textAlignment, this, true); int x = 0; - this.buttons = new GUIButton[buttons.Length]; + this.Buttons = new GUIButton[buttons.Length]; for (int i = 0; i < buttons.Length; i++) { - this.buttons[i] = new GUIButton(new Rectangle(x, 0, 150, 30), buttons[i], GUI.style, Alignment.Left | Alignment.Bottom, this); + this.Buttons[i] = new GUIButton(new Rectangle(x, 0, 150, 30), buttons[i], GUI.style, Alignment.Left | Alignment.Bottom, this); - x += this.buttons[i].Rect.Width + 20; + x += this.Buttons[i].Rect.Width + 20; } messageBoxes.Enqueue(this); } - private bool OkClicked(GUIButton button, object obj) + public bool Close(GUIButton button, object obj) { messageBoxes.Dequeue(); return true; - } } } diff --git a/Subsurface/GameSession/CrewManager.cs b/Subsurface/GameSession/CrewManager.cs index ea3d019e0..631306fe2 100644 --- a/Subsurface/GameSession/CrewManager.cs +++ b/Subsurface/GameSession/CrewManager.cs @@ -77,16 +77,16 @@ namespace Subsurface characterInfos.Add(character.info); } - GUIFrame frame = new GUIFrame(new Rectangle(0,0,0,40), Color.Transparent, listBox); + GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, listBox); frame.UserData = character; frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); frame.HoverColor = Color.LightGray * 0.5f; frame.SelectedColor = Color.Gold * 0.5f; - string name = character.info.name.Replace(' ','\n'); + string name = character.info.name.Replace(' ', '\n'); GUITextBlock textBlock = new GUITextBlock( - new Rectangle(40,0,0,25), + new Rectangle(40, 0, 0, 25), name, Color.Transparent, Color.White, Alignment.Left, @@ -94,7 +94,7 @@ namespace Subsurface frame); textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); - new GUIImage(new Rectangle(-10,-10,0,0), character.animController.limbs[0].sprite, Alignment.Left, frame); + new GUIImage(new Rectangle(-10, -10, 0, 0), character.animController.limbs[0].sprite, Alignment.Left, frame); } public void Update(float deltaTime) @@ -106,7 +106,11 @@ namespace Subsurface { GUIComponent characterBlock = listBox.GetChild(killedCharacter) as GUIComponent; if (characterBlock != null) characterBlock.Color = Color.DarkRed * 0.5f; - + + if (characters.Find(c => !c.IsDead)==null) + { + Game1.GameSession.EndShift(null, null); + } } public void StartShift() diff --git a/Subsurface/GameSession/GameMode.cs b/Subsurface/GameSession/GameMode.cs index ab7e72f67..5be3b8bfa 100644 --- a/Subsurface/GameSession/GameMode.cs +++ b/Subsurface/GameSession/GameMode.cs @@ -1,19 +1,59 @@ -using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; using System.Collections.Generic; +using System.Reflection; namespace Subsurface { + class GameModePreset + { + public static List list = new List(); + + public ConstructorInfo Constructor; + public string Name; + public bool IsSinglePlayer; + + public GameModePreset(string name, Type type, bool isSinglePlayer = false) + { + this.Name = name; + //Constructor = constructor; + + + Constructor = type.GetConstructor(new Type[] { typeof(GameModePreset) }); + + IsSinglePlayer = isSinglePlayer; + + list.Add(this); + } + + public GameMode Instantiate() + { + object[] lobject = new object[] { this }; + return(GameMode)Constructor.Invoke(lobject); + } + } + class GameMode { - public static List list = new List(); + public static List presetList = new List(); - //TimeSpan duration; + TimeSpan duration; protected DateTime startTime; protected DateTime endTime; + //public readonly bool IsSinglePlayer; + + private GUIProgressBar timerBar; + + + + protected bool isRunning; - protected string name; + //protected string name; + + protected GameModePreset preset; private string endMessage; @@ -32,9 +72,14 @@ namespace Subsurface get { return isRunning; } } + public bool IsSinglePlayer + { + get { return preset.IsSinglePlayer; } + } + public string Name { - get { return name; } + get { return preset.Name; } } public string EndMessage @@ -42,34 +87,51 @@ namespace Subsurface get { return endMessage; } } - public GameMode(string name) + public GameMode(GameModePreset preset) { - this.name = name; + this.preset = preset; - list.Add(this); + + //list.Add(this); + } + + public virtual void Draw(SpriteBatch spriteBatch) + { + if (timerBar != null) timerBar.Draw(spriteBatch); } public virtual void Start(TimeSpan duration) { startTime = DateTime.Now; - endTime = startTime + duration; + if (duration!=TimeSpan.Zero) + { + endTime = startTime + duration; + this.duration = duration; + + timerBar = new GUIProgressBar(new Rectangle(Game1.GraphicsWidth - 120, 20, 100, 25), Color.Gold, 0.0f, null); + } endMessage = "The round has ended!"; isRunning = true; } - public virtual void Update() + public virtual void Update(float deltaTime) { if (!isRunning) return; - if (DateTime.Now >= endTime) + if (duration!=TimeSpan.Zero) { - End(endMessage); + double elapsedTime = (DateTime.Now - startTime).TotalSeconds; + timerBar.BarSize = (float)(elapsedTime / duration.TotalSeconds); } + //if (DateTime.Now >= endTime) + //{ + // End(endMessage); + //} } - public void End(string endMessage = "") + public virtual void End(string endMessage = "") { isRunning = false; @@ -77,11 +139,17 @@ namespace Subsurface Game1.GameSession.EndShift(null, null); } - + public static void Init() { - new GameMode("Sandbox"); - new TraitorMode("Traitor"); + new GameModePreset("Single Player", typeof(SinglePlayerMode), true); + new GameModePreset("SandBox", typeof(GameMode), false); + new GameModePreset("Traitor", typeof(TraitorMode), false); + + + //new SinglePlayerMode("Single Player", true); + //new GameMode("Sandbox"); + //new TraitorMode("Traitor"); } } } diff --git a/Subsurface/GameSession/GameSession.cs b/Subsurface/GameSession/GameSession.cs index 6dda2ee69..6762a6f45 100644 --- a/Subsurface/GameSession/GameSession.cs +++ b/Subsurface/GameSession/GameSession.cs @@ -13,11 +13,10 @@ namespace Subsurface class GameSession { public readonly TaskManager taskManager; - public readonly CrewManager crewManager; - public readonly HireManager hireManager; - protected DateTime startTime; - protected DateTime endTime; + + //protected DateTime startTime; + //protected DateTime endTime; public readonly GameMode gameMode; @@ -26,31 +25,22 @@ namespace Subsurface private GUIListBox chatBox; private GUITextBox textBox; - private GUIProgressBar timerBar; - - private GUIButton endShiftButton; - private string savePath; - private Map selectedMap; - - private int day; + private Map selectedMap; - public int Day + public GameSession(Map selectedMap, GameModePreset gameModePreset) + :this(selectedMap, gameModePreset.Instantiate()) { - get { return day; } + } - public GameSession(Map selectedMap, TimeSpan gameDuration, GameMode gameMode = null) + public GameSession(Map selectedMap, GameMode gameMode = null) { taskManager = new TaskManager(this); - crewManager = new CrewManager(); - hireManager = new HireManager(); savePath = SaveUtil.CreateSavePath(SaveUtil.SaveFolder); - hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10); - guiRoot = new GUIFrame(new Rectangle(0,0,Game1.GraphicsWidth,Game1.GraphicsWidth), Color.Transparent); int width = 350, height = 100; @@ -67,74 +57,53 @@ namespace Subsurface Color.White * 0.5f, Color.Black, Alignment.Bottom, Alignment.Left, guiRoot); textBox.OnEnter = EnterChatMessage; } - - if (Game1.Client==null) - { - endShiftButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 240, 20, 100, 25), "End shift", Color.White, Alignment.Left | Alignment.Top, guiRoot); - endShiftButton.OnClicked = EndShift; - } - - timerBar = new GUIProgressBar(new Rectangle(Game1.GraphicsWidth - 120, 20, 100, 25), Color.Gold, 0.0f, guiRoot); - - + this.gameMode = gameMode; - if (this.gameMode != null) this.gameMode.Start(Game1.NetLobbyScreen.GameDuration); + //if (gameMode != null && !gameMode.IsSinglePlayer) + //{ + // gameMode.Start(Game1.NetLobbyScreen.GameDuration); + //} - startTime = DateTime.Now; - endTime = startTime + gameDuration; + //startTime = DateTime.Now; + //endTime = startTime + gameDuration; this.selectedMap = selectedMap; //if (!save) return; //CreateSaveFile(selectedMapFile); - - day = 1; + } - public GameSession(string filePath) - : this(null, new TimeSpan(0,0,0,0)) + public GameSession(Map selectedMap, string savePath, string filePath) + : this(selectedMap) { XDocument doc = ToolBox.TryLoadXml(filePath); if (doc == null) return; - day = ToolBox.GetAttributeInt(doc.Root,"day",1); + //gameMode = GameModePreset.list.Find(gm => gm.Name == "Single Player").Instantiate(); + + //day = ToolBox.GetAttributeInt(doc.Root,"day",1); foreach (XElement subElement in doc.Root.Elements()) { - if (subElement.Name.ToString().ToLower()=="crew") - { - crewManager = new CrewManager(subElement); - } + if (subElement.Name.ToString().ToLower() != "gamemode") continue; + + gameMode = new SinglePlayerMode(subElement); } - savePath = filePath; + this.savePath = savePath; } - public bool TryHireCharacter(CharacterInfo characterInfo) + public void StartShift(TimeSpan duration, int scriptedEventCount = 1) { - if (crewManager.Money < characterInfo.salary) return false; - - hireManager.availableCharacters.Remove(characterInfo); - crewManager.characterInfos.Add(characterInfo); - - crewManager.Money -= characterInfo.salary; - - return true; - } - - public string GetMoney() - { - return ("Money: " + crewManager.Money); - } - - public void StartShift(int scriptedEventCount = 1) - { - if (crewManager.characterInfos.Count == 0) return; + //if (crewManager.characterInfos.Count == 0) return; if (Map.Loaded!=selectedMap) selectedMap.Load(); - crewManager.StartShift(); + if (gameMode!=null) gameMode.Start(duration); + + //crewManager.StartShift(); taskManager.StartShift(scriptedEventCount); } @@ -148,76 +117,30 @@ namespace Subsurface } else if (Game1.Client==null) - { - StringBuilder sb = new StringBuilder(); - List casualties = crewManager.characters.FindAll(c => c.IsDead); - - if (casualties.Any()) - { - sb.Append("Casualties: \n"); - foreach (Character c in casualties) - { - sb.Append(" - " + c.info.name + "\n"); - } - } - else - { - sb.Append("No casualties!"); - } - - new GUIMessageBox("Day #" + day + " is over!\n", sb.ToString()); - - - //if (saveFile == null) return false; - - //Map.Loaded.SaveAs(saveFile); - - crewManager.EndShift(); - + { Game1.LobbyScreen.Select(); - day++; - } - - for (int i = Character.characterList.Count - 1; i >= 0; i--) - { - Character.characterList.RemoveAt(i); + SaveUtil.SaveGame(savePath); } taskManager.EndShift(); + //gameMode.End(); return true; } - private void CreateSaveFile(string mapName) + + public void KillCharacter(Character character) { - //string path = "Content/Data/Saves/"; + SinglePlayerMode singlePlayerMode = gameMode as SinglePlayerMode; + if (singlePlayerMode == null) return; + singlePlayerMode.crewManager.KillCharacter(character); + } - //if (!Directory.Exists(path)) - //{ - // Directory.CreateDirectory(path); - //} - - //string name = Path.GetFileNameWithoutExtension(mapName); - //string extension = Path.GetExtension(mapName); - - //int i = 0; - //while (File.Exists(path + name + i + extension)) - //{ - // i++; - //} - - //saveFile = path + name + i+extension; - - - //try - //{ - // File.Copy(mapName, saveFile); - //} - //catch (Exception e) - //{ - // DebugConsole.ThrowError("Copying map file ''" + mapName + "'' to ''" + saveFile + "'' failed", e); - //} + public bool LoadPrevious(GUIButton button, object obj) + { + SaveUtil.LoadGame(savePath); + return true; } public bool EnterChatMessage(GUITextBox textBox, string message) @@ -237,7 +160,7 @@ namespace Subsurface return true; } - + public void NewChatMessage(string text, Color color) { GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), text, @@ -252,24 +175,24 @@ namespace Subsurface chatBox.RemoveChild(chatBox.children.First()); } } - + public void Update(float deltaTime) { taskManager.Update(deltaTime); - if (endShiftButton!=null) endShiftButton.Enabled = !taskManager.CriticalTasks; - + //if (endShiftButton!=null) endShiftButton.Enabled = !taskManager.CriticalTasks; + //endShiftButton.Enabled = true; guiRoot.Update(deltaTime); - crewManager.Update(deltaTime); + //endShiftButton.Update(deltaTime); //textBox.Update(deltaTime); - if (gameMode != null) gameMode.Update(); + if (gameMode != null) gameMode.Update(deltaTime); - double duration = (endTime - startTime).TotalSeconds; - double elapsedTime = (DateTime.Now-startTime).TotalSeconds; - timerBar.BarSize = (float)(elapsedTime / Math.Max(duration, 1.0)); + //double duration = (endTime - startTime).TotalSeconds; + //double elapsedTime = (DateTime.Now-startTime).TotalSeconds; + //timerBar.BarSize = (float)(elapsedTime / Math.Max(duration, 1.0)); if (PlayerInput.KeyHit(Keys.Tab)) { @@ -288,9 +211,11 @@ namespace Subsurface public void Draw(SpriteBatch spriteBatch) { guiRoot.Draw(spriteBatch); - crewManager.Draw(spriteBatch); + //crewManager.Draw(spriteBatch); taskManager.Draw(spriteBatch); + gameMode.Draw(spriteBatch); + //chatBox.Draw(spriteBatch); //textBox.Draw(spriteBatch); @@ -304,7 +229,11 @@ namespace Subsurface XDocument doc = new XDocument( new XElement((XName)"Gamesession")); - doc.Root.Add(new XAttribute("day", day)); + ((SinglePlayerMode)gameMode).Save(doc.Root); + + //doc.Root.Add(new XAttribute("day", day)); + + //crewManager.Save(doc.Root); try { diff --git a/Subsurface/GameSession/SinglePlayerMode.cs b/Subsurface/GameSession/SinglePlayerMode.cs new file mode 100644 index 000000000..d644d04ae --- /dev/null +++ b/Subsurface/GameSession/SinglePlayerMode.cs @@ -0,0 +1,172 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; + +namespace Subsurface +{ + class SinglePlayerMode : GameMode + { + public readonly CrewManager crewManager; + public readonly HireManager hireManager; + + private GUIButton endShiftButton; + + private int day; + + public int Day + { + get { return day; } + } + + bool crewDead; + private float endTimer; + + public SinglePlayerMode(GameModePreset preset) + : base(preset) + { + crewManager = new CrewManager(); + hireManager = new HireManager(); + + endShiftButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 240, 20, 100, 25), "End shift", Color.White, Alignment.Left | Alignment.Top); + endShiftButton.OnClicked = EndShift; + + hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10); + + day = 1; + } + + public SinglePlayerMode(XElement element) + : this(GameModePreset.list.Find(gm => gm.Name == "Single Player")) + { + day = ToolBox.GetAttributeInt(element,"day",1); + + foreach (XElement subElement in element.Elements()) + { + if (subElement.Name.ToString().ToLower() != "crew") continue; + + crewManager = new CrewManager(subElement); + } + } + + public override void Start(TimeSpan duration) + { + endTimer = 5.0f; + + crewManager.StartShift(); + } + + public bool TryHireCharacter(CharacterInfo characterInfo) + { + if (crewManager.Money < characterInfo.salary) return false; + + hireManager.availableCharacters.Remove(characterInfo); + crewManager.characterInfos.Add(characterInfo); + + crewManager.Money -= characterInfo.salary; + + return true; + } + + public string GetMoney() + { + return ("Money: " + crewManager.Money); + } + + + public override void Draw(SpriteBatch spriteBatch) + { + base.Draw(spriteBatch); + + crewManager.Draw(spriteBatch); + + 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) + { + base.Update(deltaTime); + + crewManager.Update(deltaTime); + + endShiftButton.Update(deltaTime); + + if (!crewDead) + { + if (crewManager.characters.Find(c => !c.IsDead) == null) + { + crewDead = true; + } + } + else + { + endTimer -= deltaTime; + + if (endTimer <= 0.0f) End(""); + } + } + + private bool EndShift(GUIButton button, object obj) + { + StringBuilder sb = new StringBuilder(); + List casualties = crewManager.characters.FindAll(c => c.IsDead); + + if (casualties.Count == crewManager.characters.Count) + { + sb.Append("Your entire crew has died!"); + + var msgBox = new GUIMessageBox("GG", sb.ToString(), new string[] { "Load game", "Quit" }); + msgBox.Buttons[0].OnClicked += Game1.GameSession.LoadPrevious; + msgBox.Buttons[0].OnClicked += msgBox.Close; + msgBox.Buttons[1].OnClicked = Game1.LobbyScreen.QuitToMainMenu; + msgBox.Buttons[1].OnClicked += msgBox.Close; + } + else + { + if (casualties.Any()) + { + sb.Append("Casualties: \n"); + foreach (Character c in casualties) + { + sb.Append(" - " + c.info.name + "\n"); + } + } + else + { + sb.Append("No casualties!"); + } + + new GUIMessageBox("Day #" + day + " is over!\n", sb.ToString()); + + day++; + } + + crewManager.EndShift(); + for (int i = Character.characterList.Count-1; i>=0; i--) + { + Character.characterList.RemoveAt(i); + } + + Game1.GameSession.EndShift(null, null); + + return true; + } + + public void Save(XElement element) + { + element.Add(new XAttribute("day", day)); + + crewManager.Save(element); + + } + } +} diff --git a/Subsurface/GameSession/TraitorMode.cs b/Subsurface/GameSession/TraitorMode.cs index e114f9fbb..f93b5e054 100644 --- a/Subsurface/GameSession/TraitorMode.cs +++ b/Subsurface/GameSession/TraitorMode.cs @@ -9,8 +9,8 @@ namespace Subsurface Client traitor; Client target; - public TraitorMode(string name) - : base(name) + public TraitorMode(GameModePreset preset) + : base(preset) { } @@ -23,8 +23,9 @@ namespace Subsurface target = null; } - public override void Update() + public override void Update(float deltaTime) { + base.Update(deltaTime); if (!isRunning) return; diff --git a/Subsurface/Items/Components/Container.cs b/Subsurface/Items/Components/Container.cs index 288470e32..e3aa1a386 100644 --- a/Subsurface/Items/Components/Container.cs +++ b/Subsurface/Items/Components/Container.cs @@ -13,25 +13,13 @@ namespace Subsurface.Items.Components public ItemInventory inventory; //how many items can be contained - private int capacity; - - private bool hideItems; - private bool drawInventory; - - //the position of the first item in the container - private Vector2 itemPos; - - //item[i].Pos = itemPos + itemInterval*i - private Vector2 itemInterval; - - private float itemRotation; - [HasDefaultValue(5, false)] public int Capacity { get { return capacity; } set { capacity = Math.Max(value, 1); } } + private int capacity; [HasDefaultValue(true, false)] public bool HideItems @@ -39,6 +27,7 @@ namespace Subsurface.Items.Components get { return hideItems; } set { hideItems = value; } } + private bool hideItems; [HasDefaultValue(false, false)] public bool DrawInventory @@ -46,6 +35,25 @@ namespace Subsurface.Items.Components get { return drawInventory; } set { drawInventory = value; } } + private bool drawInventory; + + //the position of the first item in the container + [HasDefaultValue("0.0,0.0", false)] + public string ItemPos + { + get { return ToolBox.Vector2ToString(itemPos); } + set { itemPos = ToolBox.ParseToVector2(value); } + } + private Vector2 itemPos; + + //item[i].Pos = itemPos + itemInterval*i + [HasDefaultValue("0.0,0.0", false)] + public string ItemInterval + { + get { return ToolBox.Vector2ToString(itemInterval); } + set { itemInterval = ToolBox.ParseToVector2(value); } + } + private Vector2 itemInterval; [HasDefaultValue(0.0f, false)] public float ItemRotation @@ -53,25 +61,33 @@ namespace Subsurface.Items.Components get { return itemRotation; } set { itemRotation = value; } } + private float itemRotation; - [HasDefaultValue("0.0,0.0", false)] - public string ItemPos - { - get { return ToolBox.Vector2ToString(itemPos); } - set { itemPos = ToolBox.ParseToVector2(value); } - } - [HasDefaultValue("0.0,0.0", false)] - public string ItemInterval + [HasDefaultValue("0.5,0.9", false)] + public string HudPos { - get { return ToolBox.Vector2ToString(itemInterval); } - set { itemInterval = ToolBox.ParseToVector2(value); } + get { return ToolBox.Vector2ToString(hudPos); } + set + { + hudPos = ToolBox.ParseToVector2(value); + //inventory.CenterPos = hudPos; + } } - + private Vector2 hudPos; + + [HasDefaultValue(5, false)] + public int SlotsPerRow + { + get { return slotsPerRow; } + set { slotsPerRow = value; } + } + private int slotsPerRow; + public ItemContainer(Item item, XElement element) : base (item, element) { - inventory = new ItemInventory(this, capacity); + inventory = new ItemInventory(this, capacity, hudPos, slotsPerRow); containableItems = new List(); //itemPos = ToolBox.GetAttributeVector2(element, "ItemPos", Vector2.Zero); @@ -99,6 +115,7 @@ namespace Subsurface.Items.Components public bool CanBeContained(Item item) { + if (containableItems.Count == 0) return true; return (containableItems.Find(x => x.MatchesItem(item)) != null); } @@ -182,10 +199,7 @@ namespace Subsurface.Items.Components public override bool Pick(Character picker) { - if (picker == null) return false; - //picker.SelectedConstruction = item; - - return true; + return (picker != null); } diff --git a/Subsurface/Items/Components/Fabricator.cs b/Subsurface/Items/Components/Fabricator.cs new file mode 100644 index 000000000..398799724 --- /dev/null +++ b/Subsurface/Items/Components/Fabricator.cs @@ -0,0 +1,216 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; + +namespace Subsurface.Items.Components +{ + class FabricableItem + { + //public static List list = new List(); + + //public readonly string[] FabricatorTags; + + public readonly ItemPrefab TargetItem; + + public readonly List RequiredItems; + + public readonly float RequiredTime; + + + //ListOrSomething requiredLevels + + public FabricableItem(XElement element) + { + string name = ToolBox.GetAttributeString(element, "name", "").ToLower(); + + TargetItem = ItemPrefab.list.Find(ip => ip.Name.ToLower() == name) as ItemPrefab; + if (TargetItem == null) + { + DebugConsole.ThrowError("Error in Fabricable Item! Item ''" + element.Name + "'' not found."); + return; + } + + RequiredItems = new List(); + + string[] requiredItemNames = ToolBox.GetAttributeString(element, "requireditems", "").Split(','); + foreach (string requiredItemName in requiredItemNames) + { + ItemPrefab requiredItem = ItemPrefab.list.Find(ip => ip.Name.ToLower() == requiredItemName.Trim().ToLower()) as ItemPrefab; + if (requiredItem == null) continue; + RequiredItems.Add(requiredItem); + } + + RequiredTime = ToolBox.GetAttributeFloat(element, "requiredtime", 1.0f); + } + } + + class Fabricator : ItemComponent + { + List fabricableItems; + + GUIListBox itemList; + + GUIFrame selectedItemFrame; + + FabricableItem fabricatedItem; + float timeUntilReady; + + public Fabricator(Item item, XElement element) + : base(item, element) + { + fabricableItems = new List(); + + foreach (XElement subElement in element.Elements()) + { + if (subElement.Name.ToString() != "fabricableitem") continue; + + FabricableItem fabricableItem = new FabricableItem(subElement); + if (fabricableItem.TargetItem != null) fabricableItems.Add(fabricableItem); + + } + + int width = 400, height = 300; + itemList = new GUIListBox(new Rectangle(Game1.GraphicsWidth / 2 - width / 2, Game1.GraphicsHeight / 2 - height / 2, width, height), Color.White * 0.7f); + itemList.OnSelected = SelectItem; + //structureList.CheckSelected = MapEntityPrefab.GetSelected; + + foreach (FabricableItem fi in fabricableItems) + { + Color color = ((itemList.CountChildren % 2) == 0) ? Color.White : Color.LightGray; + + //GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, itemList); + //frame.UserData = fi; + //frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); + //frame.Color = color; + //frame.HoverColor = Color.Gold * 0.2f; + //frame.SelectedColor = Color.Gold * 0.5f; + + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + fi.TargetItem.Name, + color, Color.Black, + Alignment.Left, + Alignment.Left, + itemList); + textBlock.UserData = fi; + textBlock.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); + + //if (fi.TargetItem.sprite != null) + //{ + // GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), fi.TargetItem.sprite, Alignment.Left, frame); + // img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f); + //} + } + } + + private bool SelectItem(object obj) + { + FabricableItem targetItem = obj as FabricableItem; + if (targetItem == null) return false; + + int width = 200, height = 150; + selectedItemFrame = new GUIFrame(new Rectangle(Game1.GraphicsWidth / 2 - width / 2, itemList.Rect.Bottom+20, width, height), Color.Black*0.8f); + selectedItemFrame.Padding = GUI.style.smallPadding; + + if (targetItem.TargetItem.sprite != null) + { + GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), targetItem.TargetItem.sprite, Alignment.CenterX, selectedItemFrame); + img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f); + + string text = targetItem.TargetItem.Name + "\n"; + text += "Required items:\n"; + foreach (ItemPrefab ip in targetItem.RequiredItems) + { + text += " - " + ip.Name + "\n"; + } + text += "Required time: "+targetItem.RequiredTime+" s"; + + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + text, + Color.Transparent, Color.White, + Alignment.CenterX | Alignment.CenterY, + Alignment.Left, + selectedItemFrame); + + GUIButton button = new GUIButton(new Rectangle(0,0,100,20), "Create", Color.White, Alignment.CenterX | Alignment.Bottom, selectedItemFrame); + button.OnClicked = StartFabricating; + button.UserData = targetItem; + + + } + + return true; + } + + public override bool Pick(Character picker) + { + return (picker != null); + } + + private bool StartFabricating(GUIButton button, object obj) + { + GUIComponent listElement = itemList.GetChild(obj); + + listElement.Color = Color.Green; + itemList.Enabled = false; + + fabricatedItem = obj as FabricableItem; + isActive = true; + + timeUntilReady = fabricatedItem.RequiredTime; + + return true; + } + + public override void Update(float deltaTime, Camera cam) + { + timeUntilReady -= deltaTime; + + if (timeUntilReady > 0.0f) return; + + ItemContainer container = item.GetComponent(); + foreach (ItemPrefab ip in fabricatedItem.RequiredItems) + { + var requiredItem = Array.Find(container.inventory.items, it => it != null && it.Prefab == ip); + container.inventory.RemoveItem(requiredItem); + } + + new Item(fabricatedItem.TargetItem, item.Position); + + isActive = false; + fabricatedItem = null; + } + + public override void DrawHUD(SpriteBatch spriteBatch, Character character) + { + FabricableItem targetItem = itemList.SelectedData as FabricableItem; + if (targetItem != null) + { + selectedItemFrame.GetChild().Enabled = true; + + ItemContainer container = item.GetComponent(); + foreach (ItemPrefab ip in targetItem.RequiredItems) + { + if (Array.Find(container.inventory.items, it => it != null && it.Prefab == ip) != null) continue; + selectedItemFrame.GetChild().Enabled = false; + break; + } + } + + + itemList.Update(0.016f); + itemList.Draw(spriteBatch); + + if (selectedItemFrame != null) + { + selectedItemFrame.Update(0.016f); + selectedItemFrame.Draw(spriteBatch); + } + } + } +} diff --git a/Subsurface/Items/Components/Signal/Wire.cs b/Subsurface/Items/Components/Signal/Wire.cs index 56553d701..b2ce301cf 100644 --- a/Subsurface/Items/Components/Signal/Wire.cs +++ b/Subsurface/Items/Components/Signal/Wire.cs @@ -224,10 +224,10 @@ namespace Subsurface.Items.Components { if (nodes.Count == 0) return; - for (int i = 0; i < nodes.Count; i++) - { - GUI.DrawRectangle(spriteBatch, new Rectangle((int)nodes[i].X, (int)-nodes[i].Y, 5, 5), Color.DarkGray, true, wireSprite.Depth - 0.01f); - } + //for (int i = 0; i < nodes.Count; i++) + //{ + // GUI.DrawRectangle(spriteBatch, new Rectangle((int)nodes[i].X, (int)-nodes[i].Y, 5, 5), Color.DarkGray, true, wireSprite.Depth - 0.01f); + //} for (int i = 1; i < nodes.Count; i++) { diff --git a/Subsurface/Items/Inventory.cs b/Subsurface/Items/Inventory.cs index 5893628b7..10d19af36 100644 --- a/Subsurface/Items/Inventory.cs +++ b/Subsurface/Items/Inventory.cs @@ -10,20 +10,44 @@ namespace Subsurface { class Inventory : Entity { + public static Item draggingItem; + public static Item doubleClickedItem; + + private int slotsPerRow; + + public int SlotsPerRow + { + set { slotsPerRow = Math.Max(1, value); } + } + protected int capacity; - public static Item draggingItem; + public Vector2 CenterPos + { + get { return centerPos; } + set + { + centerPos = value; + centerPos.X *= Game1.GraphicsWidth; + centerPos.Y *= Game1.GraphicsHeight; + } + } - public static Item doubleClickedItem; + private Vector2 centerPos; protected int selectedSlot; public Item[] items; - public Inventory(int capacity) + public Inventory(int capacity, Vector2? centerPos = null, int slotsPerRow=5) { this.capacity = capacity; + + this.slotsPerRow = slotsPerRow; + items = new Item[capacity]; + + CenterPos = (centerPos==null) ? new Vector2(0.5f, 0.5f) : (Vector2)centerPos; } public int FindIndex(Item item) @@ -132,13 +156,11 @@ namespace Subsurface int rectWidth = 40, rectHeight = 40; int spacing = 10; - - int slotsPerRow = 5; - + int rows = (int)Math.Ceiling((double)capacity / slotsPerRow); - int startX = Game1.GraphicsWidth / 2 - (rectWidth * slotsPerRow + spacing * (slotsPerRow - 1)) / 2; - int startY = (int)(Game1.GraphicsHeight * 0.9) - rows*(spacing+rectHeight); + int startX = (int)centerPos.X - (rectWidth * slotsPerRow + spacing * (slotsPerRow - 1)) / 2; + int startY = (int)centerPos.Y - rows * (spacing + rectHeight); Rectangle slotRect = new Rectangle(startX, startY, rectWidth, rectHeight); Rectangle draggingItemSlot = slotRect; diff --git a/Subsurface/Items/Item.cs b/Subsurface/Items/Item.cs index f1c69953e..3bb86d37c 100644 --- a/Subsurface/Items/Item.cs +++ b/Subsurface/Items/Item.cs @@ -166,6 +166,12 @@ namespace Subsurface } + public Item(ItemPrefab itemPrefab, Vector2 position) + : this(new Rectangle((int)position.X, (int)position.Y, (int)itemPrefab.sprite.size.X, (int)itemPrefab.sprite.size.Y), itemPrefab) + { + + } + public Item(Rectangle newRect, ItemPrefab itemPrefab) { prefab = itemPrefab; diff --git a/Subsurface/Items/ItemInventory.cs b/Subsurface/Items/ItemInventory.cs index 5cdf85cf7..5fd589516 100644 --- a/Subsurface/Items/ItemInventory.cs +++ b/Subsurface/Items/ItemInventory.cs @@ -1,4 +1,5 @@ -using Subsurface.Items.Components; +using Microsoft.Xna.Framework; +using Subsurface.Items.Components; namespace Subsurface { @@ -6,8 +7,8 @@ namespace Subsurface { ItemContainer container; - public ItemInventory(ItemContainer container, int capacity) - : base(capacity) + public ItemInventory(ItemContainer container, int capacity, Vector2? centerPos = null, int slotsPerRow = 5) + : base(capacity, centerPos, slotsPerRow) { this.container = container; } diff --git a/Subsurface/Map/Map.cs b/Subsurface/Map/Map.cs index 64dd2ca72..0ac4f41f1 100644 --- a/Subsurface/Map/Map.cs +++ b/Subsurface/Map/Map.cs @@ -275,8 +275,7 @@ namespace Subsurface // DebugConsole.ThrowError("No save file selected"); // return; //} - XDocument doc = new XDocument( - new XElement((XName)name)); + XDocument doc = new XDocument(new XElement((XName)name)); foreach (MapEntity e in MapEntity.mapEntityList) { @@ -290,9 +289,9 @@ namespace Subsurface { SaveUtil.CompressStringToFile(filePath, doc.ToString()); } - catch + catch (Exception e) { - DebugConsole.ThrowError("Saving map ''" + filePath + "'' failed!"); + DebugConsole.ThrowError("Saving map ''" + filePath + "'' failed!", e); } @@ -505,12 +504,14 @@ namespace Subsurface loaded = this; } - public static void Load(string file) + public static Map Load(string file) { Unload(); Map map = new Map(file); map.Load(); + + return map; } @@ -523,14 +524,9 @@ namespace Subsurface private void Clear() { - filePath = ""; - if (Game1.GameScreen.Cam != null) Game1.GameScreen.Cam.TargetPos = Vector2.Zero; Entity.RemoveAll(); - - if (Game1.GameSession!=null) - Game1.GameSession.crewManager.EndShift(); PhysicsBody.list.Clear(); diff --git a/Subsurface/Networking/GameClient.cs b/Subsurface/Networking/GameClient.cs index eae49a78e..e3108b808 100644 --- a/Subsurface/Networking/GameClient.cs +++ b/Subsurface/Networking/GameClient.cs @@ -240,8 +240,8 @@ namespace Subsurface.Networking TimeSpan duration = new TimeSpan(0,(int)durationMinutes,0); //int gameModeIndex = inc.ReadInt32(); - Game1.GameSession = new GameSession(Map.Loaded, duration); - Game1.GameSession.StartShift(1); + Game1.GameSession = new GameSession(Map.Loaded); + Game1.GameSession.StartShift(duration, 1); myCharacter = ReadCharacterData(inc); Character.Controlled = myCharacter; diff --git a/Subsurface/Networking/GameServer.cs b/Subsurface/Networking/GameServer.cs index 8704f091b..d57040920 100644 --- a/Subsurface/Networking/GameServer.cs +++ b/Subsurface/Networking/GameServer.cs @@ -9,7 +9,6 @@ namespace Subsurface.Networking { class GameServer : NetworkMember { - // Server object NetServer Server; // Configuration object @@ -275,8 +274,8 @@ namespace Subsurface.Networking //selectedMap.Load(); - Game1.GameSession = new GameSession(selectedMap, Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.SelectedMode); - Game1.GameSession.StartShift(1); + Game1.GameSession = new GameSession(selectedMap, Game1.NetLobbyScreen.SelectedMode); + Game1.GameSession.StartShift(Game1.NetLobbyScreen.GameDuration, 1); //EventManager.SelectEvent(Game1.netLobbyScreen.SelectedEvent); foreach (Client client in connectedClients) diff --git a/Subsurface/SaveUtil.cs b/Subsurface/SaveUtil.cs index 397d46e52..beef366c4 100644 --- a/Subsurface/SaveUtil.cs +++ b/Subsurface/SaveUtil.cs @@ -9,36 +9,40 @@ namespace Subsurface { class SaveUtil { - public const string SaveFolder = "Content/SavedMaps/"; + public const string SaveFolder = "Content/Data/Saves/"; public delegate void ProgressDelegate(string sMessage); - public static void SaveGame(string directory) + public static void SaveGame(string savePath) { - if (Directory.Exists(directory)) + string tempPath = Path.GetDirectoryName(savePath) + "\\temp"; + if (!Directory.Exists(tempPath)) { - Directory.Delete(directory, true); + Directory.CreateDirectory(tempPath); } - Directory.CreateDirectory(directory); + //Directory.CreateDirectory(Path.GetDirectoryName(filePath) + "\\temp"); - Map.Loaded.SaveAs(directory+"\\map.gz"); + Map.Loaded.SaveAs(tempPath + "\\map.gz"); - Game1.GameSession.Save(directory+"\\gamesession.xml"); + Game1.GameSession.Save(tempPath + "\\gamesession.xml"); //Game1.GameSession.crewManager.Save(directory+"\\crew.xml"); - CompressDirectory(directory, directory+".save", null); + CompressDirectory(tempPath, savePath, null); - Directory.Delete(directory, true); + Directory.Delete(tempPath, true); } public static void LoadGame(string filePath) { - DecompressToDirectory(filePath+".save", Path.GetDirectoryName(filePath)+"\\temp", null); + string tempPath = Path.GetDirectoryName(filePath) + "\\temp"; - Map.Load(Path.GetDirectoryName(filePath) + "\\temp\\map.gz"); - Game1.GameSession = new GameSession(Path.GetDirectoryName(filePath) + "\\temp\\gamesession.gz"); + DecompressToDirectory(filePath, tempPath, null); + Map selectedMap = Map.Load(tempPath +"\\map.gz"); + Game1.GameSession = new GameSession(selectedMap, filePath, tempPath + "\\gamesession.xml"); + + Directory.Delete(tempPath, true); } public static string CreateSavePath(string saveFolder, string fileName="save") @@ -57,7 +61,7 @@ namespace Subsurface i++; } - return saveFolder + fileName + i + extension; + return saveFolder + fileName + i; } public static void CompressStringToFile(string fileName, string value) diff --git a/Subsurface/Screens/LobbyScreen.cs b/Subsurface/Screens/LobbyScreen.cs index f2233466a..508569e85 100644 --- a/Subsurface/Screens/LobbyScreen.cs +++ b/Subsurface/Screens/LobbyScreen.cs @@ -1,5 +1,9 @@ -using Microsoft.Xna.Framework; +using FarseerPhysics; +using FarseerPhysics.Dynamics; +using FarseerPhysics.Factories; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System; namespace Subsurface { @@ -15,6 +19,13 @@ namespace Subsurface GUIListBox characterList; GUIListBox hireList; + SinglePlayerMode gameMode; + + Body previewPlatform; + Hull previewHull; + + Character previewCharacter; + public LobbyScreen() { Rectangle panelRect = new Rectangle( @@ -81,14 +92,14 @@ namespace Subsurface new GUITextBlock(new Rectangle(0, 0, 200, 25), "Crew:", Color.Transparent, Color.White, Alignment.Left, rightPanel[0]); characterList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, rightPanel[0]); + characterList.OnSelected = SelectCharacter; //--------------------------------------- rightPanel[1] = new GUIFrame(panelRect, GUI.style.backGroundColor); rightPanel[1].Padding = GUI.style.smallPadding; - hireList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, Alignment.Left, rightPanel[1]); - + hireList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, Alignment.Left, rightPanel[1]); hireList.OnSelected = HireCharacter; } @@ -96,16 +107,74 @@ namespace Subsurface { base.Select(); + gameMode = Game1.GameSession.gameMode as SinglePlayerMode; + //Map.Unload(); - UpdateCharacterLists(); - + UpdateCharacterLists(); + } + + public override void Deselect() + { + base.Deselect(); + + if (previewPlatform != null) + { + Game1.world.RemoveBody(previewPlatform); + previewPlatform = null; + } + + if (previewHull != null) + { + previewHull.Remove(); + previewHull = null; + } + + if (previewCharacter != null) + { + previewCharacter.Remove(); + previewCharacter = null; + } + } + + private void CreatePreviewCharacter() + { + if (previewCharacter != null) previewCharacter.Remove(); + + Vector2 pos = new Vector2(1000.0f, 1000.0f); + + previewCharacter = new Character(characterList.SelectedData as CharacterInfo, pos); + + previewCharacter.animController.isStanding = true; + + if (previewPlatform == null) + { + Body platform = BodyFactory.CreateRectangle(Game1.world, 3.0f, 1.0f, 5.0f); + platform.SetTransform(new Vector2(pos.X, pos.Y - 3.5f), 0.0f); + platform.IsStatic = true; + } + + if (previewHull == null) + { + pos = ConvertUnits.ToDisplayUnits(pos); + previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 500)); + } + + Physics.Alpha = 1.0f; + + for (int i = 0; i < 500; i++) + { + previewCharacter.animController.Update((float)Physics.step); + previewCharacter.animController.UpdateAnim((float)Physics.step); + Game1.world.Step((float)Physics.step); + } + } private void UpdateCharacterLists() { characterList.ClearChildren(); - foreach (CharacterInfo c in Game1.GameSession.crewManager.characterInfos) + foreach (CharacterInfo c in gameMode.crewManager.characterInfos) { GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), @@ -114,10 +183,11 @@ namespace Subsurface Alignment.Left, characterList); textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); + textBlock.UserData = c; } hireList.ClearChildren(); - foreach (CharacterInfo c in Game1.GameSession.hireManager.availableCharacters) + foreach (CharacterInfo c in gameMode.hireManager.availableCharacters) { GUIFrame frame = new GUIFrame( new Rectangle(0, 0, 0, 25), @@ -156,8 +226,8 @@ namespace Subsurface public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) { - if (characterList.CountChildren != Game1.GameSession.crewManager.characterInfos.Count - || hireList.CountChildren != Game1.GameSession.hireManager.availableCharacters.Count) + if (characterList.CountChildren != gameMode.crewManager.characterInfos.Count + || hireList.CountChildren != gameMode.hireManager.availableCharacters.Count) { UpdateCharacterLists(); } @@ -168,10 +238,6 @@ namespace Subsurface spriteBatch.Begin(); - - //ConstructionPrefab.list[5].sprite.Draw(spriteBatch, Vector2.Zero, new Vector2(10.0f, 1.0f), Color.White); - - leftPanel.Draw(spriteBatch); shiftPanel.Draw(spriteBatch); @@ -180,6 +246,26 @@ namespace Subsurface GUI.Draw((float)deltaTime, spriteBatch, null); spriteBatch.End(); + + if (characterList.SelectedData != null) + { + if (previewCharacter != null) + { + Vector2 position = new Vector2(characterList.Rect.Right + 100, characterList.Rect.Y + 25.0f); + + Vector2 pos = previewCharacter.Position; + pos.Y = -pos.Y; + Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f)); + + spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform); + previewCharacter.Draw(spriteBatch); + spriteBatch.End(); + } + else + { + CreatePreviewCharacter(); + } + } } public bool SelectRightPanel(GUIButton button, object selection) @@ -189,49 +275,93 @@ namespace Subsurface return true; } + //private void CreatePreviewCharacter() + //{ + // if (Game1.Client.Character != null) Game1.Client.Character.Remove(); + + // Vector2 pos = new Vector2(1000.0f, 1000.0f); + + // Character character = new Character(Game1.Client.CharacterInfo, pos); + + // Game1.Client.Character = character; + + // character.animController.isStanding = true; + + // if (previewPlatform == null) + // { + // Body platform = BodyFactory.CreateRectangle(Game1.world, 3.0f, 1.0f, 5.0f); + // platform.SetTransform(new Vector2(pos.X, pos.Y - 2.5f), 0.0f); + // platform.IsStatic = true; + // } + + // if (previewPlatform == null) + // { + // pos = ConvertUnits.ToDisplayUnits(pos); + // new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200)); + // } + + // Physics.Alpha = 1.0f; + + // for (int i = 0; i < 500; i++) + // { + // character.animController.Update((float)Physics.step); + // character.animController.UpdateAnim((float)Physics.step); + // Game1.world.Step((float)Physics.step); + // } + //} + private string GetMoney() { - return "Money: " + ((Game1.GameSession == null) ? "" : Game1.GameSession.crewManager.Money.ToString()); + return "Money: " + ((Game1.GameSession == null) ? "" : gameMode.crewManager.Money.ToString()); } private string GetDay() { - return "Day #" + ((Game1.GameSession == null) ? "" : Game1.GameSession.Day.ToString()); + return "Day #" + ((Game1.GameSession == null) ? "" : gameMode.Day.ToString()); } private float GetWeekProgress() { if (Game1.GameSession == null) return 0.0f; - return (float)((Game1.GameSession.Day - 1) % 7) / 7.0f; + return (float)((gameMode.Day - 1) % 7) / 7.0f; + } + + private bool SelectCharacter(object selection) + { + CharacterInfo characterInfo = selection as CharacterInfo; + if (characterInfo == null) return false; + + if (Character.Controlled != null && characterInfo == Character.Controlled.info) return false; + + CreatePreviewCharacter(); + + return false; } private bool HireCharacter(object selection) { - CharacterInfo characterInfo; - try { characterInfo = (CharacterInfo)selection; } - catch { return false; } - + CharacterInfo characterInfo = selection as CharacterInfo; if (characterInfo == null) return false; - Game1.GameSession.TryHireCharacter(characterInfo); + gameMode.TryHireCharacter(characterInfo); return false; } private bool StartShift(GUIButton button, object selection) - { - - //Map.Load(Game1.GameSession.SaveFile); - - Game1.GameSession.StartShift(); - - //EventManager.StartShift(); - + { + Game1.GameSession.StartShift(TimeSpan.Zero); Game1.GameScreen.Select(); return true; } + + public bool QuitToMainMenu(GUIButton button, object selection) + { + Game1.MainMenuScreen.Select(); + return true; + } } } diff --git a/Subsurface/Screens/MainMenu.cs b/Subsurface/Screens/MainMenu.cs index 7e9ef24f1..5e442a034 100644 --- a/Subsurface/Screens/MainMenu.cs +++ b/Subsurface/Screens/MainMenu.cs @@ -2,16 +2,19 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Subsurface.Networking; +using System.IO; namespace Subsurface { class MainMenuScreen : Screen { - enum Tabs { Main = 0, NewGame = 1, JoinServer = 2} + enum Tabs { Main = 0, NewGame = 1, LoadGame = 2, JoinServer = 3 } GUIFrame[] menuTabs; GUIListBox mapList; + GUIListBox saveList; + GUITextBox nameBox; GUITextBox ipBox; @@ -21,7 +24,7 @@ namespace Subsurface public MainMenuScreen(Game1 game) { - menuTabs = new GUIFrame[3]; + menuTabs = new GUIFrame[Enum.GetValues(typeof(Tabs)).Length]; Rectangle panelRect = new Rectangle( Game1.GraphicsWidth / 2 - 250, @@ -32,17 +35,23 @@ namespace Subsurface menuTabs[(int)Tabs.Main].Padding = GUI.style.smallPadding; GUIButton button = new GUIButton(new Rectangle(0, 0, 0, 30), "New Game", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); - button.OnClicked = NewGameClicked; + button.UserData = (int)Tabs.NewGame; + button.OnClicked = SelectTab; //button.Enabled = false; - button = new GUIButton(new Rectangle(0, 60, 0, 30), "Join Server", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); - button.OnClicked = JoinServerClicked; + button = new GUIButton(new Rectangle(0, 60, 0, 30), "Load Game", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); + button.UserData = (int)Tabs.LoadGame; + button.OnClicked = SelectTab; - button = new GUIButton(new Rectangle(0, 120, 0, 30), "Host Server", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); + button = new GUIButton(new Rectangle(0, 120, 0, 30), "Join Server", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); + button.UserData = (int)Tabs.JoinServer; + button.OnClicked = SelectTab; + + button = new GUIButton(new Rectangle(0, 180, 0, 30), "Host Server", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); button.OnClicked = HostServerClicked; //button.Enabled = false; - button = new GUIButton(new Rectangle(0, 180, 0, 30), "Quit", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); + button = new GUIButton(new Rectangle(0, 240, 0, 30), "Quit", GUI.style, Alignment.CenterX, menuTabs[(int)Tabs.Main]); button.OnClicked = QuitClicked; //---------------------------------------------------------------------- @@ -53,7 +62,7 @@ namespace Subsurface new GUITextBlock(new Rectangle(0, 0, 0, 30), "New Game", Color.Transparent, Color.Black, Alignment.CenterX, menuTabs[(int)Tabs.NewGame]); new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected map:", Color.Transparent, Color.Black, Alignment.Left, menuTabs[(int)Tabs.NewGame]); - mapList = new GUIListBox(new Rectangle(0, 60, 200, 400), Color.White, menuTabs[1]); + mapList = new GUIListBox(new Rectangle(0, 60, 200, 400), Color.White, menuTabs[(int)Tabs.NewGame]); foreach (Map map in Map.SavedMaps) { @@ -73,6 +82,34 @@ namespace Subsurface button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", GUI.style, Alignment.Right | Alignment.Bottom, menuTabs[(int)Tabs.NewGame]); button.OnClicked = StartGame; + //---------------------------------------------------------------------- + + menuTabs[(int)Tabs.LoadGame] = new GUIFrame(panelRect, GUI.style.backGroundColor); + menuTabs[(int)Tabs.LoadGame].Padding = GUI.style.smallPadding; + + new GUITextBlock(new Rectangle(0, 0, 0, 30), "Load Game", Color.Transparent, Color.Black, Alignment.CenterX, menuTabs[(int)Tabs.LoadGame]); + + + string[] saveFiles = Directory.GetFiles(SaveUtil.SaveFolder, "*.save"); + + //new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected map:", Color.Transparent, Color.Black, Alignment.Left, menuTabs[(int)Tabs.NewGame]); + saveList = new GUIListBox(new Rectangle(0, 60, 200, 400), Color.White, menuTabs[(int)Tabs.LoadGame]); + + foreach (string saveFile in saveFiles) + { + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + saveFile, + GUI.style, + Alignment.Left, + Alignment.Left, + saveList); + textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); + textBlock.UserData = saveFile; + } + + button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", GUI.style, Alignment.Right | Alignment.Bottom, menuTabs[(int)Tabs.LoadGame]); + button.OnClicked = LoadGame; //---------------------------------------------------------------------- @@ -95,18 +132,12 @@ namespace Subsurface } - private bool NewGameClicked(GUIButton button, object obj) + private bool SelectTab(GUIButton button, object obj) { - selectedTab = (int)Tabs.NewGame; + selectedTab = (int)obj; return true; } - - private bool JoinServerClicked(GUIButton button, object obj) - { - selectedTab = (int)Tabs.JoinServer; - return true; - } - + private bool HostServerClicked(GUIButton button, object obj) { Game1.NetLobbyScreen.isServer = true; @@ -142,18 +173,39 @@ namespace Subsurface private bool StartGame(GUIButton button, object obj) { - Map selectedMap = mapList.SelectedData as Map; if (selectedMap == null) return false; - - Game1.GameSession = new GameSession(selectedMap, TimeSpan.Zero); + Game1.GameSession = new GameSession(selectedMap, GameModePreset.list.Find(gm => gm.Name == "Single Player")); Game1.LobbyScreen.Select(); return true; } + private bool LoadGame(GUIButton button, object obj) + { + + string saveFile = saveList.SelectedData as string; + if (string.IsNullOrWhiteSpace(saveFile)) return false; + + try + { + SaveUtil.LoadGame(saveFile); + } + catch (Exception e) + { + DebugConsole.ThrowError("Loading map ''"+saveFile+"'' failed", e); + return false; + } + + + Game1.LobbyScreen.Select(); + + return true; + } + + private bool JoinServer(GUIButton button, object obj) { if (string.IsNullOrEmpty(nameBox.Text)) return false; diff --git a/Subsurface/Screens/NetLobbyScreen.cs b/Subsurface/Screens/NetLobbyScreen.cs index 4992832d9..d2e304ce3 100644 --- a/Subsurface/Screens/NetLobbyScreen.cs +++ b/Subsurface/Screens/NetLobbyScreen.cs @@ -36,9 +36,9 @@ namespace Subsurface } - public GameMode SelectedMode + public GameModePreset SelectedMode { - get { return modeList.SelectedData as GameMode; } + get { return modeList.SelectedData as GameModePreset; } } public TimeSpan GameDuration @@ -161,8 +161,10 @@ namespace Subsurface modeList.Enabled = (Game1.Server != null); //modeList.OnSelected = new GUIListBox.OnSelectedHandler(SelectEvent); - foreach (GameMode mode in GameMode.list) + foreach (GameModePreset mode in GameModePreset.list) { + if (mode.IsSinglePlayer) continue; + GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), mode.Name, @@ -192,8 +194,8 @@ namespace Subsurface modeList.OnSelected = Game1.Server.UpdateNetLobby; durationBar.OnMoved = Game1.Server.UpdateNetLobby; - if (mapList.CountChildren > 0) mapList.Select(Map.SavedMaps[0]); - if (GameMode.list.Count > 0) modeList.Select(GameMode.list[0]); + if (mapList.CountChildren > 0) mapList.Select(0); + if (GameModePreset.list.Count > 0) modeList.Select(0); } else { @@ -319,9 +321,9 @@ namespace Subsurface Vector2 pos = Game1.Client.Character.Position; pos.Y = -pos.Y; - Matrix transform = Matrix.CreateTranslation(new Vector3(-pos+position, 0.0f)); - - spriteBatch.Begin(SpriteSortMode.BackToFront, null,null,null,null,null,transform); + Matrix transform = Matrix.CreateTranslation(new Vector3(-pos + position, 0.0f)); + + spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, transform); Game1.Client.Character.Draw(spriteBatch); spriteBatch.End(); } @@ -386,10 +388,10 @@ namespace Subsurface platform.IsStatic = true; } - if (previewPlatform==null) + if (previewHull==null) { pos = ConvertUnits.ToDisplayUnits(pos); - new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200)); + previewHull = new Hull(new Rectangle((int)pos.X - 100, (int)pos.Y + 100, 200, 200)); } Physics.Alpha = 1.0f; @@ -473,7 +475,7 @@ namespace Subsurface } else { - msg.Write(Path.GetFileName(selectedMap.FilePath)); + msg.Write(Path.GetFileName(selectedMap.Name)); msg.Write(selectedMap.MapHash.MD5Hash); } diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 620cadf7e..11d227d65 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -71,12 +71,14 @@ + + @@ -305,6 +307,13 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + Designer + PreserveNewest @@ -437,22 +446,22 @@ PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest @@ -587,7 +596,7 @@ PreserveNewest - + PreserveNewest