diff --git a/Subsurface/Characters/Character.cs b/Subsurface/Characters/Character.cs index 2d54ed133..bd9102e62 100644 --- a/Subsurface/Characters/Character.cs +++ b/Subsurface/Characters/Character.cs @@ -74,7 +74,20 @@ namespace Subsurface //the name of the species (e.q. human) public readonly string SpeciesName; - public CharacterInfo Info; + private CharacterInfo info; + + public CharacterInfo Info + { + get + { + return info; + } + set + { + info = value; + if (info != null) info.Character = this; + } + } protected float soundTimer; protected float soundInterval; @@ -366,6 +379,17 @@ namespace Subsurface } } + if (Info.PickedItemIDs.Any()) + { + foreach (int id in Info.PickedItemIDs) + { + Item item = FindEntityByID(id) as Item; + if (item == null) continue; + + item.Pick(this); + } + } + AnimController.FindHull(); //if (info.ID >= 0) @@ -525,18 +549,21 @@ namespace Subsurface cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition); Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); - - Body body = Submarine.PickBody(AnimController.limbs[0].SimPosition, mouseSimPos); - Structure structure = null; - if (body != null) structure = body.UserData as Structure; - if (structure!=null) + if (Vector2.Distance(AnimController.limbs[0].SimPosition, mouseSimPos)>1.0f) { - if (!structure.CastShadow && moveCam) + Body body = Submarine.PickBody(AnimController.limbs[0].SimPosition, mouseSimPos); + Structure structure = null; + if (body != null) structure = body.UserData as Structure; + if (structure!=null) { - cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 500.0f, 0.05f); + if (!structure.CastShadow && moveCam) + { + cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 500.0f, 0.05f); + } } } + if (AnimController.onGround && !AnimController.InWater && AnimController.Anim != AnimController.Animation.UsingConstruction) @@ -664,14 +691,19 @@ namespace Subsurface if (IsNetworkPlayer) { - 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); + 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 (Game1.DebugDraw) + { + spriteBatch.DrawString(GUI.Font, ID.ToString(), namePos - new Vector2(0.0f, 20.0f), Color.White); + } } Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition); pos.Y = -pos.Y; - spriteBatch.DrawString(GUI.font, ID.ToString(), pos, Color.White); + if (this == Character.controlled) return; @@ -714,18 +746,18 @@ namespace Subsurface Vector2 textPos = startPos; - float stringWidth = GUI.font.MeasureString(closestItem.Prefab.Name).X; + float stringWidth = GUI.Font.MeasureString(closestItem.Prefab.Name).X; textPos -= new Vector2(stringWidth / 2, 20); - spriteBatch.DrawString(GUI.font, closestItem.Prefab.Name, textPos, Color.Black); - spriteBatch.DrawString(GUI.font, closestItem.Prefab.Name, textPos + new Vector2(1, -1), Color.Orange); + spriteBatch.DrawString(GUI.Font, closestItem.Prefab.Name, textPos, Color.Black); + spriteBatch.DrawString(GUI.Font, closestItem.Prefab.Name, textPos + new Vector2(1, -1), Color.Orange); textPos.Y += 50.0f; - foreach (string text in closestItem.HighlightText) + foreach (ColoredText coloredText in closestItem.GetHUDTexts(Controlled)) { - textPos.X = startPos.X - GUI.font.MeasureString(text).X / 2; + textPos.X = startPos.X - GUI.Font.MeasureString(coloredText.text).X / 2; - spriteBatch.DrawString(GUI.font, text, textPos, Color.Black); - spriteBatch.DrawString(GUI.font, text, textPos + new Vector2(1, -1), Color.Orange); + spriteBatch.DrawString(GUI.Font, coloredText.text, textPos, Color.Black); + spriteBatch.DrawString(GUI.Font, coloredText.text, textPos + new Vector2(1, -1), coloredText.color); textPos.Y += 25; } diff --git a/Subsurface/Characters/CharacterInfo.cs b/Subsurface/Characters/CharacterInfo.cs index 947a58083..67660c959 100644 --- a/Subsurface/Characters/CharacterInfo.cs +++ b/Subsurface/Characters/CharacterInfo.cs @@ -1,4 +1,5 @@ using Microsoft.Xna.Framework; +using System.Collections.Generic; using System.Xml.Linq; namespace Subsurface @@ -9,12 +10,18 @@ namespace Subsurface { public string Name; + public Character Character; + public readonly string File; public int HeadSpriteId; public Job Job; + private List pickedItems; + + private Vector2[] headSpriteRange; + private Gender gender; public Gender Gender { @@ -23,6 +30,17 @@ namespace Subsurface { if (gender == value) return; gender = value; + + int genderIndex = (this.gender == Gender.Female) ? 1 : 0; + if (headSpriteRange[genderIndex] != Vector2.Zero) + { + HeadSpriteId = Rand.Range((int)headSpriteRange[genderIndex].X, (int)headSpriteRange[genderIndex].Y + 1); + } + else + { + HeadSpriteId = 0; + } + LoadHeadSprite(); } } @@ -31,10 +49,10 @@ namespace Subsurface public bool StartItemsGiven; - //public string GenderString() - //{ - // return gender.ToString(); - //} + public List PickedItemIDs + { + get { return pickedItems; } + } private Sprite headSprite; public Sprite HeadSprite @@ -50,6 +68,10 @@ namespace Subsurface { this.File = file; + headSpriteRange = new Vector2[2]; + + pickedItems = new List(); + //ID = -1; XDocument doc = ToolBox.TryLoadXml(file); @@ -69,19 +91,19 @@ namespace Subsurface this.gender = gender; } } - - Vector2 headSpriteRange = ToolBox.GetAttributeVector2(doc.Root, "headid", Vector2.Zero); - if (headSpriteRange == Vector2.Zero) + + headSpriteRange[0] = ToolBox.GetAttributeVector2(doc.Root, "headid", Vector2.Zero); + headSpriteRange[1] = headSpriteRange[0]; + if (headSpriteRange[0] == Vector2.Zero) { - headSpriteRange = ToolBox.GetAttributeVector2( - doc.Root, - this.gender == Gender.Female ? "femaleheadid" : "maleheadid", - Vector2.Zero); + headSpriteRange[0] = ToolBox.GetAttributeVector2(doc.Root, "maleheadid", Vector2.Zero); + headSpriteRange[1] = ToolBox.GetAttributeVector2(doc.Root, "femaleheadid", Vector2.Zero); } - if (headSpriteRange != Vector2.Zero) + int genderIndex = (this.gender == Gender.Female) ? 1 : 0; + if (headSpriteRange[genderIndex] != Vector2.Zero) { - HeadSpriteId = Rand.Range((int)headSpriteRange.X, (int)headSpriteRange.Y + 1); + HeadSpriteId = Rand.Range((int)headSpriteRange[genderIndex].X, (int)headSpriteRange[genderIndex].Y + 1); } this.Job = (jobPrefab == null) ? Job.Random() : new Job(jobPrefab); @@ -167,18 +189,40 @@ namespace Subsurface return frame; } + public void UpdateCharacterItems() + { + pickedItems.Clear(); + foreach (Item item in Character.Inventory.items) + { + if (item == null) continue; + pickedItems.Add(item.ID); + } + } + public CharacterInfo(XElement element) { Name = ToolBox.GetAttributeString(element, "name", "unnamed"); string genderStr = ToolBox.GetAttributeString(element, "gender", "male").ToLower(); - gender = (genderStr == "male") ? Gender.Male : Gender.Female; + gender = (genderStr == "m") ? Gender.Male : Gender.Female; File = ToolBox.GetAttributeString(element, "file", ""); Salary = ToolBox.GetAttributeInt(element, "salary", 1000); HeadSpriteId = ToolBox.GetAttributeInt(element, "headspriteid", 1); StartItemsGiven = ToolBox.GetAttributeBool(element, "startitemsgiven", false); + pickedItems = new List(); + + string pickedItemString = ToolBox.GetAttributeString(element, "items", ""); + if (!string.IsNullOrEmpty(pickedItemString)) + { + string[] itemIds = pickedItemString.Split(','); + foreach (string s in itemIds) + { + pickedItems.Add(int.Parse(s)); + } + } + foreach (XElement subElement in element.Elements()) { if (subElement.Name.ToString().ToLower() != "job") continue; @@ -195,11 +239,23 @@ namespace Subsurface charElement.Add( new XAttribute("name", Name), new XAttribute("file", File), - new XAttribute("gender", gender == Gender.Male ? "male" : "female"), + new XAttribute("gender", gender == Gender.Male ? "m" : "f"), new XAttribute("salary", Salary), new XAttribute("headspriteid", HeadSpriteId), new XAttribute("startitemsgiven", StartItemsGiven)); + if (Character!=null && Character.Inventory!=null) + { + UpdateCharacterItems(); + } + + if (pickedItems.Count>0) + { + charElement.Add(new XAttribute("items", string.Join(",", pickedItems))); + } + + + Job.Save(charElement); parentElement.Add(charElement); diff --git a/Subsurface/Characters/FishAnimController.cs b/Subsurface/Characters/FishAnimController.cs index 3a2be93df..8448ecefe 100644 --- a/Subsurface/Characters/FishAnimController.cs +++ b/Subsurface/Characters/FishAnimController.cs @@ -336,8 +336,8 @@ namespace Subsurface Limb head = GetLimb(LimbType.Head); Limb tail = GetLimb(LimbType.Tail); - head.body.ApplyTorque(head.Mass * Dir * 0.1f); - tail.body.ApplyTorque(tail.Mass * -Dir * 0.1f); + if (head != null) head.body.ApplyTorque(head.Mass * Dir * 0.1f); + if (tail != null) tail.body.ApplyTorque(tail.Mass * -Dir * 0.1f); } public override void Flip() diff --git a/Subsurface/Characters/Jobs/Job.cs b/Subsurface/Characters/Jobs/Job.cs index 2e97c48de..984715e10 100644 --- a/Subsurface/Characters/Jobs/Job.cs +++ b/Subsurface/Characters/Jobs/Job.cs @@ -84,6 +84,7 @@ namespace Subsurface string name = ToolBox.GetAttributeString(element, "name", "").ToLower(); prefab = JobPrefab.List.Find(jp => jp.Name.ToLower() == name); + skills = new Dictionary(); foreach (XElement subElement in element.Elements()) { if (subElement.Name.ToString().ToLower() != "skill") continue; diff --git a/Subsurface/Characters/Ragdoll.cs b/Subsurface/Characters/Ragdoll.cs index 937e7649d..281c328f5 100644 --- a/Subsurface/Characters/Ragdoll.cs +++ b/Subsurface/Characters/Ragdoll.cs @@ -67,9 +67,17 @@ namespace Subsurface public Vector2 TargetMovement { - get { return (correctionMovement == Vector2.Zero) ? targetMovement : correctionMovement; } + get + { + return (correctionMovement == Vector2.Zero) ? targetMovement : correctionMovement; + } set { + if (float.IsNaN(value.X) || float.IsNaN(value.Y)) + { + targetMovement = Vector2.Zero; + return; + } targetMovement.X = MathHelper.Clamp(value.X, -3.0f, 3.0f); targetMovement.Y = MathHelper.Clamp(value.Y, -3.0f, 3.0f); } @@ -574,6 +582,7 @@ namespace Subsurface else { correctionMovement = Vector2.Normalize(newMovement) * ((targetMovement == Vector2.Zero) ? 1.0f : targetMovement.Length()); + } } diff --git a/Subsurface/Content/Items/Button/item.xml b/Subsurface/Content/Items/Button/button.xml similarity index 70% rename from Subsurface/Content/Items/Button/item.xml rename to Subsurface/Content/Items/Button/button.xml index 3e4a2c9e1..f381f6949 100644 --- a/Subsurface/Content/Items/Button/item.xml +++ b/Subsurface/Content/Items/Button/button.xml @@ -7,10 +7,10 @@ - + - + diff --git a/Subsurface/Content/Items/Door/door.png b/Subsurface/Content/Items/Door/door.png index 48ed55aeb..8a69d05d7 100644 Binary files a/Subsurface/Content/Items/Door/door.png and b/Subsurface/Content/Items/Door/door.png differ diff --git a/Subsurface/Content/Items/Door/doorframe.png b/Subsurface/Content/Items/Door/doorframe.png deleted file mode 100644 index 119ec3f85..000000000 Binary files a/Subsurface/Content/Items/Door/doorframe.png and /dev/null differ diff --git a/Subsurface/Content/Items/Door/doors.xml b/Subsurface/Content/Items/Door/doors.xml index f62eba26c..92cd50284 100644 --- a/Subsurface/Content/Items/Door/doors.xml +++ b/Subsurface/Content/Items/Door/doors.xml @@ -4,7 +4,7 @@ linkable="true" pickdistance="150.0"> - + @@ -12,7 +12,7 @@ - + @@ -26,7 +26,7 @@ linkable="true" pickdistance="150.0"> - + @@ -34,7 +34,7 @@ - + diff --git a/Subsurface/Content/Items/Door/windowedDoor.png b/Subsurface/Content/Items/Door/windowedDoor.png deleted file mode 100644 index f51c1401d..000000000 Binary files a/Subsurface/Content/Items/Door/windowedDoor.png and /dev/null differ diff --git a/Subsurface/Content/Items/Engine/engine.xml b/Subsurface/Content/Items/Engine/engine.xml index cb3318286..e5041f479 100644 --- a/Subsurface/Content/Items/Engine/engine.xml +++ b/Subsurface/Content/Items/Engine/engine.xml @@ -12,7 +12,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/Subsurface/Content/Items/MiniMap/item.xml b/Subsurface/Content/Items/MiniMap/item.xml index 82e32f95c..f21a5c0ce 100644 --- a/Subsurface/Content/Items/MiniMap/item.xml +++ b/Subsurface/Content/Items/MiniMap/item.xml @@ -10,7 +10,7 @@ - + diff --git a/Subsurface/Content/Items/OxygenGenerator/item.xml b/Subsurface/Content/Items/OxygenGenerator/item.xml index 50a16e7b0..8a70b26ee 100644 --- a/Subsurface/Content/Items/OxygenGenerator/item.xml +++ b/Subsurface/Content/Items/OxygenGenerator/item.xml @@ -11,11 +11,11 @@ - + - + diff --git a/Subsurface/Content/Items/Pump/pump.xml b/Subsurface/Content/Items/Pump/pump.xml index f9bddd070..c38b83bc7 100644 --- a/Subsurface/Content/Items/Pump/pump.xml +++ b/Subsurface/Content/Items/Pump/pump.xml @@ -7,7 +7,7 @@ - + diff --git a/Subsurface/Content/Items/Reactor/reactor.xml b/Subsurface/Content/Items/Reactor/reactor.xml index 51f98f343..15ad3cfef 100644 --- a/Subsurface/Content/Items/Reactor/reactor.xml +++ b/Subsurface/Content/Items/Reactor/reactor.xml @@ -10,12 +10,12 @@ - + - + diff --git a/Subsurface/Content/Items/Tools/tools.xml b/Subsurface/Content/Items/Tools/tools.xml index d6ca8fe5f..6bcfc97f2 100644 --- a/Subsurface/Content/Items/Tools/tools.xml +++ b/Subsurface/Content/Items/Tools/tools.xml @@ -12,7 +12,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -86,7 +86,6 @@ Tags="smallitem" pickdistance="200"> - diff --git a/Subsurface/Content/Items/Weapons/weapons.xml b/Subsurface/Content/Items/Weapons/weapons.xml index 93bdd6a4c..654824ded 100644 --- a/Subsurface/Content/Items/Weapons/weapons.xml +++ b/Subsurface/Content/Items/Weapons/weapons.xml @@ -30,7 +30,7 @@ - + diff --git a/Subsurface/Content/Items/poweritems.xml b/Subsurface/Content/Items/poweritems.xml index 907bc87f1..447fe6533 100644 --- a/Subsurface/Content/Items/poweritems.xml +++ b/Subsurface/Content/Items/poweritems.xml @@ -12,7 +12,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/Subsurface/Content/UI/titleBackground.png b/Subsurface/Content/UI/titleBackground.png new file mode 100644 index 000000000..18f8e6b28 Binary files /dev/null and b/Subsurface/Content/UI/titleBackground.png differ diff --git a/Subsurface/Content/UI/titleMonster.png b/Subsurface/Content/UI/titleMonster.png new file mode 100644 index 000000000..905dfe87a Binary files /dev/null and b/Subsurface/Content/UI/titleMonster.png differ diff --git a/Subsurface/Content/UI/titleText.png b/Subsurface/Content/UI/titleText.png new file mode 100644 index 000000000..1310a8f02 Binary files /dev/null and b/Subsurface/Content/UI/titleText.png differ diff --git a/Subsurface/Content/randomevents.xml b/Subsurface/Content/randomevents.xml index 027a43ca1..13a283356 100644 --- a/Subsurface/Content/randomevents.xml +++ b/Subsurface/Content/randomevents.xml @@ -21,12 +21,4 @@ difficulty="30" starttimemin="15" starttimemax="20" musictype="monster"/> - - \ No newline at end of file diff --git a/Subsurface/DebugConsole.cs b/Subsurface/DebugConsole.cs index cf68caf93..c00a2bf9f 100644 --- a/Subsurface/DebugConsole.cs +++ b/Subsurface/DebugConsole.cs @@ -127,7 +127,7 @@ namespace Subsurface Vector2 messagePos = new Vector2(x + margin * 2, y + height - 70 - messages.Count()*20); foreach (ColoredText message in messages) { - spriteBatch.DrawString(GUI.font, message.text, messagePos, message.color); + spriteBatch.DrawString(GUI.Font, message.text, messagePos, message.color); messagePos.Y += 20; } @@ -210,7 +210,7 @@ namespace Subsurface } break; case "generatelevel": - Game1.Level = new Level("asdf", 500,500, 50); + Game1.Level = new Level("asdf", 50.0f, 500,500, 50); Game1.Level.Generate(100.0f); break; case "fowenabled": diff --git a/Subsurface/Events/ScriptedEvent.cs b/Subsurface/Events/ScriptedEvent.cs index 3dd7c7c04..eb7b56405 100644 --- a/Subsurface/Events/ScriptedEvent.cs +++ b/Subsurface/Events/ScriptedEvent.cs @@ -92,13 +92,11 @@ namespace Subsurface } - public static ScriptedEvent LoadRandom(string seed) + public static ScriptedEvent LoadRandom(Random rand) { XDocument doc = ToolBox.TryLoadXml(configFile); if (doc == null) return null; - - Random rand = new Random(seed.GetHashCode()); - + int eventCount = doc.Root.Elements().Count(); //int[] commonness = new int[eventCount]; float[] eventProbability = new float[eventCount]; diff --git a/Subsurface/Events/TaskManager.cs b/Subsurface/Events/TaskManager.cs index 8f94c3645..6474414ac 100644 --- a/Subsurface/Events/TaskManager.cs +++ b/Subsurface/Events/TaskManager.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System; namespace Subsurface { @@ -61,8 +62,25 @@ namespace Subsurface private void CreateScriptedEvents(Level level) { - ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(level.Seed); - AddTask(new ScriptedTask(scriptedEvent)); + Random rand = new Random(level.Seed.GetHashCode()); + + float totalDifficulty = level.Difficulty; + + int tries = 0; + do + { + ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(rand); + if (scriptedEvent==null || scriptedEvent.Difficulty > totalDifficulty) + { + tries++; + continue; + } + + AddTask(new ScriptedTask(scriptedEvent)); + totalDifficulty -= scriptedEvent.Difficulty; + tries = 0; + } while (tries < 5); + } public void TaskStarted(Task task) diff --git a/Subsurface/GUI/GUI.cs b/Subsurface/GUI/GUI.cs index bcb251288..d7ddf1dda 100644 --- a/Subsurface/GUI/GUI.cs +++ b/Subsurface/GUI/GUI.cs @@ -60,7 +60,7 @@ namespace Subsurface pos = position; this.lifeTime = lifeTime; - size = GUI.font.MeasureString(text); + size = GUI.Font.MeasureString(text); } } @@ -69,7 +69,8 @@ namespace Subsurface public static GUIStyle style; static Texture2D t; - public static SpriteFont font; + public static SpriteFont Font, SmallFont; + private static GraphicsDevice graphicsDevice; @@ -257,21 +258,21 @@ namespace Subsurface } DrawRectangle(sb, rect, color, true); - sb.DrawString(font, text, new Vector2(rect.X + 10, rect.Y + 10), Color.White); + sb.DrawString(Font, text, new Vector2(rect.X + 10, rect.Y + 10), Color.White); return clicked; } public static void Draw(float deltaTime, SpriteBatch spriteBatch, Camera cam) { - spriteBatch.DrawString(font, + spriteBatch.DrawString(Font, "FPS: " + (int)Game1.frameCounter.AverageFramesPerSecond + " - Physics: " + Game1.World.UpdateTime + " - bodies: " + Game1.World.BodyList.Count, new Vector2(10, 10), Color.White); - spriteBatch.DrawString(font, + spriteBatch.DrawString(Font, "Camera pos: " + Game1.GameScreen.Cam.Position, new Vector2(10, 30), Color.White); @@ -295,17 +296,27 @@ namespace Subsurface if (GUIMessageBox.messageBoxes.Count > 0) { var messageBox = GUIMessageBox.messageBoxes.Peek(); - if (messageBox != null) messageBox.Update(deltaTime); + if (messageBox != null) + { + GUIComponent.MouseOn = messageBox; + messageBox.Update(deltaTime); + } } } - public static void AddMessage(string message, Color color, float lifeTime = 3.0f) + public static void AddMessage(string message, Color color, float lifeTime = 3.0f, bool playSound = true) { + if (messages.Count>0 && messages[messages.Count-1].Text == message) + { + messages[messages.Count - 1].LifeTime = lifeTime; + return; + } + Vector2 currPos = new Vector2(Game1.GraphicsWidth / 2.0f, Game1.GraphicsHeight * 0.7f); currPos.Y += messages.Count * 30; messages.Add(new GUIMessage(message, color, currPos, lifeTime)); - PlayMessageSound(); + if (playSound) PlayMessageSound(); } public static void PlayMessageSound() @@ -331,7 +342,7 @@ namespace Subsurface msg.Pos = MathUtils.SmoothStep(msg.Pos, currPos, deltaTime*20.0f); - spriteBatch.DrawString(font, msg.Text, + spriteBatch.DrawString(Font, msg.Text, new Vector2((int)msg.Pos.X, (int)msg.Pos.Y), msg.Color * alpha, 0.0f, new Vector2((int)(0.5f * msg.Size.X), (int)(0.5f * msg.Size.Y)), 1.0f, SpriteEffects.None, 0.0f); diff --git a/Subsurface/GUI/GUIButton.cs b/Subsurface/GUI/GUIButton.cs index 1688ef06c..0eacc727d 100644 --- a/Subsurface/GUI/GUIButton.cs +++ b/Subsurface/GUI/GUIButton.cs @@ -60,7 +60,7 @@ namespace Subsurface public override void Draw(SpriteBatch spriteBatch) { - if (rect.Contains(PlayerInput.GetMouseState.Position) && Enabled && (MouseOn == this || IsParentOf(MouseOn))) + if (rect.Contains(PlayerInput.GetMouseState.Position) && Enabled && (MouseOn == null || MouseOn == this || IsParentOf(MouseOn))) { state = ComponentState.Hover; if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed) @@ -75,7 +75,7 @@ namespace Subsurface if (OnClicked != null) { if (OnClicked(this, UserData)) state = ComponentState.Selected; - } + } } } else diff --git a/Subsurface/GUI/GUIComponent.cs b/Subsurface/GUI/GUIComponent.cs index c033071c8..f05b07244 100644 --- a/Subsurface/GUI/GUIComponent.cs +++ b/Subsurface/GUI/GUIComponent.cs @@ -23,6 +23,8 @@ namespace Subsurface protected Rectangle rect; + public bool CanBeFocused; + protected Vector4 padding; protected Color color; @@ -34,6 +36,12 @@ namespace Subsurface protected ComponentState state; + public virtual SpriteFont Font + { + get; + set; + } + //protected float alpha; public GUIComponent Parent @@ -139,10 +147,12 @@ namespace Subsurface OutlineColor = Color.Transparent; + Font = GUI.Font; + sprites = new List(); children = new List(); - + CanBeFocused = true; if (style!=null) style.Apply(this); } @@ -196,13 +206,17 @@ namespace Subsurface public virtual void Update(float deltaTime) { - if (rect.Contains(PlayerInput.MousePosition)) + if (CanBeFocused) { - MouseOn = this; - } - else - { - if (MouseOn == this) MouseOn = null; + if (rect.Contains(PlayerInput.MousePosition)) + { + MouseOn = this; + } + else + { + if (MouseOn == this) MouseOn = null; + } + } foreach (GUIComponent child in children) diff --git a/Subsurface/GUI/GUIFrame.cs b/Subsurface/GUI/GUIFrame.cs index a16e9af5d..979fdeb22 100644 --- a/Subsurface/GUI/GUIFrame.cs +++ b/Subsurface/GUI/GUIFrame.cs @@ -67,7 +67,7 @@ namespace Subsurface } - DrawChildren(spriteBatch); + DrawChildren(spriteBatch); } } diff --git a/Subsurface/GUI/GUIMessageBox.cs b/Subsurface/GUI/GUIMessageBox.cs index 317e4f45e..a3db142c6 100644 --- a/Subsurface/GUI/GUIMessageBox.cs +++ b/Subsurface/GUI/GUIMessageBox.cs @@ -50,6 +50,8 @@ namespace Subsurface public bool Close(GUIButton button, object obj) { + if (parent != null) parent.RemoveChild(this); + messageBoxes.Dequeue(); return true; } diff --git a/Subsurface/GUI/GUITextBlock.cs b/Subsurface/GUI/GUITextBlock.cs index df7e25f9f..96004c4d6 100644 --- a/Subsurface/GUI/GUITextBlock.cs +++ b/Subsurface/GUI/GUITextBlock.cs @@ -125,17 +125,12 @@ namespace Subsurface { if (text==null) return; - - - - - Vector2 size = MeasureText(); if (wrap && rect.Width>0) { text = text.Replace("\n"," "); - text = ToolBox.WrapText(text, rect.Width); + text = ToolBox.WrapText(text, rect.Width, Font); Vector2 newSize = MeasureText(); @@ -177,7 +172,7 @@ namespace Subsurface Vector2 size = Vector2.Zero; while (size == Vector2.Zero) { - try { size = GUI.font.MeasureString((text == "") ? " " : text); } + try { size = Font.MeasureString((text == "") ? " " : text); } catch { text = text.Substring(0, text.Length - 1); } } @@ -196,7 +191,7 @@ namespace Subsurface if (!string.IsNullOrEmpty(text)) { - spriteBatch.DrawString(GUI.font, + spriteBatch.DrawString(Font, text, new Vector2(rect.X, rect.Y) + textPos, textColor * (textColor.A / 255.0f), diff --git a/Subsurface/GUI/GUITextBox.cs b/Subsurface/GUI/GUITextBox.cs index f5f334500..3ee6794e4 100644 --- a/Subsurface/GUI/GUITextBox.cs +++ b/Subsurface/GUI/GUITextBox.cs @@ -30,6 +30,16 @@ namespace Subsurface set; } + public override SpriteFont Font + { + set + { + base.Font = value; + if (textBlock == null) return; + textBlock.Font = value; + } + } + public override Color Color { get { return color; } @@ -59,13 +69,12 @@ namespace Subsurface String filtered = ""; foreach (char c in value) { - if (GUI.font.Characters.Contains(c)) - filtered += c; + if (Font.Characters.Contains(c)) filtered += c; } textBlock.Text = filtered; - if (GUI.font.MeasureString(textBlock.Text).X > rect.Width) + if (Font.MeasureString(textBlock.Text).X > rect.Width) { //recursion to ensure that text cannot be larger than the box Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1); diff --git a/Subsurface/GUI/TitleScreen.cs b/Subsurface/GUI/TitleScreen.cs new file mode 100644 index 000000000..c9621534c --- /dev/null +++ b/Subsurface/GUI/TitleScreen.cs @@ -0,0 +1,91 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace Subsurface +{ + class TitleScreen + { + private Texture2D backgroundTexture,monsterTexture,titleTexture; + + readonly RenderTarget2D renderTarget; + + float state; + + public Vector2 Position; + + public TitleScreen(GraphicsDevice graphics) + { + backgroundTexture = Game1.textureLoader.FromFile("Content/UI/titleBackground.png"); + monsterTexture = Game1.textureLoader.FromFile("Content/UI/titleMonster.png"); + titleTexture = Game1.textureLoader.FromFile("Content/UI/titleText.png"); + + renderTarget = new RenderTarget2D(graphics, Game1.GraphicsWidth, Game1.GraphicsHeight); + + } + + public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float loadState, float deltaTime) + { + //if (stopwatch == null) + //{ + // stopwatch = new Stopwatch(); + // stopwatch.Start(); + //} + + graphics.SetRenderTarget(renderTarget); + //Debug.WriteLine(stopwatch.Elapsed.TotalMilliseconds); + + float scale = Game1.GraphicsHeight/2048.0f; + + state += deltaTime; + + Vector2 center = new Vector2(Game1.GraphicsWidth*0.3f, Game1.GraphicsHeight/2.0f) + Position*scale; + + Vector2 titlePos = center + new Vector2(-0.0f + (float)Math.Sqrt(state) * 220.0f, 0.0f) * scale; + titlePos.X = Math.Min(titlePos.X, (float)Game1.GraphicsWidth / 2.0f); + + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); + graphics.Clear(Color.Black); + + spriteBatch.Draw(backgroundTexture, center, null, Color.White * Math.Min(state / 5.0f, 1.0f), 0.0f, + new Vector2(backgroundTexture.Width / 2.0f, backgroundTexture.Height / 2.0f), + scale, SpriteEffects.None, 0.2f); + + spriteBatch.Draw(monsterTexture, + center + new Vector2(state * 100.0f - 1200.0f, state * 30.0f - 100.0f) * scale, null, + Color.White, 0.0f, Vector2.Zero, scale, SpriteEffects.None, 0.1f); + + spriteBatch.Draw(titleTexture, + titlePos, null, + Color.White * Math.Min((state - 1.0f) / 5.0f, 1.0f), 0.0f, new Vector2(titleTexture.Width / 2.0f, titleTexture.Height / 2.0f), scale, SpriteEffects.None, 0.0f); + + spriteBatch.End(); + + graphics.SetRenderTarget(null); + + Matrix transform = Matrix.CreateTranslation( + new Vector3(Game1.GraphicsWidth / 2.0f, + Game1.GraphicsHeight / 2.0f, 0)); + + Hull.renderer.RenderBack(graphics, renderTarget, transform); + + + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); + + spriteBatch.Draw(titleTexture, + titlePos, null, + Color.White * Math.Min((state - 3.0f) / 5.0f, 1.0f), 0.0f, new Vector2(titleTexture.Width / 2.0f, titleTexture.Height / 2.0f), scale, SpriteEffects.None, 0.0f); + + string loadText = (loadState<100.0f) ? "Loading... "+(int)loadState+" %" : "Press any key to continue"; + spriteBatch.DrawString(GUI.Font, loadText, new Vector2(Game1.GraphicsWidth/2.0f - 50.0f, Game1.GraphicsHeight*0.8f), Color.White); + + spriteBatch.End(); + + } + } +} diff --git a/Subsurface/Game1.cs b/Subsurface/Game1.cs index 608233fff..bff2fc20b 100644 --- a/Subsurface/Game1.cs +++ b/Subsurface/Game1.cs @@ -7,6 +7,8 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Subsurface.Networking; using Subsurface.Particles; +using System.Collections; +using System.Collections.Generic; namespace Subsurface { @@ -43,6 +45,9 @@ namespace Subsurface public static World World; + public static TitleScreen TitleScreen; + private bool titleScreenOpen; + //public static Random localRandom; //public static Random random; @@ -82,7 +87,7 @@ namespace Subsurface graphicsWidth = 1280; graphicsHeight = 720; - //graphics.IsFullScreen = true; + //Graphics.IsFullScreen = true; Graphics.PreferredBackBufferWidth = graphicsWidth; Graphics.PreferredBackBufferHeight = graphicsHeight; Content.RootDirectory = "Content"; @@ -116,13 +121,6 @@ namespace Subsurface CurrGraphicsDevice = GraphicsDevice; - particleManager = new ParticleManager("Content/Particles/prefabs.xml", Cam); - - GameMode.Init(); - GUIComponent.Init(Window); - DebugConsole.Init(Window); - - LocationType.Init("Content/Map/locationTypes.xml"); //Event.Init("Content/randomevents.xml"); } @@ -141,31 +139,77 @@ namespace Subsurface spriteBatch = new SpriteBatch(GraphicsDevice); textureLoader = new TextureLoader(GraphicsDevice); - - Hull.renderer = new WaterRenderer(GraphicsDevice); - GUI.font = Content.Load("SpriteFont1"); + titleScreenOpen = true; + TitleScreen = new TitleScreen(GraphicsDevice); + + CoroutineManager.StartCoroutine(Load()); + } + + private float loadState = 0.0f; + private IEnumerable Load() + { + GUI.Font = Content.Load("SpriteFont1"); + GUI.SmallFont = Content.Load("SmallFont"); + + Hull.renderer = new WaterRenderer(GraphicsDevice); + loadState = 1.0f; + yield return Status.Running; + GUI.LoadContent(GraphicsDevice); + loadState = 2.0f; + yield return Status.Running; MapEntityPrefab.Init(); + loadState = 10.0f; + yield return Status.Running; JobPrefab.LoadAll("Content/Characters/Jobs.xml"); + loadState = 15.0f; + yield return Status.Running; StructurePrefab.LoadAll("Content/Map/StructurePrefabs.xml"); + loadState = 25.0f; + yield return Status.Running; + ItemPrefab.LoadAll(); - - AmbientSoundManager.Init("Content/Sounds/Sounds.xml"); + loadState = 40.0f; + yield return Status.Running; + + Debug.WriteLine("sounds"); + CoroutineManager.StartCoroutine(AmbientSoundManager.Init()); + loadState = 70.0f; + yield return Status.Running; Submarine.Preload("Content/SavedMaps"); + loadState = 80.0f; + yield return Status.Running; + GameScreen = new GameScreen(Graphics.GraphicsDevice); + loadState = 90.0f; + yield return Status.Running; + MainMenuScreen = new MainMenuScreen(this); LobbyScreen = new LobbyScreen(); NetLobbyScreen = new NetLobbyScreen(); EditMapScreen = new EditMapScreen(); EditCharacterScreen = new EditCharacterScreen(); + yield return Status.Running; + particleManager = new ParticleManager("Content/Particles/prefabs.xml", Cam); + yield return Status.Running; - MainMenuScreen.Select(); + GameMode.Init(); + GUIComponent.Init(Window); + DebugConsole.Init(Window); + yield return Status.Running; + + LocationType.Init("Content/Map/locationTypes.xml"); + MainMenuScreen.Select(); + yield return Status.Running; + + loadState = 100.0f; + yield return Status.Success; } /// @@ -188,25 +232,26 @@ namespace Subsurface base.Update(gameTime); double deltaTime = gameTime.ElapsedGameTime.TotalSeconds; - PlayerInput.Update(deltaTime); - - //if (PlayerInput.KeyDown(Keys.Escape)) Quit(); - - DebugConsole.Update(this, (float)deltaTime); - - if (!DebugConsole.IsOpen || NetworkMember != null) Screen.Selected.Update(deltaTime); - - GUI.Update((float)deltaTime); - - if (NetworkMember != null) + if (loadState>=100.0f && !titleScreenOpen) { - NetworkMember.Update(); - } - else - { - NetworkEvent.events.Clear(); + //if (PlayerInput.KeyDown(Keys.Escape)) Quit(); + + DebugConsole.Update(this, (float)deltaTime); + + if (!DebugConsole.IsOpen || NetworkMember != null) Screen.Selected.Update(deltaTime); + + GUI.Update((float)deltaTime); + + if (NetworkMember != null) + { + NetworkMember.Update(); + } + else + { + NetworkEvent.events.Clear(); + } } CoroutineManager.Update(); @@ -224,8 +269,18 @@ namespace Subsurface frameCounter.Update(deltaTime); - Screen.Selected.Draw(deltaTime, GraphicsDevice, spriteBatch); - + if (titleScreenOpen) + { + TitleScreen.Draw(spriteBatch, GraphicsDevice, loadState, (float)deltaTime); + if (loadState>=100.0f && (PlayerInput.GetKeyboardState.GetPressedKeys().Length>0 || PlayerInput.LeftButtonClicked())) + { + titleScreenOpen = false; + } + } + else if (loadState>=100.0f) + { + Screen.Selected.Draw(deltaTime, GraphicsDevice, spriteBatch); + } //renderTimeElapsed = (int)renderTimer.Elapsed.Ticks; //renderTimer.Stop(); } diff --git a/Subsurface/GameSession/CrewManager.cs b/Subsurface/GameSession/CrewManager.cs index ad1bfe0b6..5f97e700e 100644 --- a/Subsurface/GameSession/CrewManager.cs +++ b/Subsurface/GameSession/CrewManager.cs @@ -20,6 +20,7 @@ namespace Subsurface private GUIFrame guiFrame; private GUIListBox listBox; + public int Money { get { return money; } @@ -143,7 +144,11 @@ namespace Subsurface { foreach (Character c in characters) { - if (!c.IsDead) continue; + if (!c.IsDead) + { + c.Info.UpdateCharacterItems(); + continue; + } CharacterInfo deadInfo = characterInfos.Find(x => c.Info == x); if (deadInfo != null) characterInfos.Remove(deadInfo); @@ -165,7 +170,7 @@ namespace Subsurface element.Add(new XAttribute("money", money)); foreach (CharacterInfo ci in characterInfos) - { + { ci.Save(element); } diff --git a/Subsurface/GameSession/GameSession.cs b/Subsurface/GameSession/GameSession.cs index 25477bd55..63392e487 100644 --- a/Subsurface/GameSession/GameSession.cs +++ b/Subsurface/GameSession/GameSession.cs @@ -31,18 +31,31 @@ namespace Subsurface private Level level; - public Map map; - public Level Level { get { return level; } } + public Map Map + { + get + { + SinglePlayerMode mode = (gameMode as SinglePlayerMode); + return (mode == null) ? null : mode.map; + } + } + + public Submarine Submarine { get { return submarine; } } + public string SavePath + { + get { return savePath; } + } + public GameSession(Submarine submarine, GameModePreset gameModePreset) :this(submarine, gameModePreset.Instantiate()) { @@ -57,8 +70,6 @@ namespace Subsurface guiRoot = new GUIFrame(new Rectangle(0,0,Game1.GraphicsWidth,Game1.GraphicsWidth), Color.Transparent); - map = new Map(Rand.Int(), 500); - //int width = 350, height = 100; //if (Game1.NetworkMember!=null) //{ @@ -118,13 +129,13 @@ namespace Subsurface StartShift(duration, level); } - public void StartShift(TimeSpan duration, Level level) + public void StartShift(TimeSpan duration, Level level, bool reloadSub = true) { Lights.LightManager.FowEnabled = (Game1.Server==null); this.level = level; - if (Submarine.Loaded != submarine) submarine.Load(); + if (reloadSub || Submarine.Loaded != submarine) submarine.Load(); if (gameMode!=null) gameMode.Start(duration); @@ -147,8 +158,6 @@ namespace Subsurface else if (Game1.Client==null) { Game1.LobbyScreen.Select(); - - SaveUtil.SaveGame(savePath); } taskManager.EndShift(); diff --git a/Subsurface/GameSession/SinglePlayerMode.cs b/Subsurface/GameSession/SinglePlayerMode.cs index 3655d1e0d..d53bee590 100644 --- a/Subsurface/GameSession/SinglePlayerMode.cs +++ b/Subsurface/GameSession/SinglePlayerMode.cs @@ -22,9 +22,13 @@ namespace Subsurface // get { return day; } //} + public Map map; + bool crewDead; private float endTimer; + private bool savedOnStart; + public SinglePlayerMode(GameModePreset preset) : base(preset) { @@ -36,6 +40,7 @@ namespace Subsurface hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10); + //day = 1; } @@ -44,6 +49,12 @@ namespace Subsurface { //day = ToolBox.GetAttributeInt(element,"day",1); + string mapSeed = ToolBox.GetAttributeString(element, "mapseed", "a"); + + GenerateMap(mapSeed); + + map.SetLocation(ToolBox.GetAttributeInt(element, "currentlocation", 0)); + foreach (XElement subElement in element.Elements()) { if (subElement.Name.ToString().ToLower() != "crew") continue; @@ -52,8 +63,23 @@ namespace Subsurface } } + public void GenerateMap(string seed) + { + map = new Map(seed.GetHashCode(), 500); + } + public override void Start(TimeSpan duration) { + if (!savedOnStart) + { + SaveUtil.SaveGame(Game1.GameSession.SavePath); + savedOnStart = true; + + + //Game1.GameSession.submarine.Load(); + } + + endTimer = 5.0f; crewManager.StartShift(); @@ -85,12 +111,12 @@ namespace Subsurface if (Level.Loaded.AtEndPosition) { - endShiftButton.Text = "Enter " + Game1.GameSession.map.SelectedLocation.Name; + endShiftButton.Text = "Enter " + map.SelectedLocation.Name; endShiftButton.Draw(spriteBatch); } else if (Level.Loaded.AtStartPosition) { - endShiftButton.Text = "Enter " + Game1.GameSession.map.CurrentLocation.Name; + endShiftButton.Text = "Enter " + map.CurrentLocation.Name; endShiftButton.Draw(spriteBatch); } @@ -125,8 +151,10 @@ namespace Subsurface } } - private bool EndShift(GUIButton button, object obj) + public override void End(string endMessage = "") { + base.End(endMessage); + StringBuilder sb = new StringBuilder(); List casualties = crewManager.characters.FindAll(c => c.IsDead); @@ -157,9 +185,10 @@ namespace Subsurface if (Level.Loaded.AtEndPosition) { - Game1.GameSession.map.MoveToNextLocation(); + map.MoveToNextLocation(); } + SaveUtil.SaveGame(Game1.GameSession.SavePath); } crewManager.EndShift(); @@ -168,16 +197,30 @@ namespace Subsurface Character.CharacterList[i].Remove(); } + + //SaveUtil.SaveGame(Game1.GameSession.SavePath); + Game1.GameSession.EndShift(""); + } + + private bool EndShift(GUIButton button, object obj) + { + End(""); return true; } public void Save(XElement element) { //element.Add(new XAttribute("day", day)); + XElement modeElement = new XElement("gamemode"); - crewManager.Save(element); + modeElement.Add(new XAttribute("currentlocation", map.CurrentLocationIndex)); + modeElement.Add(new XAttribute("mapseed", map.Seed)); + + crewManager.Save(modeElement); + + element.Add(modeElement); } } diff --git a/Subsurface/Items/Components/Holdable/Pickable.cs b/Subsurface/Items/Components/Holdable/Pickable.cs index fdb97dd14..f0f8017e2 100644 --- a/Subsurface/Items/Components/Holdable/Pickable.cs +++ b/Subsurface/Items/Components/Holdable/Pickable.cs @@ -37,17 +37,19 @@ namespace Subsurface.Items.Components if (picker == null) return false; if (picker.Inventory == null) return false; - this.picker = picker; + //this.picker = picker; - for (int i = item.linkedTo.Count - 1; i >= 0; i--) - item.linkedTo[i].RemoveLinked(item); - item.linkedTo.Clear(); + if (picker.Inventory.TryPutItem(item, allowedSlots)) { if (!picker.HasSelectedItem(item) && item.body!=null) item.body.Enabled = false; this.picker = picker; + for (int i = item.linkedTo.Count - 1; i >= 0; i--) + item.linkedTo[i].RemoveLinked(item); + item.linkedTo.Clear(); + ApplyStatusEffects(ActionType.OnPicked, 1.0f, picker); //foreach (StatusEffect effect in item.Prefab.statusEffects) diff --git a/Subsurface/Items/Components/Holdable/RangedWeapon.cs b/Subsurface/Items/Components/Holdable/RangedWeapon.cs index 8f804ead7..98622a207 100644 --- a/Subsurface/Items/Components/Holdable/RangedWeapon.cs +++ b/Subsurface/Items/Components/Holdable/RangedWeapon.cs @@ -94,22 +94,16 @@ namespace Subsurface.Items.Components projectile.body.ApplyTorque(projectile.body.Mass * Rand.Range(-10.0f, 10.0f)); //recoil - item.body.ApplyLinearImpulse( - new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * item.body.Mass * -10.0f); - - if (Rand.Int(2) == 0) - { - item.Drop(character); - item.body.ApplyTorque(projectile.body.Mass * Rand.Range(-10.0f, 10.0f)); - } + //item.body.ApplyLinearImpulse( + // new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * item.body.Mass * -10.0f); } else { projectileComponent.ignoredBodies = limbBodies; //recoil - item.body.ApplyLinearImpulse( - new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * -item.body.Mass); + //item.body.ApplyLinearImpulse( + // new Vector2((float)Math.Cos(projectile.body.Rotation), (float)Math.Sin(projectile.body.Rotation)) * -item.body.Mass); } item.RemoveContained(projectile); diff --git a/Subsurface/Items/Components/ItemComponent.cs b/Subsurface/Items/Components/ItemComponent.cs index d500b0498..048e61dba 100644 --- a/Subsurface/Items/Components/ItemComponent.cs +++ b/Subsurface/Items/Components/ItemComponent.cs @@ -393,6 +393,7 @@ namespace Subsurface if (containedItem == null) { //if (addMessage && !String.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red); + if (addMessage && !string.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red); return false; } } @@ -403,9 +404,7 @@ namespace Subsurface public bool HasRequiredItems(Character character, bool addMessage) { if (!requiredItems.Any()) return true; - - - + foreach (RelatedItem ri in requiredItems) { if (!ri.Type.HasFlag(RelatedItem.RelationType.Equipped) && !ri.Type.HasFlag(RelatedItem.RelationType.Picked)) continue; @@ -419,7 +418,11 @@ namespace Subsurface { if (character.Inventory.items.FirstOrDefault(x => x!=null && x.Condition>0.0f && ri.MatchesItem(x))!=null) hasItem = true; } - if (!hasItem) return false; + if (!hasItem) + { + if (addMessage && !string.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red); + return false; + } } return true; @@ -484,7 +487,7 @@ namespace Subsurface { if (componentElement == null) return; - bool requiredItemsCleared = false; + foreach (XAttribute attribute in componentElement.Attributes()) { @@ -494,6 +497,9 @@ namespace Subsurface property.TrySetValue(attribute.Value); } + List prevRequiredItems = new List(requiredItems); + requiredItems.Clear(); + foreach (XElement subElement in componentElement.Elements()) { switch (subElement.Name.ToString().ToLower()) @@ -503,10 +509,11 @@ namespace Subsurface if (newRequiredItem == null) continue; - if (!requiredItemsCleared) + var prevRequiredItem = prevRequiredItems.Find(ri => ri.JoinedNames == newRequiredItem.JoinedNames); + if (prevRequiredItem!=null) { - requiredItems.Clear(); - requiredItemsCleared = true; + newRequiredItem.statusEffects = prevRequiredItem.statusEffects; + newRequiredItem.Msg = prevRequiredItem.Msg; } requiredItems.Add(newRequiredItem); diff --git a/Subsurface/Items/Components/Machines/Engine.cs b/Subsurface/Items/Components/Machines/Engine.cs index 3e1d26073..df26e4e05 100644 --- a/Subsurface/Items/Components/Machines/Engine.cs +++ b/Subsurface/Items/Components/Machines/Engine.cs @@ -87,7 +87,7 @@ namespace Subsurface.Items.Components //GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true); - spriteBatch.DrawString(GUI.font, "Force: " + (int)(targetForce) + " %", new Vector2(GuiFrame.Rect.X + 30, GuiFrame.Rect.Y + 30), Color.White); + spriteBatch.DrawString(GUI.Font, "Force: " + (int)(targetForce) + " %", new Vector2(GuiFrame.Rect.X + 30, GuiFrame.Rect.Y + 30), Color.White); if (GUI.DrawButton(spriteBatch, new Rectangle(GuiFrame.Rect.X + 280, GuiFrame.Rect.Y + 30, 40, 40), "+", true)) targetForce += 1.0f; if (GUI.DrawButton(spriteBatch, new Rectangle(GuiFrame.Rect.X + 280, GuiFrame.Rect.Y + 80, 40, 40), "-", true)) targetForce -= 1.0f; diff --git a/Subsurface/Items/Components/Machines/Reactor.cs b/Subsurface/Items/Components/Machines/Reactor.cs index a1174408b..5df26a393 100644 --- a/Subsurface/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Items/Components/Machines/Reactor.cs @@ -310,12 +310,12 @@ namespace Subsurface.Items.Components GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true); - spriteBatch.DrawString(GUI.font, "Temperature: " + (int)temperature + " C", new Vector2(x + 30, y + 30), Color.White); + spriteBatch.DrawString(GUI.Font, "Temperature: " + (int)temperature + " C", new Vector2(x + 30, y + 30), Color.White); DrawGraph(tempGraph, spriteBatch, x + 30, y + 50, 10000.0f, xOffset); y += 130; - spriteBatch.DrawString(GUI.font, "Fission rate: " + (int)fissionRate + " %", new Vector2(x + 30, y + 30), Color.White); + spriteBatch.DrawString(GUI.Font, "Fission rate: " + (int)fissionRate + " %", new Vector2(x + 30, y + 30), Color.White); DrawGraph(fissionRateGraph, spriteBatch, x + 30, y + 50, 100.0f, xOffset); if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 30, 40, 40), "+", true)) FissionRate += 1.0f; @@ -323,7 +323,7 @@ namespace Subsurface.Items.Components y += 130; - spriteBatch.DrawString(GUI.font, "Cooling rate: " + (int)coolingRate + " %", new Vector2(x + 30, y + 30), Color.White); + spriteBatch.DrawString(GUI.Font, "Cooling rate: " + (int)coolingRate + " %", new Vector2(x + 30, y + 30), Color.White); DrawGraph(coolingRateGraph, spriteBatch, x + 30, y + 50, 100.0f, xOffset); if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 30, 40, 40), "+", true)) CoolingRate += 1.0f; @@ -331,10 +331,10 @@ namespace Subsurface.Items.Components y = y - 260; - spriteBatch.DrawString(GUI.font, "Autotemp: " + ((autoTemp) ? "ON" : "OFF"), new Vector2(x + 400, y + 30), Color.White); + spriteBatch.DrawString(GUI.Font, "Autotemp: " + ((autoTemp) ? "ON" : "OFF"), new Vector2(x + 400, y + 30), Color.White); if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 60, 100, 40), ((autoTemp) ? "TURN OFF" : "TURN ON"))) autoTemp = !autoTemp; - spriteBatch.DrawString(GUI.font, "Max temperature: " + shutDownTemp, new Vector2(x + 400, y + 150), Color.White); + spriteBatch.DrawString(GUI.Font, "Max temperature: " + shutDownTemp, new Vector2(x + 400, y + 150), Color.White); if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 180, 40, 40), "+", true)) shutDownTemp += 100.0f; if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true)) shutDownTemp -= 100.0f; diff --git a/Subsurface/Items/Components/Machines/Steering.cs b/Subsurface/Items/Components/Machines/Steering.cs index 305bbd46d..62753df99 100644 --- a/Subsurface/Items/Components/Machines/Steering.cs +++ b/Subsurface/Items/Components/Machines/Steering.cs @@ -24,6 +24,11 @@ namespace Subsurface.Items.Components get { return targetVelocity;} set { + if (float.IsNaN(value.X) || float.IsNaN(value.Y)) + { + targetVelocity = Vector2.Zero; + return; + } targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f); targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f); } diff --git a/Subsurface/Items/Components/Power/PowerContainer.cs b/Subsurface/Items/Components/Power/PowerContainer.cs index 501c43b0e..6761c4128 100644 --- a/Subsurface/Items/Components/Power/PowerContainer.cs +++ b/Subsurface/Items/Components/Power/PowerContainer.cs @@ -38,7 +38,11 @@ namespace Subsurface.Items.Components public float Charge { get { return charge; } - set { charge = MathHelper.Clamp(value, 0.0f, capacity); } + set + { + if (float.IsNaN(value)) return; + charge = MathHelper.Clamp(value, 0.0f, capacity); + } } @@ -49,12 +53,15 @@ namespace Subsurface.Items.Components set { capacity = Math.Max(value,1.0f); } } - //[HasDefaultValue(10.0f, false)] - //public float MaxInput - //{ - // get { return maxInput; } - // set { maxInput = value; } - //} + public float RechargeSpeed + { + get { return rechargeSpeed; } + set + { + if (float.IsNaN(value)) return; + rechargeSpeed = MathHelper.Clamp(rechargeSpeed, 0.0f, maxRechargeSpeed); + } + } [HasDefaultValue(10.0f, false)] public float MaxRechargeSpeed @@ -188,16 +195,38 @@ namespace Subsurface.Items.Components GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true); - spriteBatch.DrawString(GUI.font, + spriteBatch.DrawString(GUI.Font, "Charge: " + (int)charge + "/" + (int)capacity + " (" + (int)((charge / capacity) * 100.0f) + " %)", new Vector2(x + 30, y + 30), Color.White); - spriteBatch.DrawString(GUI.font, "Recharge rate: " + (rechargeSpeed / maxRechargeSpeed), new Vector2(x + 30, y + 100), Color.White); + spriteBatch.DrawString(GUI.Font, "Recharge rate: " + (rechargeSpeed / maxRechargeSpeed), new Vector2(x + 30, y + 100), Color.White); if (GUI.DrawButton(spriteBatch, new Rectangle(x + 50, y + 150, 40, 40), "+", true)) rechargeSpeed = Math.Min(rechargeSpeed + 10.0f, maxRechargeSpeed); if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 150, 40, 40), "-", true)) rechargeSpeed = Math.Max(rechargeSpeed - 10.0f, 0.0f); } + public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message) + { + message.Write(rechargeSpeed); + message.Write(charge); + } + + public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message) + { + float newRechargeSpeed = 0.0f; + float newCharge = 0.0f; + + try + { + newRechargeSpeed = message.ReadFloat(); + newCharge = message.ReadFloat(); + } + catch { } + + RechargeSpeed = newRechargeSpeed; + Charge = newCharge; + } + } } diff --git a/Subsurface/Items/Components/Power/PowerTransfer.cs b/Subsurface/Items/Components/Power/PowerTransfer.cs index 92117fe25..238780802 100644 --- a/Subsurface/Items/Components/Power/PowerTransfer.cs +++ b/Subsurface/Items/Components/Power/PowerTransfer.cs @@ -133,8 +133,8 @@ namespace Subsurface.Items.Components GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true); - spriteBatch.DrawString(GUI.font, "Power: " + (int)(-currPowerConsumption), new Vector2(x + 30, y + 30), Color.White); - spriteBatch.DrawString(GUI.font, "Load: " + (int)powerLoad, new Vector2(x + 30, y + 100), Color.White); + spriteBatch.DrawString(GUI.Font, "Power: " + (int)(-currPowerConsumption), new Vector2(x + 30, y + 30), Color.White); + spriteBatch.DrawString(GUI.Font, "Load: " + (int)powerLoad, new Vector2(x + 30, y + 100), Color.White); } public override void ReceiveSignal(string signal, Connection connection, Item sender, float power) diff --git a/Subsurface/Items/Components/Signal/Connection.cs b/Subsurface/Items/Components/Signal/Connection.cs index 6b3b00478..695da00ed 100644 --- a/Subsurface/Items/Components/Signal/Connection.cs +++ b/Subsurface/Items/Components/Signal/Connection.cs @@ -274,7 +274,7 @@ namespace Subsurface.Items.Components private void Draw(SpriteBatch spriteBatch, Item item, Vector2 position, Vector2 labelPos, Vector2 wirePosition, bool mouseIn, bool wireEquipped) { - spriteBatch.DrawString(GUI.font, Name, new Vector2(labelPos.X, labelPos.Y-10), Color.White); + spriteBatch.DrawString(GUI.Font, Name, new Vector2(labelPos.X, labelPos.Y-10), Color.White); GUI.DrawRectangle(spriteBatch, new Rectangle((int)position.X-10, (int)position.Y-10, 20, 20), Color.White); @@ -386,11 +386,11 @@ namespace Subsurface.Items.Components } } - spriteBatch.DrawString(GUI.font, item.Name, + spriteBatch.DrawString(GUI.Font, item.Name, new Vector2(textX, start.Y-30), (mouseOn && !wireEquipped) ? Color.Gold : Color.White, MathHelper.PiOver2, - GUI.font.MeasureString(item.Name)*0.5f, + GUI.Font.MeasureString(item.Name)*0.5f, 1.0f, SpriteEffects.None, 0.0f); } diff --git a/Subsurface/Items/Inventory.cs b/Subsurface/Items/Inventory.cs index 55f5ece09..87187908d 100644 --- a/Subsurface/Items/Inventory.cs +++ b/Subsurface/Items/Inventory.cs @@ -260,15 +260,15 @@ namespace Subsurface if (isHighLighted) { - Vector2 pos = new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height + 20) - GUI.font.MeasureString(item.Name)*0.5f; + Vector2 pos = new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height + 20) - GUI.Font.MeasureString(item.Name)*0.5f; pos.X = (int)pos.X; pos.Y = (int)pos.Y; - spriteBatch.DrawString(GUI.font, item.Name + " - "+item.ID, pos - new Vector2(1.0f,1.0f), Color.Black); - spriteBatch.DrawString(GUI.font, item.Name + " - " + item.ID, pos, Color.White); + spriteBatch.DrawString(GUI.Font, item.Name + " - "+item.ID, pos - new Vector2(1.0f,1.0f), Color.Black); + spriteBatch.DrawString(GUI.Font, item.Name + " - " + item.ID, pos, Color.White); } if (item.Condition < 100.0f) - spriteBatch.DrawString(GUI.font, (int)item.Condition + " %", new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), Color.Red); + spriteBatch.DrawString(GUI.Font, (int)item.Condition + " %", new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), Color.Red); } public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data) diff --git a/Subsurface/Items/Item.cs b/Subsurface/Items/Item.cs index 787fc378a..23c0b003c 100644 --- a/Subsurface/Items/Item.cs +++ b/Subsurface/Items/Item.cs @@ -163,13 +163,13 @@ namespace Subsurface } } - List highlightText; + //List highlightText; - public List HighlightText - { - get { return highlightText;} + //public List HighlightText + //{ + // get { return highlightText;} - } + //} 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) @@ -223,7 +223,7 @@ namespace Subsurface - highlightText = new List(); + //highlightText = new List(); foreach (XElement subElement in element.Elements()) { @@ -245,7 +245,7 @@ namespace Subsurface if (ic == null) break; components.Add(ic); - if (!string.IsNullOrWhiteSpace(ic.Msg)) highlightText.Add(ic.Msg); + //if (!string.IsNullOrWhiteSpace(ic.Msg)) highlightText.Add(ic.Msg); break; } @@ -672,7 +672,6 @@ namespace Subsurface float closestDist = 0.0f, dist; Item closest = null; - Vector2 displayPos = ConvertUnits.ToDisplayUnits(position); Vector2 displayPickPos = ConvertUnits.ToDisplayUnits(pickPosition); @@ -715,7 +714,7 @@ namespace Subsurface if (Vector2.Distance(position, item.SimPosition) > item.prefab.PickDistance) continue; dist = Vector2.Distance(pickPosition, item.SimPosition); - if (closest == null || dist < closestDist) + if ((closest == null || dist < closestDist) && Submarine.CheckVisibility(position, item.SimPosition)==null) { closest = item; closestDist = dist; @@ -749,7 +748,7 @@ namespace Subsurface picker.SelectedConstruction = (picker.SelectedConstruction == this) ? null : this; } - if (!hasRequiredSkills) + if (!hasRequiredSkills && Character.Controlled==picker) { GUI.AddMessage("Your skills may be insufficient to use the item!", Color.Red, 5.0f); } @@ -785,6 +784,25 @@ namespace Subsurface } } + public List GetHUDTexts(Character character) + { + List texts = new List(); + + foreach (ItemComponent ic in components) + { + if (string.IsNullOrEmpty(ic.Msg)) continue; + if (!ic.CanBePicked && !ic.CanBeSelected) continue; + + + Color color = Color.Red; + if (ic.HasRequiredSkills(character) && ic.HasRequiredItems(character, false)) color = Color.Orange; + + texts.Add(new ColoredText(ic.Msg, color)); + } + + return texts; + } + public bool Combine(Item item) { bool isCombined = false; diff --git a/Subsurface/Items/RelatedItem.cs b/Subsurface/Items/RelatedItem.cs index 41bac1a0c..1cfab0856 100644 --- a/Subsurface/Items/RelatedItem.cs +++ b/Subsurface/Items/RelatedItem.cs @@ -20,13 +20,15 @@ namespace Subsurface RelationType type; - public readonly List statusEffects; + public List statusEffects; //public string[] Names //{ // get { return names; } //} + public string Msg; + public RelationType Type { get { return type; } @@ -95,13 +97,15 @@ namespace Subsurface ri.type = RelationType.None; } + ri.Msg = ToolBox.GetAttributeString(element, "msg", ""); + foreach (XElement subElement in element.Elements()) { if (subElement.Name.ToString().ToLower() != "statuseffect") continue; ri.statusEffects.Add(StatusEffect.Load(subElement)); } - + return ri; } } diff --git a/Subsurface/Map/Hull.cs b/Subsurface/Map/Hull.cs index c7f1ece86..5c6661380 100644 --- a/Subsurface/Map/Hull.cs +++ b/Subsurface/Map/Hull.cs @@ -286,10 +286,10 @@ namespace Subsurface new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height), Color.Red*((100.0f-OxygenPercentage)/400.0f), true); - spriteBatch.DrawString(GUI.font, "Pressure: " + ((int)pressure - rect.Y).ToString() + + spriteBatch.DrawString(GUI.Font, "Pressure: " + ((int)pressure - rect.Y).ToString() + " - Lethality: " + lethalPressure + " - Oxygen: "+((int)OxygenPercentage), new Vector2(rect.X+10, -rect.Y+10), Color.Black); - spriteBatch.DrawString(GUI.font, volume +" / "+ FullVolume, new Vector2(rect.X+10, -rect.Y+30), Color.Black); + spriteBatch.DrawString(GUI.Font, volume +" / "+ FullVolume, new Vector2(rect.X+10, -rect.Y+30), Color.Black); if (isSelected && editing) { diff --git a/Subsurface/Map/Levels/Level.cs b/Subsurface/Map/Levels/Level.cs index d153f73a5..677ca8c03 100644 --- a/Subsurface/Map/Levels/Level.cs +++ b/Subsurface/Map/Levels/Level.cs @@ -82,7 +82,13 @@ namespace Subsurface get { return seed; } } - public Level(string seed, int width, int height, int siteInterval) + public float Difficulty + { + get; + private set; + } + + public Level(string seed, float difficulty, int width, int height, int siteInterval) { if (shaftTexture == null) shaftTexture = Game1.textureLoader.FromFile("Content/Map/shaft.png"); @@ -90,16 +96,24 @@ namespace Subsurface this.siteInterval = siteInterval; + this.Difficulty = difficulty; + borders = new Rectangle(0, 0, width, height); } + public static Level CreateRandom(LocationConnection locationConnection) + { + int seed = locationConnection.Locations[0].GetHashCode() | locationConnection.Locations[1].GetHashCode(); + return new Level(seed.ToString(), locationConnection.Difficulty, 100000, 40000, 2000); + } + public static Level CreateRandom(string seed = "") { if (seed == "") { seed = Rand.Range(0, int.MaxValue, false).ToString(); } - return new Level(seed, 100000, 40000, 2000); + return new Level(seed, Rand.Range(30.0f,80.0f,false), 100000, 40000, 2000); } public void Generate(float minWidth, bool mirror=false) diff --git a/Subsurface/Map/Location.cs b/Subsurface/Map/Location.cs index dd6fa2cc2..016cd05ea 100644 --- a/Subsurface/Map/Location.cs +++ b/Subsurface/Map/Location.cs @@ -15,6 +15,8 @@ namespace Subsurface LocationType type; + public List connections; + public string Name { get { return name; } @@ -30,6 +32,8 @@ namespace Subsurface this.name = RandomName(LocationType.Random()); this.mapPosition = mapPosition; + + connections = new List(); } public static Location CreateRandom(Vector2 position) diff --git a/Subsurface/Map/Map.cs b/Subsurface/Map/Map.cs index 61c1314e5..01854e9fd 100644 --- a/Subsurface/Map/Map.cs +++ b/Subsurface/Map/Map.cs @@ -10,6 +10,9 @@ namespace Subsurface { class Map { + Vector2 difficultyIncrease = new Vector2(5.0f,10.0f); + Vector2 difficultyCutoff = new Vector2(80.0f, 100.0f); + private List levels; private List locations; @@ -31,11 +34,20 @@ namespace Subsurface get { return currentLocation; } } + public int CurrentLocationIndex + { + get { return locations.IndexOf(currentLocation); } + } + public Location SelectedLocation { get { return selectedLocation; } } + public int Seed + { + get { return seed; } + } public Map(int seed, int size) { @@ -53,9 +65,18 @@ namespace Subsurface iceCraters = Game1.textureLoader.FromFile("Content/Map/iceCraters.png"); iceCrack = Game1.textureLoader.FromFile("Content/Map/iceCrack.png"); + + Rand.SetSyncedSeed(this.seed); + GenerateLocations(); - currentLocation = locations[locations.Count/2]; + currentLocation = locations[locations.Count / 2]; + GenerateDifficulties(currentLocation, new List (connections), 10.0f); + + foreach (LocationConnection connection in connections) + { + connection.Level = Level.CreateRandom(connection); + } } private void GenerateLocations() @@ -65,7 +86,7 @@ namespace Subsurface List sites = new List(); for (int i = 0; i < 50; i++) { - sites.Add(new Vector2(Rand.Range(0.0f, size), Rand.Range(0.0f, size))); + sites.Add(new Vector2(Rand.Range(0.0f, size, false), Rand.Range(0.0f, size, false))); } List edges = voronoi.MakeVoronoiGraph(sites, size, size); @@ -91,7 +112,7 @@ namespace Subsurface Vector2[] points = new Vector2[] { edge.point1, edge.point2 }; - int positionIndex = Rand.Int(1); + int positionIndex = Rand.Int(1,false); Vector2 position = points[positionIndex]; if (newLocations[1 - i] != null && newLocations[1 - i].MapPosition == position) position = points[1 - positionIndex]; @@ -100,9 +121,7 @@ namespace Subsurface locations.Add(newLocations[i]); } int seed = (newLocations[0].GetHashCode() | newLocations[1].GetHashCode()); - connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom(seed.ToString()))); - - + connections.Add(new LocationConnection(newLocations[0], newLocations[1])); } float minDistance = 50.0f; @@ -120,17 +139,22 @@ namespace Subsurface foreach (LocationConnection connection2 in connections) { - if (connection == connection2) continue; if (connection2.Locations[0] == connection.Locations[0]) connection2.Locations[0] = connection.Locations[1]; if (connection2.Locations[1] == connection.Locations[0]) connection2.Locations[1] = connection.Locations[1]; } } + foreach (LocationConnection connection in connections) + { + connection.Locations[0].connections.Add(connection); + connection.Locations[1].connections.Add(connection); + } + for (int i = connections.Count - 1; i >= 0; i--) { LocationConnection connection = connections[i]; - for (int n = i-1; n >= 0; n--) + for (int n = i - 1; n >= 0; n--) { if (connection.Locations.Contains(connections[n].Locations[0]) && connection.Locations.Contains(connections[n].Locations[1])) @@ -147,6 +171,31 @@ namespace Subsurface int generations = (int)(Math.Sqrt(Vector2.Distance(start, end) / 10.0f)); connection.CrackSegments = GenerateCrack(start, end, generations); } + + } + + private void GenerateDifficulties(Location start, List locations, float currDifficulty) + { + + if (start.Name.Contains("Sabbati")) + { + int a = 1; + } + //start.Difficulty = currDifficulty; + currDifficulty += Rand.Range(difficultyIncrease.X, difficultyIncrease.Y, false); + if (currDifficulty > Rand.Range(difficultyCutoff.X, difficultyCutoff.Y, false)) currDifficulty = 10.0f; + + foreach (LocationConnection connection in start.connections) + { + if (!locations.Contains(connection)) continue; + + Location nextLocation = connection.OtherLocation(start); + locations.Remove(connection); + + connection.Difficulty = currDifficulty; + + GenerateDifficulties(nextLocation, locations, currDifficulty); + } } private List GenerateCrack(Vector2 start, Vector2 end, int generations) @@ -170,7 +219,7 @@ namespace Subsurface Vector2 normal = Vector2.Normalize(endSegment - startSegment); normal = new Vector2(-normal.Y, normal.X); - midPoint += normal * Rand.Range(-offsetAmount, offsetAmount); + midPoint += normal * Rand.Range(-offsetAmount, offsetAmount, false); segments.Insert(i, new Vector2[] { startSegment, midPoint }); segments.Insert(i+1, new Vector2[] { midPoint, endSegment }); @@ -188,6 +237,16 @@ namespace Subsurface selectedLocation = null; } + public void SetLocation(int index) + { + if (index < 0 || index >= locations.Count) + { + DebugConsole.ThrowError("Location index out of bounds"); + return; + } + currentLocation = locations[index]; + } + private Location highlightedLocation; public void Draw(SpriteBatch spriteBatch, Rectangle rect) { @@ -217,7 +276,7 @@ namespace Subsurface foreach (LocationConnection connection in connections) { - Color crackColor = Color.White; + Color crackColor = Color.Lerp(Color.LightGreen, Color.DarkRed, connection.Difficulty/100.0f); if (highlightedLocation != currentLocation && connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation)) @@ -283,7 +342,7 @@ namespace Subsurface pos.Y = (int)pos.Y; if (highlightedLocation==location) { - spriteBatch.DrawString(GUI.font, location.Name, pos + new Vector2(-50, -20), Color.DarkRed); + spriteBatch.DrawString(GUI.Font, location.Name, pos + new Vector2(-50, -20), Color.DarkRed); } GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 4, (int)pos.Y - 4, 5 + 8, 5 + 8), Color.DarkRed, false); } @@ -296,6 +355,8 @@ namespace Subsurface { private Location[] locations; private Level level; + + public float Difficulty; public List CrackSegments; @@ -307,12 +368,30 @@ namespace Subsurface public Level Level { get { return level; } + set { level = value; } } - - public LocationConnection(Location location1, Location location2, Level level) + + public LocationConnection(Location location1, Location location2) { locations = new Location[] { location1, location2 }; - this.level = level; + //location1.connections.Add(this); + //location2.connections.Add(this); + } + + public Location OtherLocation(Location location) + { + if (locations[0] == location) + { + return locations[1]; + } + else if (locations[1] == location) + { + return locations[0]; + } + else + { + return null; + } } } } diff --git a/Subsurface/Map/MapEntityPrefab.cs b/Subsurface/Map/MapEntityPrefab.cs index 7e063aa6d..eda03ebec 100644 --- a/Subsurface/Map/MapEntityPrefab.cs +++ b/Subsurface/Map/MapEntityPrefab.cs @@ -132,7 +132,7 @@ namespace Subsurface public void DrawListLine(SpriteBatch spriteBatch, Vector2 pos, Color color) { - spriteBatch.DrawString(GUI.font, name, pos, color); + spriteBatch.DrawString(GUI.Font, name, pos, color); } } diff --git a/Subsurface/Map/Submarine.cs b/Subsurface/Map/Submarine.cs index 22813b215..b0cecc7d0 100644 --- a/Subsurface/Map/Submarine.cs +++ b/Subsurface/Map/Submarine.cs @@ -316,6 +316,8 @@ namespace Subsurface public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List ignoredBodies = null) { + + float closestFraction = 1.0f; Body closestBody = null; Game1.World.RayCast((fixture, point, normal, fraction) => @@ -414,7 +416,7 @@ namespace Subsurface Vector2 translateAmount = speed * deltaTime; translateAmount += ConvertUnits.ToDisplayUnits(hullBody.Position) * collisionRigidness; - if (targetPosition != Vector2.Zero && Vector2.Distance(targetPosition, Position) > 5.0f) + if (targetPosition != Vector2.Zero && Vector2.Distance(targetPosition, Position) > 50.0f) { translateAmount += (targetPosition - Position) * 0.01f; } @@ -582,7 +584,7 @@ namespace Subsurface return; } - newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime); + //newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime); targetPosition = newTargetPosition; speed = newSpeed; diff --git a/Subsurface/Map/WaterRenderer.cs b/Subsurface/Map/WaterRenderer.cs index 93a68c249..0489d77d1 100644 --- a/Subsurface/Map/WaterRenderer.cs +++ b/Subsurface/Map/WaterRenderer.cs @@ -42,7 +42,7 @@ namespace Subsurface Effect effect; - Vector2 wavePos; + public Vector2 wavePos; public WaterVertex[] vertices = new WaterVertex[DefaultBufferSize]; @@ -96,6 +96,11 @@ namespace Subsurface vertexBuffer.SetData(verts); + wavePos.X += 0.0001f; + wavePos.Y += 0.0001f; + + effect.Parameters["xWavePos"].SetValue(wavePos); + effect.CurrentTechnique = effect.Techniques["WaterShader"]; effect.Parameters["xTexture"].SetValue(texture); effect.Parameters["xView"].SetValue(Matrix.Identity); @@ -115,11 +120,7 @@ namespace Subsurface vertexBuffer.SetData(vertices); - wavePos.X += 0.0001f; - wavePos.Y += 0.0001f; - - effect.Parameters["xBumpPos"].SetValue(cam.Position/Game1.GraphicsWidth/cam.Zoom); - effect.Parameters["xWavePos"].SetValue(wavePos); + effect.Parameters["xBumpPos"].SetValue(cam.Position / Game1.GraphicsWidth / cam.Zoom); effect.CurrentTechnique = effect.Techniques["EmptyShader"]; effect.Parameters["xTexture"].SetValue(texture); diff --git a/Subsurface/Map/WayPoint.cs b/Subsurface/Map/WayPoint.cs index 5027876c3..bbf47189a 100644 --- a/Subsurface/Map/WayPoint.cs +++ b/Subsurface/Map/WayPoint.cs @@ -54,7 +54,7 @@ namespace Subsurface public override void Draw(SpriteBatch spriteBatch, bool editing) { - //if (!editing) return; + if (!editing && !Game1.DebugDraw) return; Point pos = new Point((int)Position.X, (int)Position.Y); diff --git a/Subsurface/Networking/GameClient.cs b/Subsurface/Networking/GameClient.cs index ade53d4c7..3528a3bb2 100644 --- a/Subsurface/Networking/GameClient.cs +++ b/Subsurface/Networking/GameClient.cs @@ -93,6 +93,8 @@ namespace Subsurface.Networking //update.Elapsed += new System.Timers.ElapsedEventHandler(Update); // Funtion that waits for connection approval info from server + + reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to " + serverIP, new string[0]); CoroutineManager.StartCoroutine(WaitForStartingInfo()); // Start the timer @@ -106,11 +108,17 @@ namespace Subsurface.Networking return true; } + private bool SelectMainMenu(GUIButton button, object obj) + { + Disconnect(); + Game1.NetworkMember = null; + Game1.MainMenuScreen.Select(); + return true; + } + // Before main looping starts, we loop here and wait for approval message private IEnumerable WaitForStartingInfo() { - reconnectBox = new GUIMessageBox("CONNECTING", "Connecting to "+serverIP, new string[0]); - // When this is set to true, we are approved and ready to go bool CanStart = false; @@ -162,7 +170,14 @@ namespace Subsurface.Networking } break; case NetIncomingMessageType.StatusChanged: - Debug.WriteLine((NetConnectionStatus)inc.ReadByte()); + NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte(); + Debug.WriteLine(connectionStatus); + + if (connectionStatus != NetConnectionStatus.Connected) + { + string denyMessage = inc.ReadString(); + DebugConsole.ThrowError(denyMessage); + } break; default: @@ -179,13 +194,15 @@ namespace Subsurface.Networking if (Client.ConnectionStatus != NetConnectionStatus.Connected) { - reconnectBox = new GUIMessageBox("CONNECTION FAILED", "Failed to connect to server.", new string[] { "Retry", "Cancel" }); - reconnectBox.Buttons[0].OnClicked += RetryConnection; - reconnectBox.Buttons[0].OnClicked += reconnectBox.Close; + var reconnect = new GUIMessageBox("CONNECTION FAILED", "Failed to connect to server.", new string[] { "Retry", "Cancel" }); + reconnect.Buttons[0].OnClicked += RetryConnection; + reconnect.Buttons[0].OnClicked += reconnect.Close; + reconnect.Buttons[1].OnClicked += SelectMainMenu; + reconnect.Buttons[1].OnClicked += reconnect.Close; } else { - Game1.NetLobbyScreen.Select(); + if (Screen.Selected == Game1.MainMenuScreen) Game1.NetLobbyScreen.Select(); connected = true; } @@ -195,21 +212,32 @@ namespace Subsurface.Networking public override void Update() { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.K)) - { - SendRandomData(); - } + //if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.K)) + //{ + // SendRandomData(); + //} + //if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.L)) + //{ + // ConnectToServer(serverIP); + //} + if (gameStarted) inGameHUD.Update((float)Physics.step); if (!connected || updateTimer > DateTime.Now) return; - if (Client.ConnectionStatus == NetConnectionStatus.Disconnected) + if (Client.ConnectionStatus == NetConnectionStatus.Disconnected && reconnectBox==null) { reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]); - + connected = false; + ConnectToServer(serverIP); return; } + else if (reconnectBox!=null) + { + reconnectBox.Close(null,null); + reconnectBox = null; + } if (myCharacter != null) { @@ -368,8 +396,8 @@ namespace Subsurface.Networking Game1.NetLobbyScreen.Select(); if (Game1.GameSession!=null) Game1.GameSession.EndShift(""); - - DebugConsole.ThrowError(endMessage); + + new GUIMessageBox("The round has ended", endMessage); myCharacter = null; diff --git a/Subsurface/Networking/GameServer.cs b/Subsurface/Networking/GameServer.cs index 8207cbf78..e0ef07a13 100644 --- a/Subsurface/Networking/GameServer.cs +++ b/Subsurface/Networking/GameServer.cs @@ -120,24 +120,52 @@ namespace Subsurface.Networking DebugConsole.NewMessage("New player has joined the server", Color.White); + + Client existingClient = connectedClients.Find(c=> c.Connection == inc.SenderConnection); + if (existingClient==null) + { + string version = "", name = ""; + try + { + version = inc.ReadString(); + name = inc.ReadString(); + } + catch + { + inc.SenderConnection.Deny("Connection error - server failed to read your ConnectionApproval message"); + break; + } + + if (version != Game1.Version.ToString()) + { + inc.SenderConnection.Deny("Subsurface version " + Game1.Version + " required to connect to the server (Your version: " + version + ")"); + break; + } + else if (connectedClients.Find(c => c.name.ToLower() == name.ToLower())!=null) + { + inc.SenderConnection.Deny("The name ''" + name + "'' is already in use. Please choose another name."); + break; + } + + int id = 1; + while (connectedClients.Find(c=>c.ID==id)!=null) + { + id++; + } + Client newClient = new Client(name, id); + newClient.Connection = inc.SenderConnection; + newClient.version = version; + + connectedClients.Add(newClient); + + inc.SenderConnection.Approve(); + } + else + { + inc.SenderConnection.Deny(); + } //Character ch = new Character("Content/Characters/Human/human.xml"); - string version = inc.ReadString(); - string name = inc.ReadString(); - - int id = 1; - while (connectedClients.Find(c=>c.ID==id)!=null) - { - id++; - } - - Client newClient = new Client(name, id); - newClient.Connection = inc.SenderConnection; - newClient.version = version; - - connectedClients.Add(newClient); - - inc.SenderConnection.Approve(); break; case NetIncomingMessageType.StatusChanged: Debug.WriteLine(inc.SenderConnection + " status changed. " + (NetConnectionStatus)inc.SenderConnection.Status); @@ -151,7 +179,11 @@ namespace Subsurface.Networking { DisconnectClient(sender, sender.name+" was unable to connect to the server (nonmatching game version)", "Subsurface version " + Game1.Version + " required to connect to the server (Your version: " + sender.version + ")"); - + } + else if (connectedClients.Find(x => x.name == sender.name && x != sender)!=null) + { + DisconnectClient(sender, sender.name + " was unable to connect to the server (name already in use)", + "The name ''"+sender.name+"'' is already in use. Please choose another name."); } else { @@ -178,8 +210,7 @@ namespace Subsurface.Networking if (myClient != null) outmsg.Write(myClient.name); Server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered, 0); - - + //notify other clients about the new client outmsg = Server.CreateMessage(); outmsg.Write((byte)PacketTypes.PlayerJoined); @@ -200,8 +231,6 @@ namespace Subsurface.Networking DisconnectClient(inc.SenderConnection); } - - break; case NetIncomingMessageType.Data: @@ -380,7 +409,7 @@ namespace Subsurface.Networking private bool EndButtonHit(GUIButton button, object obj) { - Game1.GameSession.gameMode.End("The round has ended"); + Game1.GameSession.gameMode.End("Server admin has ended the round"); return true; } @@ -454,14 +483,15 @@ namespace Subsurface.Networking public void KickPlayer(string playerName) { playerName = playerName.ToLower(); - Client client = null; foreach (Client c in connectedClients) { - if (c.name.ToLower() != playerName) continue; - client = c; + if (c.name.ToLower() == playerName) KickClient(c); break; } + } + private void KickClient(Client client) + { if (client == null) return; DisconnectClient(client, client.name + " has been kicked from the server", "You have been kicked from the server"); @@ -526,9 +556,22 @@ namespace Subsurface.Networking private void ReadCharacterData(NetIncomingMessage message) { - string name = message.ReadString(); - Gender gender = message.ReadBoolean() ? Gender.Male : Gender.Female; - int headSpriteId = message.ReadInt32(); + string name = ""; + Gender gender = Gender.Male; + int headSpriteId = 0; + + try + { + name = message.ReadString(); + gender = message.ReadBoolean() ? Gender.Male : Gender.Female; + headSpriteId = message.ReadInt32(); + } + catch + { + name = ""; + gender = Gender.Male; + headSpriteId = 0; + } List jobPreferences = new List(); diff --git a/Subsurface/Networking/NetworkMember.cs b/Subsurface/Networking/NetworkMember.cs index d191307d0..6d3641cf6 100644 --- a/Subsurface/Networking/NetworkMember.cs +++ b/Subsurface/Networking/NetworkMember.cs @@ -59,6 +59,7 @@ namespace Subsurface.Networking public NetworkMember() { inGameHUD = new GUIFrame(new Rectangle(0,0,0,0), null, null); + inGameHUD.CanBeFocused = false; int width = 350, height = 100; chatBox = new GUIListBox(new Rectangle( @@ -70,6 +71,7 @@ namespace Subsurface.Networking var textBox = new GUITextBox( new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25), Color.White * 0.5f, Color.Black, Alignment.TopLeft, Alignment.Left, GUI.style, inGameHUD); + textBox.Font = GUI.SmallFont; textBox.OnEnter = EnterChatMessage; } @@ -89,22 +91,27 @@ namespace Subsurface.Networking { Game1.NetLobbyScreen.NewChatMessage(message, messageColor[(int)messageType]); + while (chatBox.CountChildren > 20) + { + chatBox.RemoveChild(chatBox.children[1]); + } + GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), message, ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, messageColor[(int)messageType], Alignment.Left, null, null, true); + msg.Font = GUI.SmallFont; msg.Padding = new Vector4(20.0f, 0, 0, 0); //float prevScroll = chatBox.BarScroll; - //chatBox.AddChild(msg); + float prevSize = chatBox.BarSize; + float oldScroll = chatBox.BarScroll; - //while (chatBox.CountChildren > 20) - //{ - // chatBox.RemoveChild(chatBox.children[0]); - //} + msg.Padding = new Vector4(20, 0, 0, 0); + chatBox.AddChild(msg); - //if (prevScroll == 1.0f) chatBox.BarScroll = 1.0f; + if ((prevSize == 1.0f && chatBox.BarScroll == 0.0f) || (prevSize < 1.0f && chatBox.BarScroll == 1.0f)) chatBox.BarScroll = 1.0f; GUI.PlayMessageSound(); } diff --git a/Subsurface/Properties/AssemblyInfo.cs b/Subsurface/Properties/AssemblyInfo.cs index 88b6474e0..f3d07924d 100644 --- a/Subsurface/Properties/AssemblyInfo.cs +++ b/Subsurface/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.0.0")] +[assembly: AssemblyVersion("0.0.1.0")] +[assembly: AssemblyFileVersion("0.0.1.0")] diff --git a/Subsurface/SaveUtil.cs b/Subsurface/SaveUtil.cs index a4651ee82..6ec6c17dd 100644 --- a/Subsurface/SaveUtil.cs +++ b/Subsurface/SaveUtil.cs @@ -30,7 +30,7 @@ namespace Subsurface CompressDirectory(tempPath, savePath, null); - Directory.Delete(tempPath, true); + //Directory.Delete(tempPath, true); } public static void LoadGame(string filePath) @@ -42,7 +42,7 @@ namespace Subsurface Submarine selectedMap = Submarine.Load(tempPath +"\\map.gz"); Game1.GameSession = new GameSession(selectedMap, filePath, tempPath + "\\gamesession.xml"); - Directory.Delete(tempPath, true); + //Directory.Delete(tempPath, true); } public static string CreateSavePath(string saveFolder, string fileName="save") @@ -61,7 +61,7 @@ namespace Subsurface i++; } - return saveFolder + fileName + i; + return saveFolder + fileName + i + extension; } public static void CompressStringToFile(string fileName, string value) diff --git a/Subsurface/Screens/GameScreen.cs b/Subsurface/Screens/GameScreen.cs index dc1f5c2c7..5888156fe 100644 --- a/Subsurface/Screens/GameScreen.cs +++ b/Subsurface/Screens/GameScreen.cs @@ -57,16 +57,16 @@ namespace Subsurface AmbientSoundManager.Update(); - if (Game1.GameSession!=null && Game1.GameSession.Level != null) - { - Vector2 targetMovement = Vector2.Zero; - if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f; - if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f; - if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f; - if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f; + //if (Game1.GameSession!=null && Game1.GameSession.Level != null) + //{ + // Vector2 targetMovement = Vector2.Zero; + // if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f; + // if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f; + // if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f; + // if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f; - Game1.GameSession.Submarine.ApplyForce(targetMovement*100000.0f); - } + // Game1.GameSession.Submarine.ApplyForce(targetMovement*100000.0f); + //} if (Game1.GameSession!=null) Game1.GameSession.Update((float)deltaTime); //EventManager.Update(gameTime); diff --git a/Subsurface/Screens/LobbyScreen.cs b/Subsurface/Screens/LobbyScreen.cs index 0bd660047..49e1438fe 100644 --- a/Subsurface/Screens/LobbyScreen.cs +++ b/Subsurface/Screens/LobbyScreen.cs @@ -243,7 +243,7 @@ namespace Subsurface if (selectedRightPanel == (int)PanelTab.Map) { - Game1.GameSession.map.Draw(spriteBatch, new Rectangle( + Game1.GameSession.Map.Draw(spriteBatch, new Rectangle( rightPanel[selectedRightPanel].Rect.Right - 20 - 400, rightPanel[selectedRightPanel].Rect.Y + 20, 400, 400)); diff --git a/Subsurface/Screens/MainMenu.cs b/Subsurface/Screens/MainMenu.cs index dccb87f5f..70714c967 100644 --- a/Subsurface/Screens/MainMenu.cs +++ b/Subsurface/Screens/MainMenu.cs @@ -15,6 +15,8 @@ namespace Subsurface private GUIListBox saveList; + private GUITextBox seedBox; + private GUITextBox nameBox, ipBox; private Game1 game; @@ -58,23 +60,30 @@ namespace Subsurface menuTabs[(int)Tabs.NewGame] = new GUIFrame(panelRect, GUI.style); //menuTabs[(int)Tabs.NewGame].Padding = GUI.style.smallPadding; - new GUITextBlock(new Rectangle(0, 0, 0, 30), "New Game", null, null, Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.NewGame]); + new GUITextBlock(new Rectangle(0, -20, 0, 30), "New Game", null, null, Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.NewGame]); new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected submarine:", null, null, Alignment.Left, GUI.style, menuTabs[(int)Tabs.NewGame]); mapList = new GUIListBox(new Rectangle(0, 60, 200, 360), GUI.style, menuTabs[(int)Tabs.NewGame]); - foreach (Submarine map in Submarine.SavedSubmarines) + foreach (Submarine sub in Submarine.SavedSubmarines) { GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), - map.Name, + sub.Name, GUI.style, Alignment.Left, Alignment.Left, mapList); textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); - textBlock.UserData = map; + textBlock.UserData = sub; } if (Submarine.SavedSubmarines.Count > 0) mapList.Select(Submarine.SavedSubmarines[0]); + new GUITextBlock(new Rectangle((int)(mapList.Rect.Width + 20), 30, 100, 20), + "Map Seed: ", GUI.style, Alignment.Left, Alignment.TopLeft, menuTabs[(int)Tabs.NewGame]); + + seedBox = new GUITextBox(new Rectangle((int)(mapList.Rect.Width + 20), 60, 180, 20), + Alignment.TopLeft, GUI.style, menuTabs[(int)Tabs.NewGame]); + seedBox.Text = ToolBox.RandomSeed(8); + button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start",Alignment.BottomRight, GUI.style, menuTabs[(int)Tabs.NewGame]); button.OnClicked = StartGame; @@ -102,7 +111,7 @@ namespace Subsurface 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, GUI.style, menuTabs[(int)Tabs.LoadGame]); + saveList = new GUIListBox(new Rectangle(0, 60, 200, 360), Color.White, GUI.style, menuTabs[(int)Tabs.LoadGame]); foreach (string saveFile in saveFiles) { @@ -140,7 +149,7 @@ namespace Subsurface for (int i = 1; i < 4; i++ ) { - button = new GUIButton(new Rectangle(0, 0, 100, 30), "Back", Alignment.TopLeft, GUI.style, menuTabs[i]); + button = new GUIButton(new Rectangle(-20, -20, 100, 30), "Back", Alignment.TopLeft, GUI.style, menuTabs[i]); button.OnClicked = PreviousTab; } @@ -170,13 +179,17 @@ namespace Subsurface public override void Update(double deltaTime) { menuTabs[selectedTab].Update((float)deltaTime); + + Game1.TitleScreen.Position.Y = MathHelper.Lerp(Game1.TitleScreen.Position.Y, -870.0f, 0.1f); } public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) { graphics.Clear(Color.CornflowerBlue); - Game1.GameScreen.DrawMap(graphics, spriteBatch); + Game1.TitleScreen.Draw(spriteBatch, graphics, -1.0f, (float)deltaTime); + + //Game1.GameScreen.DrawMap(graphics, spriteBatch); spriteBatch.Begin(); @@ -193,6 +206,7 @@ namespace Subsurface if (selectedMap == null) return false; Game1.GameSession = new GameSession(selectedMap, GameModePreset.list.Find(gm => gm.Name == "Single Player")); + (Game1.GameSession.gameMode as SinglePlayerMode).GenerateMap(seedBox.Text); Game1.LobbyScreen.Select(); diff --git a/Subsurface/Screens/NetLobbyScreen.cs b/Subsurface/Screens/NetLobbyScreen.cs index 02afdcfc4..26aaf70e9 100644 --- a/Subsurface/Screens/NetLobbyScreen.cs +++ b/Subsurface/Screens/NetLobbyScreen.cs @@ -110,6 +110,7 @@ namespace Subsurface chatBox = new GUIListBox(new Rectangle(0,0,0,chatFrame.Rect.Height-80), Color.White, GUI.style, chatFrame); textBox = new GUITextBox(new Rectangle(0, 25, 0, 25), Alignment.Bottom, GUI.style, chatFrame); + textBox.Font = GUI.SmallFont; textBox.OnEnter = EnterChatMessage; //player info panel ------------------------------------------------------------ @@ -309,9 +310,6 @@ namespace Subsurface { base.Update(deltaTime); - Game1.GameScreen.Cam.TargetPos = Vector2.Zero; - Game1.GameScreen.Cam.MoveCamera((float)deltaTime); - Vector2 pos = new Vector2( Submarine.Borders.X + Submarine.Borders.Width / 2, Submarine.Borders.Y - Submarine.Borders.Height / 2); @@ -324,6 +322,7 @@ namespace Subsurface pos += offset * 0.8f; Game1.GameScreen.Cam.TargetPos = pos; + Game1.GameScreen.Cam.MoveCamera((float)deltaTime); menu.Update((float)deltaTime); @@ -353,10 +352,16 @@ namespace Subsurface float prevSize = chatBox.BarSize; float oldScroll = chatBox.BarScroll; + while (chatBox.CountChildren>20) + { + chatBox.RemoveChild(chatBox.children[1]); + } + GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), message, ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black*0.1f, color, Alignment.Left, GUI.style, null, true); + msg.Font = GUI.SmallFont; msg.Padding = new Vector4(20, 0, 0, 0); chatBox.AddChild(msg); @@ -398,13 +403,12 @@ namespace Subsurface Gender gender = (Gender)obj; Game1.Client.CharacterInfo.Gender = gender; Game1.Client.SendCharacterData(); - UpdatePreviewPlayer(Game1.Client.CharacterInfo); + //CreatePreviewCharacter(); } - catch - { - return false; - } + catch {} + + UpdatePreviewPlayer(Game1.Client.CharacterInfo); return true; } diff --git a/Subsurface/Sounds/AmbientSoundManager.cs b/Subsurface/Sounds/AmbientSoundManager.cs index 0c0c24181..bcf5e4a6f 100644 --- a/Subsurface/Sounds/AmbientSoundManager.cs +++ b/Subsurface/Sounds/AmbientSoundManager.cs @@ -65,18 +65,21 @@ namespace Subsurface private static BackgroundMusic[] musicClips; private static float musicVolume; - public static void Init(string filePath) + public static IEnumerable Init() { - //Sound.Loop(music[0]); - waterAmbience = Sound.Load("Content/Sounds/Water/WaterAmbience.ogg"); - + yield return Status.Running; flowSounds[0] = Sound.Load("Content/Sounds/Water/FlowSmall.ogg"); + yield return Status.Running; flowSounds[1] = Sound.Load("Content/Sounds/Water/FlowMedium.ogg"); + yield return Status.Running; flowSounds[2] = Sound.Load("Content/Sounds/Water/FlowLarge.ogg"); + yield return Status.Running; - XDocument doc = ToolBox.TryLoadXml(filePath); - if (doc == null) return; + XDocument doc = ToolBox.TryLoadXml("Content/Sounds/Sounds.xml"); + if (doc == null) yield return Status.Failure; + + yield return Status.Running; var xDamageSounds = doc.Root.Elements("damagesound").ToList(); @@ -86,6 +89,8 @@ namespace Subsurface int i = 0; foreach (XElement element in xDamageSounds) { + yield return Status.Running; + Sound sound = Sound.Load(ToolBox.GetAttributeString(element, "file", "")); if (sound == null) continue; @@ -122,12 +127,13 @@ namespace Subsurface musicClips[i] = new BackgroundMusic(file, type, priority); + yield return Status.Running; + i++; } } - //Sound.StartStream("Content/Sounds/Music/Simplex.ogg", 0.3f); - + yield return Status.Success; } diff --git a/Subsurface/StyleCop.Cache b/Subsurface/StyleCop.Cache index 85b124af3..1e523edb5 100644 --- a/Subsurface/StyleCop.Cache +++ b/Subsurface/StyleCop.Cache @@ -1637,51 +1637,6 @@ - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.01 19:12:30.866 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - Public and internal fields must start with an upper-case letter: style. - 69 - False - - - Public and internal fields must start with an upper-case letter: font. - 72 - False - - - The line contains unnecessary parenthesis. - 251 - 8588 - 8648 - 251 - 27 - 251 - 87 - False - - - 2014.04.01 10:18:24.000 @@ -1717,35 +1672,6 @@ - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.01 22:56:30.039 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - Public and internal fields must start with an upper-case letter: children. - 33 - False - - - 2014.04.01 10:18:24.000 @@ -1815,81 +1741,6 @@ - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.01 23:37:56.626 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - The line contains unnecessary parenthesis. - 88 - 2378 - 2409 - 88 - 33 - 88 - 64 - False - - - The line contains unnecessary parenthesis. - 160 - 4498 - 4521 - 160 - 30 - 160 - 53 - False - - - - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.01 20:01:07.071 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - Public and internal fields must start with an upper-case letter: messageBoxes. - 8 - False - - - 2014.04.01 10:18:24.000 @@ -1936,46 +1787,6 @@ - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.01 23:02:10.417 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - Public and internal fields must start with an upper-case letter: draggingBar. - 9 - False - - - The line contains unnecessary parenthesis. - 92 - 2837 - 2862 - 92 - 28 - 92 - 53 - False - - - 2014.04.01 10:18:24.000 @@ -1999,70 +1810,6 @@ - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.01 22:56:30.046 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - The line contains unnecessary parenthesis. - 80 - 2337 - 2368 - 80 - 49 - 80 - 80 - False - - - - - - 2014.04.01 10:18:24.000 - 2015.07.02 21:22:42.115 - 2015.07.02 21:15:54.746 - 2014.04.01 10:18:24.000 - 2014.04.01 10:18:24.000 - -1945363787 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - 2014.04.01 10:18:24.000 - 0 - - - - Field names must not start with an underscore. - 122 - False - - - 2014.04.01 10:18:24.000 @@ -5823,9 +5570,6 @@ - - DEBUG;TRACE;WINDOWS - 2014.04.01 10:18:24.000 @@ -6469,4 +6213,242 @@ + + DEBUG;TRACE;WINDOWS + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.15 14:53:11.475 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + + Public and internal fields must start with an upper-case letter: style. + 69 + False + + + Public and internal fields must start with an upper-case letter: font. + 72 + False + + + The line contains unnecessary parenthesis. + 251 + 8588 + 8648 + 251 + 27 + 251 + 87 + False + + + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.07 12:41:43.880 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + + Public and internal fields must start with an upper-case letter: children. + 33 + False + + + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.15 16:34:49.015 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + + The line contains unnecessary parenthesis. + 99 + 2634 + 2665 + 99 + 33 + 99 + 64 + False + + + The line contains unnecessary parenthesis. + 171 + 4754 + 4777 + 171 + 30 + 171 + 53 + False + + + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.08 16:30:04.115 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + + Public and internal fields must start with an upper-case letter: messageBoxes. + 8 + False + + + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.15 16:36:42.767 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + + Public and internal fields must start with an upper-case letter: draggingBar. + 9 + False + + + The line contains unnecessary parenthesis. + 92 + 2837 + 2862 + 92 + 28 + 92 + 53 + False + + + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.08 13:34:45.102 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + + + + 2014.04.01 10:18:24.000 + 2015.07.02 21:22:42.115 + 2015.07.07 12:41:43.886 + 2014.04.01 10:18:24.000 + 2014.04.01 10:18:24.000 + -1945363787 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + 2014.04.01 10:18:24.000 + 0 + + + \ No newline at end of file diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 268807c0d..d51d48407 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -65,6 +65,7 @@ + @@ -325,9 +326,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -419,7 +417,7 @@ PreserveNewest - + PreserveNewest Designer @@ -429,9 +427,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest Designer @@ -543,6 +538,7 @@ PreserveNewest + Designer PreserveNewest @@ -591,6 +587,15 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -769,7 +774,6 @@ - diff --git a/Subsurface/ToolBox.cs b/Subsurface/ToolBox.cs index 5c795845e..0d3918a26 100644 --- a/Subsurface/ToolBox.cs +++ b/Subsurface/ToolBox.cs @@ -1,11 +1,11 @@ -using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Xml.Linq; -using Microsoft.Xna.Framework; -using System.IO.Compression; namespace Subsurface { @@ -256,17 +256,17 @@ namespace Subsurface .ToArray()); } - public static string WrapText(string text, float lineWidth) + public static string WrapText(string text, float lineWidth, SpriteFont font) { - if (GUI.font.MeasureString(text).X < lineWidth) return text; + if (GUI.Font.MeasureString(text).X < lineWidth) return text; string[] words = text.Split(' '); StringBuilder wrappedText = new StringBuilder(); float linewidth = 0f; - float spaceWidth = GUI.font.MeasureString(" ").X; + float spaceWidth = font.MeasureString(" ").X; for (int i = 0; i < words.Length; ++i) { - Vector2 size = GUI.font.MeasureString(words[i]); + Vector2 size = font.MeasureString(words[i]); if (linewidth + size.X < lineWidth) { linewidth += size.X + spaceWidth; diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index a8a0ae7a1..a4567604d 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ diff --git a/Subsurface_content/Subsurface_content/Subsurface_content.csproj.PSM.cachefile b/Subsurface_content/Subsurface_content/Subsurface_content.csproj.PSM.cachefile index 6d7e38db0..1c77f5a53 100644 --- a/Subsurface_content/Subsurface_content/Subsurface_content.csproj.PSM.cachefile +++ b/Subsurface_content/Subsurface_content/Subsurface_content.csproj.PSM.cachefile @@ -1,2 +1,4 @@ Content\SpriteFont1.xnb +Content\SmallFont.xnb Content\SpriteFont1.spritefont +Content\SmallFont.spritefont diff --git a/Subsurface_content/Subsurface_content/bin/PSM/Content/SpriteFont1.spritefont b/Subsurface_content/Subsurface_content/bin/PSM/Content/SpriteFont1.spritefont index 0d1c4909c..285dd2a0d 100644 --- a/Subsurface_content/Subsurface_content/bin/PSM/Content/SpriteFont1.spritefont +++ b/Subsurface_content/Subsurface_content/bin/PSM/Content/SpriteFont1.spritefont @@ -41,7 +41,7 @@ with. If you uncomment this line, the default character will be substituted if you draw or measure text that contains characters which were not included in the font. --> - + _ + + + + Verdana + + 7 + + 0 + + true + + + + _ + + + + + + ~ + + + + À + ə + + + + diff --git a/Subsurface_content/Subsurface_contentContent/SpriteFont1.spritefont b/Subsurface_content/Subsurface_contentContent/SpriteFont1.spritefont index 0d1c4909c..285dd2a0d 100644 --- a/Subsurface_content/Subsurface_contentContent/SpriteFont1.spritefont +++ b/Subsurface_content/Subsurface_contentContent/SpriteFont1.spritefont @@ -41,7 +41,7 @@ with. If you uncomment this line, the default character will be substituted if you draw or measure text that contains characters which were not included in the font. --> - + _