diff --git a/Subsurface/Characters/Character.cs b/Subsurface/Characters/Character.cs index c9eff264b..cb5f938dc 100644 --- a/Subsurface/Characters/Character.cs +++ b/Subsurface/Characters/Character.cs @@ -14,7 +14,7 @@ using Subsurface.Particles; namespace Subsurface { - class Character : Entity, IDamageable + class Character : Entity, IDamageable, IPropertyObject { public static List characterList = new List(); @@ -40,12 +40,14 @@ namespace Subsurface public byte largeUpdateTimer; public readonly Dictionary properties; + public Dictionary ObjectProperties + { + get { return properties; } + } protected Key selectKeyHit; - protected Key actionKeyHit; - protected Key actionKeyDown; - protected Key secondaryKeyHit; - protected Key secondaryKeyDown; + protected Key actionKeyHit, actionKeyDown; + protected Key secondaryKeyHit, secondaryKeyDown; private Item selectedConstruction; private Item[] selectedItems; @@ -83,6 +85,14 @@ namespace Subsurface //which AIstate each sound is for private AIController.AiState[] soundStates; + public string Name + { + get + { + return speciesName; + } + } + public Inventory Inventory { get { return inventory; } @@ -344,10 +354,10 @@ namespace Subsurface animController.FindHull(); - if (info.ID >= 0) - { - ID = info.ID; - } + //if (info.ID >= 0) + //{ + // ID = info.ID; + //} characterList.Add(this); } diff --git a/Subsurface/Characters/CharacterInfo.cs b/Subsurface/Characters/CharacterInfo.cs index e6ae2ab79..17f4177e2 100644 --- a/Subsurface/Characters/CharacterInfo.cs +++ b/Subsurface/Characters/CharacterInfo.cs @@ -1,4 +1,5 @@ -using System.Xml.Linq; +using Microsoft.Xna.Framework; +using System.Xml.Linq; namespace Subsurface { @@ -6,27 +7,28 @@ namespace Subsurface class CharacterInfo { - //the name of the character (e.q. Urist McEngineer) public string name; public readonly string file; - public int ID; + public readonly int headSpriteId; + + //public int ID; public Gender gender; public int salary; - public string GenderString() - { - return gender.ToString(); - } + //public string GenderString() + //{ + // return gender.ToString(); + //} public CharacterInfo(string file, string name = "", Gender gender = Gender.None) { this.file = file; - ID = -1; + //ID = -1; XDocument doc = ToolBox.TryLoadXml(file); if (doc == null) return; @@ -35,7 +37,7 @@ namespace Subsurface if (ToolBox.GetAttributeBool(doc.Root, "genders", false)) { - if (gender==Gender.None) + if (gender == Gender.None) { float femaleRatio = ToolBox.GetAttributeFloat(doc.Root, "femaleratio", 0.5f); this.gender = (Game1.random.NextDouble() < femaleRatio) ? Gender.Female : Gender.Male; @@ -45,7 +47,21 @@ namespace Subsurface this.gender = gender; } } - + + Vector2 headSpriteRange = ToolBox.GetAttributeVector2(doc.Root, "headid", Vector2.Zero); + if (headSpriteRange == Vector2.Zero) + { + headSpriteRange = ToolBox.GetAttributeVector2( + doc.Root, + this.gender == Gender.Female ? "femaleheadid" : "maleheadid", + Vector2.Zero); + } + + if (headSpriteRange != Vector2.Zero) + { + headSpriteId = Game1.localRandom.Next((int)headSpriteRange.X, (int)headSpriteRange.Y + 1); + } + if (!string.IsNullOrEmpty(name)) { this.name = name; @@ -69,8 +85,30 @@ namespace Subsurface this.name += ToolBox.GetRandomLine(lastNamePath); } } - + } + public CharacterInfo(XElement element) + { + name = element.Name.ToString(); + + string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower(); + gender = (genderStr == "male") ? Gender.Male : Gender.Female; + + salary = ToolBox.GetAttributeInt(element, "salary", 1000); + } + + public virtual XElement Save(XElement parentElement) + { + XElement componentElement = new XElement("character"); + + componentElement.Add( + new XAttribute("name", name), + new XAttribute("gender", gender == Gender.Male ? "male" : "female"), + new XAttribute("salary", salary), + new XAttribute("headspriteid", headSpriteId)); + + parentElement.Add(componentElement); + return componentElement; } } } diff --git a/Subsurface/Characters/DelayedEffect.cs b/Subsurface/Characters/DelayedEffect.cs index 1b1646083..8813d017f 100644 --- a/Subsurface/Characters/DelayedEffect.cs +++ b/Subsurface/Characters/DelayedEffect.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Microsoft.Xna.Framework; +using System.Collections.Generic; using System.Xml.Linq; namespace Subsurface @@ -11,9 +12,9 @@ namespace Subsurface float timer; - private Item item; + Vector2 position; - private Character character; + List targets; public float Timer { @@ -26,14 +27,14 @@ namespace Subsurface delay = ToolBox.GetAttributeFloat(element, "delay", 1.0f); } - public override void Apply(ActionType type, float deltaTime, Item item, Character character = null) + public override void Apply(ActionType type, float deltaTime, Vector2 position, List targets) { if (this.type != type) return; - - this.item = item; - this.character = character; - + timer = delay; + this.position = position; + + this.targets = targets; list.Add(this); } @@ -44,7 +45,7 @@ namespace Subsurface if (timer > 0.0f) return; - base.Apply(1.0f, character, item); + base.Apply(1.0f, position, targets); list.Remove(this); } diff --git a/Subsurface/Characters/Limb.cs b/Subsurface/Characters/Limb.cs index 3292ba9d6..39e57402f 100644 --- a/Subsurface/Characters/Limb.cs +++ b/Subsurface/Characters/Limb.cs @@ -227,7 +227,11 @@ namespace Subsurface string spritePath = subElement.Attribute("texture").Value; if (character.info!=null) + { spritePath = spritePath.Replace("[GENDER]", (character.info.gender == Gender.Female) ? "f" : ""); + spritePath = spritePath.Replace("[HEADID]", character.info.headSpriteId.ToString()); + } + sprite = new Sprite(subElement, "", spritePath); break; diff --git a/Subsurface/Characters/StatusEffect.cs b/Subsurface/Characters/StatusEffect.cs index eea50dc26..2101943e2 100644 --- a/Subsurface/Characters/StatusEffect.cs +++ b/Subsurface/Characters/StatusEffect.cs @@ -9,12 +9,12 @@ namespace Subsurface class StatusEffect { [Flags] - public enum Target + public enum TargetType { This = 1, Parent = 2, Character = 4, Contained = 8, Nearby = 16, UseTarget=32 } - private Target targets; + private TargetType targetTypes; private string[] targetNames; public string[] propertyNames; @@ -30,9 +30,9 @@ namespace Subsurface private Sound sound; - public Target Targets + public TargetType Targets { - get { return targets; } + get { return targetTypes; } } public string[] TargetNames @@ -92,7 +92,7 @@ namespace Subsurface string[] Flags = attribute.Value.Split(','); foreach (string s in Flags) { - targets |= (Target)Enum.Parse(typeof(Target), s, true); + targetTypes |= (TargetType)Enum.Parse(typeof(TargetType), s, true); } break; @@ -143,18 +143,27 @@ namespace Subsurface } - public virtual void Apply(ActionType type, float deltaTime, Item item, Character character = null) - { - if (this.type == type) Apply(deltaTime, character, item); - } + //public virtual void Apply(ActionType type, float deltaTime, Item item, Character character = null) + //{ + // if (this.type == type) Apply(deltaTime, character, item); + //} public virtual void Apply(ActionType type, float deltaTime, Vector2 position, IPropertyObject target) { if (!targetNames.Contains(target.Name)) return; - if (this.type == type) Apply(deltaTime, position, target); + + List targets = new List(); + targets.Add(target); + + if (this.type == type) Apply(deltaTime, position, targets); } - protected virtual void Apply(float deltaTime, Vector2 position, IPropertyObject target) + public virtual void Apply(ActionType type, float deltaTime, Vector2 position, List targets) + { + if (this.type == type) Apply(deltaTime, position, targets); + } + + protected virtual void Apply(float deltaTime, Vector2 position, List targets) { if (explosion != null) explosion.Explode(position); @@ -163,42 +172,45 @@ namespace Subsurface for (int i = 0; i < propertyNames.Count(); i++) { ObjectProperty property; - if (target.ObjectProperties.TryGetValue(propertyNames[i], out property)) + foreach (IPropertyObject target in targets) { - ApplyToProperty(property, propertyEffects[i], deltaTime); + if (targetNames!=null && !targetNames.Contains(target.Name)) continue; + if (!target.ObjectProperties.TryGetValue(propertyNames[i], out property)) continue; + + ApplyToProperty(property, propertyEffects[i], deltaTime); } } } - protected virtual void Apply(float deltaTime, Character character, Item item) - { - if (explosion != null) explosion.Explode(item.SimPosition); + //protected virtual void Apply(float deltaTime, Character character, Item item) + //{ + // if (explosion != null) explosion.Explode(item.SimPosition); - if (sound != null) sound.Play(1.0f, 1000.0f, item.body.FarseerBody); + // if (sound != null) sound.Play(1.0f, 1000.0f, item.body.FarseerBody); - for (int i = 0; i < propertyNames.Count(); i++) - { - ObjectProperty property; + // for (int i = 0; i < propertyNames.Count(); i++) + // { + // ObjectProperty property; - if (character!=null && character.properties.TryGetValue(propertyNames[i], out property)) - { - ApplyToProperty(property, propertyEffects[i], deltaTime); - } + // if (character!=null && character.properties.TryGetValue(propertyNames[i], out property)) + // { + // ApplyToProperty(property, propertyEffects[i], deltaTime); + // } - if (item == null) continue; + // if (item == null) continue; - if (item.properties.TryGetValue(propertyNames[i], out property)) - { - ApplyToProperty(property, propertyEffects[i], deltaTime); - } + // if (item.properties.TryGetValue(propertyNames[i], out property)) + // { + // ApplyToProperty(property, propertyEffects[i], deltaTime); + // } - foreach (ItemComponent ic in item.components) - { - if (!ic.properties.TryGetValue(propertyNames[i], out property)) continue; - ApplyToProperty(property, propertyEffects[i], deltaTime); - } - } - } + // foreach (ItemComponent ic in item.components) + // { + // if (!ic.properties.TryGetValue(propertyNames[i], out property)) continue; + // ApplyToProperty(property, propertyEffects[i], deltaTime); + // } + // } + //} protected void ApplyToProperty(ObjectProperty property, object value, float deltaTime) { diff --git a/Subsurface/Content/Characters/Human/fhead.png b/Subsurface/Content/Characters/Human/fhead1.png similarity index 100% rename from Subsurface/Content/Characters/Human/fhead.png rename to Subsurface/Content/Characters/Human/fhead1.png diff --git a/Subsurface/Content/Characters/Human/fhead2.png b/Subsurface/Content/Characters/Human/fhead2.png new file mode 100644 index 000000000..caac6f99a Binary files /dev/null and b/Subsurface/Content/Characters/Human/fhead2.png differ diff --git a/Subsurface/Content/Characters/Human/head.png b/Subsurface/Content/Characters/Human/head1.png similarity index 100% rename from Subsurface/Content/Characters/Human/head.png rename to Subsurface/Content/Characters/Human/head1.png diff --git a/Subsurface/Content/Characters/Human/head3.png b/Subsurface/Content/Characters/Human/head3.png new file mode 100644 index 000000000..58e8b9c86 Binary files /dev/null and b/Subsurface/Content/Characters/Human/head3.png differ diff --git a/Subsurface/Content/Characters/Human/head4.png b/Subsurface/Content/Characters/Human/head4.png new file mode 100644 index 000000000..65e524fed Binary files /dev/null and b/Subsurface/Content/Characters/Human/head4.png differ diff --git a/Subsurface/Content/Characters/Human/human.xml b/Subsurface/Content/Characters/Human/human.xml index 102159d70..d587c6d68 100644 --- a/Subsurface/Content/Characters/Human/human.xml +++ b/Subsurface/Content/Characters/Human/human.xml @@ -1,5 +1,5 @@  - + @@ -8,7 +8,7 @@ - + diff --git a/Subsurface/Content/Items/Clothes/captainhat.png b/Subsurface/Content/Items/Clothes/captainhat.png new file mode 100644 index 000000000..732da7578 Binary files /dev/null and b/Subsurface/Content/Items/Clothes/captainhat.png differ diff --git a/Subsurface/Content/Items/Clothes/clothes.xml b/Subsurface/Content/Items/Clothes/clothes.xml new file mode 100644 index 000000000..0dfb9fcf3 --- /dev/null +++ b/Subsurface/Content/Items/Clothes/clothes.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index 79cdf2cfb..0c5b41dc6 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -11,8 +11,8 @@ - - + + diff --git a/Subsurface/DebugConsole.cs b/Subsurface/DebugConsole.cs index 1ace775a9..a9fdfd4d3 100644 --- a/Subsurface/DebugConsole.cs +++ b/Subsurface/DebugConsole.cs @@ -209,12 +209,20 @@ namespace Subsurface Game1.LobbyScreen.Select(); break; case "savemap": + if (commands.Length < 2) break; Map.Loaded.SaveAs("Content/SavedMaps/" + commands[1]); NewMessage("map saved", Color.Green); break; case "loadmap": + if (commands.Length < 2) break; Map.Load("Content/SavedMaps/" + commands[1]); break; + case "savegame": + SaveUtil.SaveGame("Content/Data/test.save"); + break; + case "loadgame": + SaveUtil.LoadGame("Content/Data/test.save"); + break; case "messagebox": if (commands.Length < 3) break; new GUIMessageBox(commands[1], commands[2]); diff --git a/Subsurface/GUI/GUI.cs b/Subsurface/GUI/GUI.cs index 727f32001..f53eedb3c 100644 --- a/Subsurface/GUI/GUI.cs +++ b/Subsurface/GUI/GUI.cs @@ -269,7 +269,7 @@ namespace Subsurface // new Vector2(10, 30), Color.White); - if (Character.Controlled != null) Character.Controlled.DrawHud(spriteBatch, cam); + if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHud(spriteBatch, cam); DrawMessages(spriteBatch, (float)deltaTime); diff --git a/Subsurface/Game1.cs b/Subsurface/Game1.cs index 9510a5c1f..233a22910 100644 --- a/Subsurface/Game1.cs +++ b/Subsurface/Game1.cs @@ -103,7 +103,6 @@ namespace Subsurface /// protected override void Initialize() { - // TODO: Add your initialization logic here base.Initialize(); particleManager = new ParticleManager("Content/Particles/prefabs.xml", Cam); diff --git a/Subsurface/GameSession/CrewManager.cs b/Subsurface/GameSession/CrewManager.cs index 78daf7c79..20ab779df 100644 --- a/Subsurface/GameSession/CrewManager.cs +++ b/Subsurface/GameSession/CrewManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System.Xml.Linq; namespace Subsurface { @@ -25,7 +26,7 @@ namespace Subsurface set { money = (int)Math.Max(value, 0.0f); } } - public CrewManager(GameSession session) + public CrewManager() { characters = new List(); characterInfos = new List(); @@ -39,6 +40,19 @@ namespace Subsurface money = 10000; } + public CrewManager(XElement element) + : this() + { + money = ToolBox.GetAttributeInt(element, "money", 0); + + foreach (XElement subElement in element.Elements()) + { + if (subElement.Name.ToString().ToLower()!="character") continue; + + characterInfos.Add(new CharacterInfo(subElement)); + } + } + private string CreateSaveFile(string mapName) { string path = "Content/Data/Saves/"; @@ -89,7 +103,7 @@ namespace Subsurface GUITextBlock textBlock = new GUITextBlock( new Rectangle(40,0,0,25), name, - Color.Transparent, Color.Black, + Color.Transparent, Color.White, Alignment.Left, Alignment.Left, frame); @@ -98,6 +112,11 @@ namespace Subsurface new GUIImage(new Rectangle(-10,-10,0,0), character.animController.limbs[0].sprite, Alignment.Left, frame); } + public void Update(float deltaTime) + { + guiFrame.Update(deltaTime); + } + public void KillCharacter(Character killedCharacter) { GUIComponent characterBlock = listBox.GetChild(killedCharacter) as GUIComponent; @@ -138,5 +157,27 @@ namespace Subsurface { guiFrame.Draw(spriteBatch); } + + public void Save(string filePath) + { + XDocument doc = new XDocument( + new XElement((XName)"Crew")); + + doc.Root.Add(new XAttribute("money", money)); + + foreach (CharacterInfo ci in characterInfos) + { + ci.Save(doc.Root); + } + + try + { + doc.Save(filePath); + } + catch + { + DebugConsole.ThrowError("Saving crewmanager to ''" + filePath + "'' failed!"); + } + } } } diff --git a/Subsurface/GameSession/GameSession.cs b/Subsurface/GameSession/GameSession.cs index bcb18bd55..b2bf0403d 100644 --- a/Subsurface/GameSession/GameSession.cs +++ b/Subsurface/GameSession/GameSession.cs @@ -6,6 +6,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System.Text; using System.Collections.Generic; +using System.Xml.Linq; namespace Subsurface { @@ -20,6 +21,8 @@ namespace Subsurface public readonly GameMode gameMode; + private GUIFrame guiRoot; + private GUIListBox chatBox; private GUITextBox textBox; @@ -27,57 +30,76 @@ namespace Subsurface private GUIButton endShiftButton; - string saveFile; - + Map selectedMap; + private int day; - public string SaveFile - { - get { return saveFile; } - } + //public string SaveFile + //{ + // get { return saveFile; } + //} public int Day { get { return day; } } - public GameSession(string selectedMapFile, bool save, TimeSpan gameDuration, GameMode gameMode = null) + public GameSession(Map selectedMap, TimeSpan gameDuration, GameMode gameMode = null) { taskManager = new TaskManager(this); - crewManager = new CrewManager(this); + crewManager = new CrewManager(); hireManager = new HireManager(); 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; - chatBox = new GUIListBox(new Rectangle( - Game1.GraphicsWidth - (int)GUI.style.smallPadding.X - width, - Game1.GraphicsHeight - (int)GUI.style.smallPadding.W*2 - 25 - height, - width, height), - Color.White * 0.5f); + if (Game1.Client!=null || Game1.Server!=null) + { + chatBox = new GUIListBox(new Rectangle( + Game1.GraphicsWidth - (int)GUI.style.smallPadding.X - width, + Game1.GraphicsHeight - (int)GUI.style.smallPadding.W*2 - 25 - height, + width, height), + Color.White * 0.5f, guiRoot); - endShiftButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 240, 20, 100, 25), "End shift", Color.White, Alignment.CenterX, null); - endShiftButton.OnClicked = EndShift; + textBox = new GUITextBox( + new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + (int)GUI.style.smallPadding.W, chatBox.Rect.Width, 25), + Color.White * 0.5f, Color.Black, Alignment.Bottom, Alignment.Left, guiRoot); + textBox.OnEnter = EnterChatMessage; + } - timerBar = new GUIProgressBar(new Rectangle(Game1.GraphicsWidth - 120, 20, 100, 25), Color.Gold, 0.0f, null); + 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); - textBox = new GUITextBox( - new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + (int)GUI.style.smallPadding.W, chatBox.Rect.Width, 25), - Color.White * 0.5f, Color.Black, Alignment.Bottom, Alignment.Left); - textBox.OnEnter = EnterChatMessage; this.gameMode = gameMode; if (this.gameMode != null) this.gameMode.Start(Game1.NetLobbyScreen.GameDuration); startTime = DateTime.Now; - endTime = startTime + gameDuration; + endTime = startTime + gameDuration; - if (!save) return; - - CreateSaveFile(selectedMapFile); - - day = 1; + this.selectedMap = selectedMap; + //if (!save) return; + + //CreateSaveFile(selectedMapFile); + + day = 1; + } + + public GameSession(string filePath) + : this(null, new TimeSpan(0,0,0,0)) + { + XDocument doc = ToolBox.TryLoadXml(filePath); + if (doc == null) return; + + day = ToolBox.GetAttributeInt(doc.Root,"day",1); } public bool TryHireCharacter(CharacterInfo characterInfo) @@ -101,6 +123,8 @@ namespace Subsurface { if (crewManager.characterInfos.Count == 0) return; + if (Map.Loaded!=selectedMap) selectedMap.Load(); + crewManager.StartShift(); taskManager.StartShift(scriptedEventCount); } @@ -135,9 +159,9 @@ namespace Subsurface new GUIMessageBox("Day #" + day + " is over!\n", sb.ToString()); - if (saveFile == null) return false; + //if (saveFile == null) return false; - Map.Loaded.SaveAs(saveFile); + //Map.Loaded.SaveAs(saveFile); crewManager.EndShift(); @@ -146,6 +170,11 @@ namespace Subsurface day++; } + for (int i = Character.characterList.Count - 1; i >= 0; i--) + { + Character.characterList.RemoveAt(i); + } + taskManager.EndShift(); return true; @@ -153,33 +182,33 @@ namespace Subsurface private void CreateSaveFile(string mapName) { - string path = "Content/Data/Saves/"; + //string path = "Content/Data/Saves/"; - if (!Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } + //if (!Directory.Exists(path)) + //{ + // Directory.CreateDirectory(path); + //} - string name = Path.GetFileNameWithoutExtension(mapName); - string extension = Path.GetExtension(mapName); + //string name = Path.GetFileNameWithoutExtension(mapName); + //string extension = Path.GetExtension(mapName); - int i = 0; - while (File.Exists(path + name + i + extension)) - { - i++; - } + //int i = 0; + //while (File.Exists(path + name + i + extension)) + //{ + // i++; + //} - saveFile = path + name + i+extension; + //saveFile = path + name + i+extension; - try - { - File.Copy(mapName, saveFile); - } - catch (Exception e) - { - DebugConsole.ThrowError("Copying map file ''" + mapName + "'' to ''" + saveFile + "'' failed", e); - } + //try + //{ + // File.Copy(mapName, saveFile); + //} + //catch (Exception e) + //{ + // DebugConsole.ThrowError("Copying map file ''" + mapName + "'' to ''" + saveFile + "'' failed", e); + //} } public bool EnterChatMessage(GUITextBox textBox, string message) @@ -218,11 +247,14 @@ namespace Subsurface public void Update(float deltaTime) { taskManager.Update(deltaTime); - endShiftButton.Enabled = !taskManager.CriticalTasks; + if (endShiftButton!=null) endShiftButton.Enabled = !taskManager.CriticalTasks; - endShiftButton.Update(deltaTime); + + guiRoot.Update(deltaTime); + crewManager.Update(deltaTime); + //endShiftButton.Update(deltaTime); - textBox.Update(deltaTime); + //textBox.Update(deltaTime); if (gameMode != null) gameMode.Update(); @@ -246,15 +278,33 @@ namespace Subsurface public void Draw(SpriteBatch spriteBatch) { + guiRoot.Draw(spriteBatch); crewManager.Draw(spriteBatch); taskManager.Draw(spriteBatch); - chatBox.Draw(spriteBatch); - textBox.Draw(spriteBatch); + //chatBox.Draw(spriteBatch); + //textBox.Draw(spriteBatch); - timerBar.Draw(spriteBatch); + //timerBar.Draw(spriteBatch); - if (Game1.Client == null) endShiftButton.Draw(spriteBatch); + //if (Game1.Client == null) endShiftButton.Draw(spriteBatch); + } + + public void Save(string filePath) + { + XDocument doc = new XDocument( + new XElement((XName)"Gamesession")); + + doc.Root.Add(new XAttribute("day", day)); + + try + { + doc.Save(filePath); + } + catch + { + DebugConsole.ThrowError("Saving gamesession to ''" + filePath + "'' failed!"); + } } } } diff --git a/Subsurface/Items/Components/Container.cs b/Subsurface/Items/Components/Container.cs index 63c6a12db..288470e32 100644 --- a/Subsurface/Items/Components/Container.cs +++ b/Subsurface/Items/Components/Container.cs @@ -115,47 +115,13 @@ namespace Subsurface.Items.Components foreach (StatusEffect effect in ri.statusEffects) { - if (effect.Targets.HasFlag(StatusEffect.Target.This)) effect.Apply(ActionType.OnContaining, deltaTime, item); - if (effect.Targets.HasFlag(StatusEffect.Target.Contained)) effect.Apply(ActionType.OnContaining, deltaTime, contained); + if (effect.Targets.HasFlag(StatusEffect.TargetType.This)) effect.Apply(ActionType.OnContaining, deltaTime, item.SimPosition, item.AllPropertyObjects); + if (effect.Targets.HasFlag(StatusEffect.TargetType.Contained)) effect.Apply(ActionType.OnContaining, deltaTime, item.SimPosition, contained.AllPropertyObjects); } contained.ApplyStatusEffects(ActionType.OnContained, deltaTime); } - //if (hideItems) return; - - //Vector2 transformedItemPos; - //Vector2 transformedItemInterval = itemInterval; - ////float transformedItemRotation = itemRotation; - //if (item.body==null) - //{ - // transformedItemPos = new Vector2(item.Rect.X, item.Rect.Y); - // transformedItemPos = ConvertUnits.ToSimUnits(transformedItemPos) + itemPos; - //} - //else - //{ - // Matrix transform = Matrix.CreateRotationZ(item.body.Rotation); - - // transformedItemPos = item.body.Position + Vector2.Transform(itemPos, transform); - // transformedItemInterval = Vector2.Transform(transformedItemInterval, transform); - // //transformedItemRotation += item.body.Rotation; - //} - - //foreach (Item containedItem in inventory.items) - //{ - // if (containedItem == null) continue; - - // Vector2 itemDist = (transformedItemPos - containedItem.body.Position); - // Vector2 force = (itemDist - containedItem.body.LinearVelocity * 0.1f) * containedItem.body.Mass * 60.0f; - - // containedItem.body.ApplyForce(force); - - // containedItem.body.SmoothRotate(itemRotation); - - // transformedItemPos += transformedItemInterval; - //} - - } public override void Draw(SpriteBatch spriteBatch) diff --git a/Subsurface/Items/Components/Door.cs b/Subsurface/Items/Components/Door.cs index 69d84c23a..aa6bd1cbd 100644 --- a/Subsurface/Items/Components/Door.cs +++ b/Subsurface/Items/Components/Door.cs @@ -233,9 +233,12 @@ namespace Subsurface.Items.Components public override void Update(float deltaTime, Camera cam) { - OpenState += deltaTime * ((isOpen) ? 3.0f : -3.0f); + if (!isStuck) + { + OpenState += deltaTime * ((isOpen) ? 3.0f : -3.0f); + LinkedGap.Open = openState; + } - LinkedGap.Open = openState; item.SendSignal((isOpen) ? "1" : "0", "state_out"); } @@ -309,8 +312,6 @@ namespace Subsurface.Items.Components public override void ReceiveSignal(string signal, Connection connection, Item sender) { - if (isStuck) return; - if (connection.name=="toggle") { isOpen = !isOpen; diff --git a/Subsurface/Items/Components/ItemComponent.cs b/Subsurface/Items/Components/ItemComponent.cs index 9e79166f7..5e7763ff8 100644 --- a/Subsurface/Items/Components/ItemComponent.cs +++ b/Subsurface/Items/Components/ItemComponent.cs @@ -291,7 +291,13 @@ namespace Subsurface return false; } - public virtual void Remove() { } + public virtual void Remove() + { + if (loopingSound!=null) + { + Sounds.SoundManager.Stop(loopingSoundIndex); + } + } public bool HasRequiredContainedItems(bool addMessage) { diff --git a/Subsurface/Items/Components/RepairTool.cs b/Subsurface/Items/Components/RepairTool.cs index 37049cb64..9571498ba 100644 --- a/Subsurface/Items/Components/RepairTool.cs +++ b/Subsurface/Items/Components/RepairTool.cs @@ -147,8 +147,8 @@ namespace Subsurface.Items.Components foreach (StatusEffect effect in statusEffects) { - if (Array.IndexOf(effect.TargetNames, targetItem.Name) == -1) continue; - effect.Apply(ActionType.OnUse, deltaTime, targetItem); + //if (Array.IndexOf(effect.TargetNames, targetItem.Name) == -1) continue; + effect.Apply(ActionType.OnUse, deltaTime, item.SimPosition, targetItem.AllPropertyObjects); //targetItem.ApplyStatusEffect(effect, ActionType.OnUse, deltaTime); } //ApplyStatusEffects(ActionType.OnUse, 1.0f, null, targ); diff --git a/Subsurface/Items/Components/Wearable.cs b/Subsurface/Items/Components/Wearable.cs index ae3bb018f..db693fd27 100644 --- a/Subsurface/Items/Components/Wearable.cs +++ b/Subsurface/Items/Components/Wearable.cs @@ -115,22 +115,14 @@ namespace Subsurface.Items.Components Item[] containedItems = item.ContainedItems; + ApplyStatusEffects(ActionType.OnWearing, deltaTime, picker); - for (int i = 0; i < limb.Length; i++) + if (containedItems == null) return; + for (int j = 0; j AllPropertyObjects + { + get + { + List pobjects = new List(); + pobjects.Add(this); + foreach (ItemComponent ic in components) + { + pobjects.Add(ic); + } + return pobjects; + } + } + List highlightText; public List HighlightText @@ -334,9 +348,11 @@ namespace Subsurface } } + List targets = new List(); + if (containedItems!=null) { - if (effect.Targets.HasFlag(StatusEffect.Target.Contained)) + if (effect.Targets.HasFlag(StatusEffect.TargetType.Contained)) { foreach (Item containedItem in containedItems) { @@ -344,7 +360,8 @@ namespace Subsurface if (effect.TargetNames != null && !effect.TargetNames.Contains(containedItem.Name)) continue; hasTargets = true; - effect.Apply(type, deltaTime, containedItem); + targets.Add(containedItem); + //effect.Apply(type, deltaTime, containedItem); //containedItem.ApplyStatusEffect(effect, type, deltaTime, containedItem); } } @@ -353,19 +370,27 @@ namespace Subsurface if (hasTargets) { - if (effect.Targets.HasFlag(StatusEffect.Target.This)) - effect.Apply(type, deltaTime, this); + if (effect.Targets.HasFlag(StatusEffect.TargetType.This)) + { + foreach (var pobject in AllPropertyObjects) + { + targets.Add(pobject); + } + } + //effect.Apply(type, deltaTime, this); //ApplyStatusEffect(effect, type, deltaTime, this); - if (effect.Targets.HasFlag(StatusEffect.Target.Character)) - effect.Apply(type, deltaTime, null, character); + if (effect.Targets.HasFlag(StatusEffect.TargetType.Character)) targets.Add(character); + //effect.Apply(type, deltaTime, null, character); //ApplyStatusEffect(effect, type, deltaTime, null, character, limb); - if (container != null && effect.Targets.HasFlag(StatusEffect.Target.Parent)) - { - effect.Apply(type, deltaTime, container); - //container.ApplyStatusEffect(effect, type, deltaTime, container); - } + if (container != null && effect.Targets.HasFlag(StatusEffect.TargetType.Parent)) targets.Add(container); + //{ + // effect.Apply(type, deltaTime, container); + // //container.ApplyStatusEffect(effect, type, deltaTime, container); + //} + + effect.Apply(type, deltaTime, SimPosition, targets); } } diff --git a/Subsurface/Map/Map.cs b/Subsurface/Map/Map.cs index e5d28e9cb..0ea5ad66f 100644 --- a/Subsurface/Map/Map.cs +++ b/Subsurface/Map/Map.cs @@ -62,6 +62,8 @@ namespace Subsurface { get { + if (mapHash != null) return mapHash; + XDocument doc = OpenDoc(filePath); mapHash = new MapHash(doc); @@ -286,8 +288,7 @@ namespace Subsurface try { - //string docString = doc.ToString(); - ToolBox.CompressStringToFile(filePath, doc.ToString()); + SaveUtil.CompressStringToFile(filePath, doc.ToString()); } catch { @@ -388,7 +389,7 @@ namespace Subsurface if (extension == ".gz") { - Stream stream = ToolBox.DecompressFiletoStream(file); + Stream stream = SaveUtil.DecompressFiletoStream(file); if (stream == null) { DebugConsole.ThrowError("Loading map ''" + file + "'' failed!"); @@ -504,7 +505,7 @@ namespace Subsurface public static void Unload() { - if (loaded==null)return; + if (loaded == null) return; loaded.Clear(); loaded = null; } diff --git a/Subsurface/Networking/GameClient.cs b/Subsurface/Networking/GameClient.cs index 2a2081060..eae49a78e 100644 --- a/Subsurface/Networking/GameClient.cs +++ b/Subsurface/Networking/GameClient.cs @@ -240,7 +240,7 @@ namespace Subsurface.Networking TimeSpan duration = new TimeSpan(0,(int)durationMinutes,0); //int gameModeIndex = inc.ReadInt32(); - Game1.GameSession = new GameSession("", false, duration); + Game1.GameSession = new GameSession(Map.Loaded, duration); Game1.GameSession.StartShift(1); myCharacter = ReadCharacterData(inc); diff --git a/Subsurface/Networking/GameServer.cs b/Subsurface/Networking/GameServer.cs index fe9dd925c..8704f091b 100644 --- a/Subsurface/Networking/GameServer.cs +++ b/Subsurface/Networking/GameServer.cs @@ -273,9 +273,9 @@ namespace Subsurface.Networking Map selectedMap = Game1.NetLobbyScreen.SelectedMap as Map; - selectedMap.Load(); + //selectedMap.Load(); - Game1.GameSession = new GameSession("", false, Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.SelectedMode); + Game1.GameSession = new GameSession(selectedMap, Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.SelectedMode); Game1.GameSession.StartShift(1); //EventManager.SelectEvent(Game1.netLobbyScreen.SelectedEvent); diff --git a/Subsurface/SaveUtil.cs b/Subsurface/SaveUtil.cs new file mode 100644 index 000000000..81678ab23 --- /dev/null +++ b/Subsurface/SaveUtil.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; + +namespace Subsurface +{ + class SaveUtil + { + public delegate void ProgressDelegate(string sMessage); + + public static void SaveGame(string directory) + { + if (Directory.Exists(directory)) + { + Directory.Delete(directory, true); + } + + Directory.CreateDirectory(directory); + + Map.Loaded.SaveAs(directory+"\\map.gz"); + + Game1.GameSession.crewManager.Save(directory+"\\crew.xml"); + + CompressDirectory(directory, directory+".save", null); + + Directory.Delete(directory, true); + } + + public static void LoadGame(string filePath) + { + DecompressToDirectory(filePath+".save", Path.GetDirectoryName(filePath)+"\\temp", null); + + Map.Load(Path.GetDirectoryName(filePath) + "\\temp\\map.gz"); + Game1.GameSession = new GameSession(Path.GetDirectoryName(filePath) + "\\temp\\map.gz"); + } + + public static string CreateSavePath(string saveFolder, string fileName="save") + { + if (!Directory.Exists(saveFolder)) + { + DebugConsole.ThrowError("Save folder ''"+saveFolder+"'' not found. Created new folder"); + Directory.CreateDirectory(saveFolder); + } + + string extension = ".save"; + + int i = 0; + while (File.Exists(saveFolder + fileName + i + extension)) + { + i++; + } + + return saveFolder + fileName + i + extension; + } + + public static void CompressStringToFile(string fileName, string value) + { + // A. + // Write string to temporary file. + string temp = Path.GetTempFileName(); + File.WriteAllText(temp, value); + + // B. + // Read file into byte array buffer. + byte[] b; + using (FileStream f = new FileStream(temp, FileMode.Open)) + { + b = new byte[f.Length]; + f.Read(b, 0, (int)f.Length); + } + + // C. + // Use GZipStream to write compressed bytes to target file. + using (FileStream f2 = new FileStream(fileName, FileMode.Create)) + using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false)) + { + gz.Write(b, 0, b.Length); + } + } + + public static Stream DecompressFiletoStream(string fileName) + { + if (!File.Exists(fileName)) + { + DebugConsole.ThrowError("File ''"+fileName+" doesn't exist!"); + return null; + } + + using (FileStream originalFileStream = new FileStream(fileName, FileMode.Open)) + { + MemoryStream decompressedFileStream = new MemoryStream(); + + using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress)) + { + decompressionStream.CopyTo(decompressedFileStream); + return decompressedFileStream; + } + } + } + + public static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream) + { + //Compress file name + char[] chars = sRelativePath.ToCharArray(); + zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int)); + foreach (char c in chars) + zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char)); + + //Compress file content + byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath)); + zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int)); + zipStream.Write(bytes, 0, bytes.Length); + } + + public static bool DecompressFile(string sDir, GZipStream zipStream, ProgressDelegate progress) + { + //Decompress file name + byte[] bytes = new byte[sizeof(int)]; + int Readed = zipStream.Read(bytes, 0, sizeof(int)); + if (Readed < sizeof(int)) + return false; + + int iNameLen = BitConverter.ToInt32(bytes, 0); + bytes = new byte[sizeof(char)]; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < iNameLen; i++) + { + zipStream.Read(bytes, 0, sizeof(char)); + char c = BitConverter.ToChar(bytes, 0); + sb.Append(c); + } + string sFileName = sb.ToString(); + if (progress != null) + progress(sFileName); + + //Decompress file content + bytes = new byte[sizeof(int)]; + zipStream.Read(bytes, 0, sizeof(int)); + int iFileLen = BitConverter.ToInt32(bytes, 0); + + bytes = new byte[iFileLen]; + zipStream.Read(bytes, 0, bytes.Length); + + string sFilePath = Path.Combine(sDir, sFileName); + string sFinalDir = Path.GetDirectoryName(sFilePath); + if (!Directory.Exists(sFinalDir)) + Directory.CreateDirectory(sFinalDir); + + using (FileStream outFile = new FileStream(sFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + outFile.Write(bytes, 0, iFileLen); + + return true; + } + + public static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress) + { + string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories); + int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1; + + using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None)) + using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress)) + foreach (string sFilePath in sFiles) + { + string sRelativePath = sFilePath.Substring(iDirLen); + if (progress != null) + progress(sRelativePath); + CompressFile(sInDir, sRelativePath, str); + } + } + + public static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress) + { + using (FileStream inFile = new FileStream(sCompressedFile, FileMode.Open, FileAccess.Read, FileShare.None)) + using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true)) + while (DecompressFile(sDir, zipStream, progress)) ; + } + } +} diff --git a/Subsurface/Screens/LobbyScreen.cs b/Subsurface/Screens/LobbyScreen.cs index bb33a69b7..f2233466a 100644 --- a/Subsurface/Screens/LobbyScreen.cs +++ b/Subsurface/Screens/LobbyScreen.cs @@ -96,7 +96,7 @@ namespace Subsurface { base.Select(); - Map.Unload(); + //Map.Unload(); UpdateCharacterLists(); @@ -222,7 +222,8 @@ namespace Subsurface private bool StartShift(GUIButton button, object selection) { - Map.Load(Game1.GameSession.SaveFile); + + //Map.Load(Game1.GameSession.SaveFile); Game1.GameSession.StartShift(); diff --git a/Subsurface/Screens/MainMenu.cs b/Subsurface/Screens/MainMenu.cs index c3eddf30e..7e9ef24f1 100644 --- a/Subsurface/Screens/MainMenu.cs +++ b/Subsurface/Screens/MainMenu.cs @@ -55,23 +55,20 @@ namespace Subsurface 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]); - //string[] mapFilePaths = Map.GetMapFilePaths(); - //if (mapFilePaths!=null) - //{ - foreach (Map map in Map.SavedMaps) - { - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 0, 25), - map.Name, - GUI.style, - Alignment.Left, - Alignment.Left, - mapList); - textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); - textBlock.UserData = map; - } - if (Map.SavedMaps.Count > 0) mapList.Select(Map.SavedMaps[0]); - //} + foreach (Map map in Map.SavedMaps) + { + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + map.Name, + GUI.style, + Alignment.Left, + Alignment.Left, + mapList); + textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); + textBlock.UserData = map; + } + if (Map.SavedMaps.Count > 0) mapList.Select(Map.SavedMaps[0]); + button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", GUI.style, Alignment.Right | Alignment.Bottom, menuTabs[(int)Tabs.NewGame]); button.OnClicked = StartGame; @@ -150,7 +147,7 @@ namespace Subsurface if (selectedMap == null) return false; - Game1.GameSession = new GameSession(selectedMap.FilePath, true, TimeSpan.Zero); + Game1.GameSession = new GameSession(selectedMap, TimeSpan.Zero); Game1.LobbyScreen.Select(); diff --git a/Subsurface/Screens/NetLobbyScreen.cs b/Subsurface/Screens/NetLobbyScreen.cs index 9a81b0b9b..4992832d9 100644 --- a/Subsurface/Screens/NetLobbyScreen.cs +++ b/Subsurface/Screens/NetLobbyScreen.cs @@ -6,6 +6,7 @@ using Subsurface.Networking; using FarseerPhysics; using FarseerPhysics.Factories; using FarseerPhysics.Dynamics; +using System.IO; namespace Subsurface { @@ -472,7 +473,7 @@ namespace Subsurface } else { - msg.Write(selectedMap.Name); + msg.Write(Path.GetFileName(selectedMap.FilePath)); msg.Write(selectedMap.MapHash.MD5Hash); } @@ -502,7 +503,7 @@ namespace Subsurface else { mapList.Select(map); - map.Load(); + //map.Load(); return true; } } diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 5cfeb61e0..ef430e917 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -133,6 +133,7 @@ + @@ -187,6 +188,9 @@ False .\FarseerPhysics MonoGame.dll + + C:\Users\Joonas\Desktop\SharpZipLib_0860_Bin\net-20\ICSharpCode.SharpZipLib.dll + False .\Lidgren.Network.dll @@ -218,16 +222,28 @@ PreserveNewest - + + PreserveNewest + + PreserveNewest PreserveNewest - + PreserveNewest - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + PreserveNewest @@ -271,6 +287,12 @@ PreserveNewest Designer + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Subsurface/ToolBox.cs b/Subsurface/ToolBox.cs index 245368bd8..57b9bdd3d 100644 --- a/Subsurface/ToolBox.cs +++ b/Subsurface/ToolBox.cs @@ -128,50 +128,50 @@ namespace Subsurface } - public static void CompressStringToFile(string fileName, string value) - { - // A. - // Write string to temporary file. - string temp = Path.GetTempFileName(); - File.WriteAllText(temp, value); + //public static void CompressStringToFile(string fileName, string value) + //{ + // // A. + // // Write string to temporary file. + // string temp = Path.GetTempFileName(); + // File.WriteAllText(temp, value); - // B. - // Read file into byte array buffer. - byte[] b; - using (FileStream f = new FileStream(temp, FileMode.Open)) - { - b = new byte[f.Length]; - f.Read(b, 0, (int)f.Length); - } + // // B. + // // Read file into byte array buffer. + // byte[] b; + // using (FileStream f = new FileStream(temp, FileMode.Open)) + // { + // b = new byte[f.Length]; + // f.Read(b, 0, (int)f.Length); + // } - // C. - // Use GZipStream to write compressed bytes to target file. - using (FileStream f2 = new FileStream(fileName, FileMode.Create)) - using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false)) - { - gz.Write(b, 0, b.Length); - } - } + // // C. + // // Use GZipStream to write compressed bytes to target file. + // using (FileStream f2 = new FileStream(fileName, FileMode.Create)) + // using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false)) + // { + // gz.Write(b, 0, b.Length); + // } + //} - public static Stream DecompressFiletoStream(string fileName) - { - if (!File.Exists(fileName)) - { - DebugConsole.ThrowError("File ''"+fileName+" doesn't exist!"); - return null; - } + //public static Stream DecompressFiletoStream(string fileName) + //{ + // if (!File.Exists(fileName)) + // { + // DebugConsole.ThrowError("File ''"+fileName+" doesn't exist!"); + // return null; + // } - using (FileStream originalFileStream = new FileStream(fileName, FileMode.Open)) - { - MemoryStream decompressedFileStream = new MemoryStream(); + // using (FileStream originalFileStream = new FileStream(fileName, FileMode.Open)) + // { + // MemoryStream decompressedFileStream = new MemoryStream(); - using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress)) - { - decompressionStream.CopyTo(decompressedFileStream); - return decompressedFileStream; - } - } - } + // using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress)) + // { + // decompressionStream.CopyTo(decompressedFileStream); + // return decompressedFileStream; + // } + // } + //} public static XDocument TryLoadXml(string filePath) { diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 248f75092..605d748b4 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ