diff --git a/Launcher/Launcher.csproj.user b/Launcher/Launcher.csproj.user new file mode 100644 index 000000000..fe7dc2232 --- /dev/null +++ b/Launcher/Launcher.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/Subsurface/Content/Items/Electricity/lamp.png b/Subsurface/Content/Items/Electricity/lamp.png new file mode 100644 index 000000000..253cfec45 Binary files /dev/null and b/Subsurface/Content/Items/Electricity/lamp.png differ diff --git a/Subsurface/Content/Items/Electricity/lights.xml b/Subsurface/Content/Items/Electricity/lights.xml new file mode 100644 index 000000000..021b3179e --- /dev/null +++ b/Subsurface/Content/Items/Electricity/lights.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Subsurface/Content/Items/Electricity/poweritems.xml b/Subsurface/Content/Items/Electricity/poweritems.xml index a8c515af5..63e6562fa 100644 --- a/Subsurface/Content/Items/Electricity/poweritems.xml +++ b/Subsurface/Content/Items/Electricity/poweritems.xml @@ -21,7 +21,10 @@ - + + + + diff --git a/Subsurface/Content/Items/Electricity/wire.png b/Subsurface/Content/Items/Electricity/wire.png index 8ca9b4186..b7e47f301 100644 Binary files a/Subsurface/Content/Items/Electricity/wire.png and b/Subsurface/Content/Items/Electricity/wire.png differ diff --git a/Subsurface/Content/Items/Engine/fabricator.png b/Subsurface/Content/Items/Engine/fabricator.png index ca1175552..29579d52d 100644 Binary files a/Subsurface/Content/Items/Engine/fabricator.png and b/Subsurface/Content/Items/Engine/fabricator.png differ diff --git a/Subsurface/Content/Items/Vent/vent.png b/Subsurface/Content/Items/Vent/vent.png index 565e2d57c..4d02e6fe9 100644 Binary files a/Subsurface/Content/Items/Vent/vent.png and b/Subsurface/Content/Items/Vent/vent.png differ diff --git a/Subsurface/Content/Items/wireCorner.png b/Subsurface/Content/Items/wireCorner.png index a0d28f839..57c55c01d 100644 Binary files a/Subsurface/Content/Items/wireCorner.png and b/Subsurface/Content/Items/wireCorner.png differ diff --git a/Subsurface/Content/Items/wireHorizontal.png b/Subsurface/Content/Items/wireHorizontal.png index 51809705c..28fec2afd 100644 Binary files a/Subsurface/Content/Items/wireHorizontal.png and b/Subsurface/Content/Items/wireHorizontal.png differ diff --git a/Subsurface/Content/Items/wireVertical.png b/Subsurface/Content/Items/wireVertical.png index 65fedc3af..6bbe6d0b4 100644 Binary files a/Subsurface/Content/Items/wireVertical.png and b/Subsurface/Content/Items/wireVertical.png differ diff --git a/Subsurface/Content/Lights/AlphaOne.dds b/Subsurface/Content/Lights/AlphaOne.dds new file mode 100644 index 000000000..20997b165 Binary files /dev/null and b/Subsurface/Content/Lights/AlphaOne.dds differ diff --git a/Subsurface/Content/Lights/alphaOne.png b/Subsurface/Content/Lights/alphaOne.png new file mode 100644 index 000000000..c6ffc1c0a Binary files /dev/null and b/Subsurface/Content/Lights/alphaOne.png differ diff --git a/Subsurface/Content/Lights/light.png b/Subsurface/Content/Lights/light.png new file mode 100644 index 000000000..54905d9aa Binary files /dev/null and b/Subsurface/Content/Lights/light.png differ diff --git a/Subsurface/Content/SmallFont.xnb b/Subsurface/Content/SmallFont.xnb new file mode 100644 index 000000000..31fcd8392 Binary files /dev/null and b/Subsurface/Content/SmallFont.xnb differ diff --git a/Subsurface/Content/SpriteFont1.xnb b/Subsurface/Content/SpriteFont1.xnb index ab9f04af5..37d6342fc 100644 Binary files a/Subsurface/Content/SpriteFont1.xnb and b/Subsurface/Content/SpriteFont1.xnb differ diff --git a/Subsurface/DebugConsole.cs b/Subsurface/DebugConsole.cs index 55a91b956..cc9caae8e 100644 --- a/Subsurface/DebugConsole.cs +++ b/Subsurface/DebugConsole.cs @@ -216,7 +216,12 @@ namespace Subsurface case "fowenabled": case "fow": case "drawfow": - Lights.LightManager.FowEnabled = !Lights.LightManager.FowEnabled; + Game1.LightManager.FowEnabled = !Game1.LightManager.FowEnabled; + break; + case "lighting": + case "lightingenabled": + case "light": + Game1.LightManager.LightingEnabled = !Game1.LightManager.LightingEnabled; break; case "lobbyscreen": case "lobby": diff --git a/Subsurface/GUI/GUITextBox.cs b/Subsurface/GUI/GUITextBox.cs index 00cbbda46..725b97a5f 100644 --- a/Subsurface/GUI/GUITextBox.cs +++ b/Subsurface/GUI/GUITextBox.cs @@ -24,6 +24,12 @@ namespace Subsurface public delegate bool OnTextChangedHandler(GUITextBox textBox, string text); public OnTextChangedHandler OnTextChanged; + public GUITextBlock.TextGetterHandler TextGetter + { + get { return textBlock.TextGetter; } + set { textBlock.TextGetter = value; } + } + public bool Wrap { get { return textBlock.Wrap; } @@ -171,15 +177,14 @@ namespace Subsurface public override void Draw(SpriteBatch spriteBatch) { DrawChildren(spriteBatch); - - + Vector2 caretPos = textBlock.CaretPos; if (caretVisible && Selected) { GUI.DrawLine(spriteBatch, new Vector2((int)caretPos.X + 2, caretPos.Y + 3), - new Vector2((int)caretPos.X + 2, caretPos.Y + Font.MeasureString(Text).Y - 3), + new Vector2((int)caretPos.X + 2, caretPos.Y + Font.MeasureString("I").Y - 3), textBlock.TextColor * (textBlock.TextColor.A / 255.0f)); } diff --git a/Subsurface/Game1.cs b/Subsurface/Game1.cs index bcdd5e2c0..8b8767ea7 100644 --- a/Subsurface/Game1.cs +++ b/Subsurface/Game1.cs @@ -33,6 +33,8 @@ namespace Subsurface public static EditMapScreen EditMapScreen; public static EditCharacterScreen EditCharacterScreen; + public static Lights.LightManager LightManager; + public static ContentPackage SelectedPackage { get { return Config.SelectedContentPackage; } @@ -160,6 +162,8 @@ namespace Subsurface GUI.Font = Content.Load("SpriteFont1"); GUI.SmallFont = Content.Load("SmallFont"); + LightManager = new Lights.LightManager(GraphicsDevice); + Hull.renderer = new WaterRenderer(GraphicsDevice); loadState = 1.0f; yield return Status.Running; diff --git a/Subsurface/GameSession/GameSession.cs b/Subsurface/GameSession/GameSession.cs index 63392e487..fe6bdea88 100644 --- a/Subsurface/GameSession/GameSession.cs +++ b/Subsurface/GameSession/GameSession.cs @@ -131,7 +131,7 @@ namespace Subsurface public void StartShift(TimeSpan duration, Level level, bool reloadSub = true) { - Lights.LightManager.FowEnabled = (Game1.Server==null); + Game1.LightManager.FowEnabled = (Game1.Server==null); this.level = level; diff --git a/Subsurface/Items/Components/Container.cs b/Subsurface/Items/Components/Container.cs index e3aa1a386..c9b3f6eca 100644 --- a/Subsurface/Items/Components/Container.cs +++ b/Subsurface/Items/Components/Container.cs @@ -141,7 +141,7 @@ namespace Subsurface.Items.Components } - public override void Draw(SpriteBatch spriteBatch) + public override void Draw(SpriteBatch spriteBatch, bool editing) { base.Draw(spriteBatch); diff --git a/Subsurface/Items/Components/Door.cs b/Subsurface/Items/Components/Door.cs index bbd6c59df..d26ab9113 100644 --- a/Subsurface/Items/Components/Door.cs +++ b/Subsurface/Items/Components/Door.cs @@ -250,8 +250,8 @@ namespace Subsurface.Items.Components linkedGap.Open = 1.0f; if (convexHull2 != null) convexHull2.Enabled = false; } - - public override void Draw(SpriteBatch spriteBatch) + + public override void Draw(SpriteBatch spriteBatch, bool editing) { Color color = (item.IsSelected) ? Color.Green : Color.White; color = color * (item.Condition / 100.0f); diff --git a/Subsurface/Items/Components/Holdable/Holdable.cs b/Subsurface/Items/Components/Holdable/Holdable.cs index 9e22c2793..cae56f6e0 100644 --- a/Subsurface/Items/Components/Holdable/Holdable.cs +++ b/Subsurface/Items/Components/Holdable/Holdable.cs @@ -81,6 +81,8 @@ namespace Subsurface.Items.Components handlePos[i - 1] = ConvertUnits.ToSimUnits(handlePos[i - 1]); } + canBePicked = true; + //holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f); //holdAngle = MathHelper.ToRadians(holdAngle); } @@ -160,6 +162,8 @@ namespace Subsurface.Items.Components // return false; //} + if (attached) return false; + item.body = body; item.body.Enabled = true; diff --git a/Subsurface/Items/Components/Holdable/RepairTool.cs b/Subsurface/Items/Components/Holdable/RepairTool.cs index 98bb5e813..32711b03e 100644 --- a/Subsurface/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Items/Components/Holdable/RepairTool.cs @@ -173,8 +173,8 @@ namespace Subsurface.Items.Components //isActive = true; } - - public override void Draw(SpriteBatch spriteBatch) + + public override void Draw(SpriteBatch spriteBatch, bool editing) { if (!isActive) return; diff --git a/Subsurface/Items/Components/ItemComponent.cs b/Subsurface/Items/Components/ItemComponent.cs index cf2d7d63b..64e0aaf7a 100644 --- a/Subsurface/Items/Components/ItemComponent.cs +++ b/Subsurface/Items/Components/ItemComponent.cs @@ -293,7 +293,7 @@ namespace Subsurface /// a character has dropped the item public virtual void Drop(Character dropper) { } - public virtual void Draw(SpriteBatch spriteBatch) { } + public virtual void Draw(SpriteBatch spriteBatch, bool editing = false) { } public virtual void DrawHUD(SpriteBatch spriteBatch, Character character) { } diff --git a/Subsurface/Items/Components/Machines/Reactor.cs b/Subsurface/Items/Components/Machines/Reactor.cs index bd2260e39..cb7c5496d 100644 --- a/Subsurface/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Items/Components/Machines/Reactor.cs @@ -281,7 +281,7 @@ namespace Subsurface.Items.Components return true; } - public override void Draw(SpriteBatch spriteBatch) + public override void Draw(SpriteBatch spriteBatch, bool editing) { base.Draw(spriteBatch); diff --git a/Subsurface/Items/Components/Power/PowerContainer.cs b/Subsurface/Items/Components/Power/PowerContainer.cs index 6761c4128..ffde43589 100644 --- a/Subsurface/Items/Components/Power/PowerContainer.cs +++ b/Subsurface/Items/Components/Power/PowerContainer.cs @@ -173,7 +173,7 @@ namespace Subsurface.Items.Components voltage = 0.0f; } - public override void Draw(SpriteBatch spriteBatch) + public override void Draw(SpriteBatch spriteBatch, bool editing) { base.Draw(spriteBatch); diff --git a/Subsurface/Items/Components/Power/PowerTransfer.cs b/Subsurface/Items/Components/Power/PowerTransfer.cs index cc69e94dc..537f5abc0 100644 --- a/Subsurface/Items/Components/Power/PowerTransfer.cs +++ b/Subsurface/Items/Components/Power/PowerTransfer.cs @@ -53,11 +53,6 @@ namespace Subsurface.Items.Components "power", fullPower / Math.Max(fullLoad, 1.0f)); if (-pt.currPowerConsumption > pt.powerLoad * 2.0f) pt.item.Condition = 0.0f; } - else - { - - //p.Power = fullPower; - } } diff --git a/Subsurface/Items/Components/Power/Powered.cs b/Subsurface/Items/Components/Power/Powered.cs index 092e5b979..ada384bd8 100644 --- a/Subsurface/Items/Components/Power/Powered.cs +++ b/Subsurface/Items/Components/Power/Powered.cs @@ -61,7 +61,8 @@ namespace Subsurface.Items.Components public override void ReceiveSignal(string signal, Connection connection, Item sender, float power) { - if (connection.Name=="power_in") voltage = power; + if (currPowerConsumption == 0.0f) voltage = 0.0f; + if (connection.Name == "power_in" || connection.Name == "power") voltage = power; } public override void Update(float deltaTime, Camera cam) diff --git a/Subsurface/Items/Components/Rope.cs b/Subsurface/Items/Components/Rope.cs index e3f1c45bc..4147f1dc8 100644 --- a/Subsurface/Items/Components/Rope.cs +++ b/Subsurface/Items/Components/Rope.cs @@ -239,7 +239,7 @@ namespace Subsurface.Items.Components } } - public override void Draw(SpriteBatch spriteBatch) + public override void Draw(SpriteBatch spriteBatch, bool editing) { base.Draw(spriteBatch); diff --git a/Subsurface/Items/Components/Signal/Connection.cs b/Subsurface/Items/Components/Signal/Connection.cs index efd2536a4..2777872e4 100644 --- a/Subsurface/Items/Components/Signal/Connection.cs +++ b/Subsurface/Items/Components/Signal/Connection.cs @@ -339,29 +339,31 @@ namespace Subsurface.Items.Components int textX = (int)start.X; float connLength = 10.0f; - Color color = (wireEquipped) ? Color.Gray : Color.White; + float alpha = wireEquipped ? 0.5f : 1.0f; + + //Color color = (wireEquipped) ? wireItem.Color * 0.5f : wireItem.Color; if (Math.Abs(end.X-start.X) start.X) ? -1.0f : 1.0f; - wireCorner.Draw(spriteBatch, - new Vector2(start.X, end.Y), color, 0.0f, 1.0f, + wireCorner.Draw(spriteBatch, + new Vector2(start.X, end.Y), wireItem.Color * alpha, 0.0f, 1.0f, (end.X > start.X) ? SpriteEffects.None : SpriteEffects.FlipHorizontally); float wireStartX = start.X - wireCorner.size.X / 2 * dir; @@ -370,11 +372,11 @@ namespace Subsurface.Items.Components pos = new Vector2(Math.Min(wireStartX,wireEndX), end.Y - wireVertical.size.Y / 2); size = new Vector2(Math.Abs(wireStartX - wireEndX), wireHorizontal.size.Y); - wireHorizontal.DrawTiled(spriteBatch, pos, size, color); + wireHorizontal.DrawTiled(spriteBatch, pos, size, wireItem.Color * alpha); rect = new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y); if (!wireEquipped && rect.Contains(PlayerInput.MousePosition)) mouseOn = true; - connector.Draw(spriteBatch, end, color, -MathHelper.PiOver2*dir); + connector.Draw(spriteBatch, end, Color.White*alpha, -MathHelper.PiOver2 * dir); } if (draggingConnected == null && !wireEquipped) diff --git a/Subsurface/Items/Components/Signal/LightComponent.cs b/Subsurface/Items/Components/Signal/LightComponent.cs index 3feb0201b..1776d3ee4 100644 --- a/Subsurface/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Items/Components/Signal/LightComponent.cs @@ -1,13 +1,33 @@ -using Microsoft.Xna.Framework; +using FarseerPhysics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Subsurface.Lights; +using System; using System.Xml.Linq; namespace Subsurface.Items.Components { - class LightComponent : ItemComponent + class LightComponent : Powered { private Color lightColor; - private Sprite sprite; + //private Sprite sprite; + + LightSource light; + + float range; + + float lightBrightness; + + [HasDefaultValue(100.0f, true)] + public float Range + { + get { return range; } + set + { + range = MathHelper.Clamp(value, 0.0f, 2048.0f); + } + } [InGameEditable, HasDefaultValue("1.0,1.0,1.0,1.0", true)] public string LightColor @@ -19,27 +39,74 @@ namespace Subsurface.Items.Components } } + public override void Move(Vector2 amount) + { + light.Position += amount; + } + public LightComponent(Item item, XElement element) : base (item, element) { - foreach (XElement subElement in element.Elements()) - { - if (subElement.Name.ToString().ToLower() != "sprite") continue; - sprite = new Sprite(subElement); - break; - } + //foreach (XElement subElement in element.Elements()) + //{ + // if (subElement.Name.ToString().ToLower() != "sprite") continue; + // sprite = new Sprite(subElement); + // break; + //} + + light = new LightSource(item.Position, 100.0f, Color.White); + + isActive = true; //lightColor = new Color(ToolBox.GetAttributeVector4(element, "color", Vector4.One)); } - - public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) + + public override void Update(float deltaTime, Camera cam) { - if (!isActive || sprite==null) return; - sprite.Draw(spriteBatch, new Vector2(item.Position.X, -item.Position.Y), 0.0f, 1.0f, Microsoft.Xna.Framework.Graphics.SpriteEffects.None); + base.Update(deltaTime, cam); + + if (item.body != null) + { + light.Position = ConvertUnits.ToDisplayUnits(item.body.Position); + } + + if (powerConsumption == 0.0f) + { + voltage = 1.0f; + } + else + { + currPowerConsumption = powerConsumption; + } + + if (voltage < Rand.Range(0.0f, minVoltage)) + { + lightBrightness = 0.0f; + } + else + { + lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(voltage, 1.0f), 0.1f); + } + + light.Color = lightColor * lightBrightness; + + light.Range = range * (float)Math.Sqrt(lightBrightness); + + voltage = 0.0f; + } + + public override void Draw(SpriteBatch spriteBatch, bool editing) + { + if (!isActive) + { + light.Color = Color.Transparent; + } } public override void ReceiveSignal(string signal, Connection connection, Item sender, float power=0.0f) { + base.ReceiveSignal(signal, connection, sender, power); + switch (connection.Name) { case "toggle": diff --git a/Subsurface/Items/Components/Signal/Wire.cs b/Subsurface/Items/Components/Signal/Wire.cs index 5cb2bb011..aaa2245ef 100644 --- a/Subsurface/Items/Components/Signal/Wire.cs +++ b/Subsurface/Items/Components/Signal/Wire.cs @@ -20,7 +20,9 @@ namespace Subsurface.Items.Components Connection[] connections; private Vector2 newNodePos; - + + private static int? selectedNodeIndex; + public Wire(Item item, XElement element) : base(item, element) { @@ -34,14 +36,14 @@ namespace Subsurface.Items.Components connections = new Connection[2]; } - + public override void Move(Vector2 amount) { amount = FarseerPhysics.ConvertUnits.ToDisplayUnits(amount); - for (int i = 0; i nodeDistance*10) //{ @@ -170,14 +172,13 @@ namespace Subsurface.Items.Components public override bool Use(float deltaTime, Character character = null) { + if (character == Character.Controlled && character.SelectedConstruction != null) return false; + if (newNodePos!= Vector2.Zero && Nodes.Count>0 && Vector2.Distance(newNodePos, Nodes[Nodes.Count - 1]) > nodeDistance) { Nodes.Add(newNodePos); newNodePos = Vector2.Zero; } - - - return true; } @@ -213,6 +214,23 @@ namespace Subsurface.Items.Components } } + private Vector2 RoundNode(Vector2 position, Hull hull) + { + position.X = MathUtils.Round(position.X, nodeDistance); + if (hull == null) + { + position.Y = MathUtils.Round(position.Y, nodeDistance); + } + else + { + position.Y -= hull.Rect.Y - hull.Rect.Height; + position.Y = Math.Max(MathUtils.Round(position.Y, nodeDistance), heightFromFloor); + position.Y += hull.Rect.Y -hull.Rect.Height; + } + + return position; + } + private void CleanNodes() { for (int i = Nodes.Count - 2; i > 0; i--) @@ -246,7 +264,7 @@ namespace Subsurface.Items.Components } - public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) + public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, bool editing) { if (Nodes.Count == 0) return; @@ -257,15 +275,63 @@ namespace Subsurface.Items.Components for (int i = 1; i < Nodes.Count; i++) { - DrawSection(spriteBatch, Nodes[i], Nodes[i - 1], i, Color.White); + DrawSection(spriteBatch, Nodes[i], Nodes[i - 1], i, item.Color); } if (isActive && Vector2.Distance(newNodePos, Nodes[Nodes.Count - 1]) > nodeDistance) { - DrawSection(spriteBatch, Nodes[Nodes.Count - 1], newNodePos, Nodes.Count, Color.White * 0.5f); + DrawSection(spriteBatch, Nodes[Nodes.Count - 1], newNodePos, Nodes.Count, item.Color * 0.5f); //nodes.Add(newNodePos); } + if (!editing) return; + + for (int i = 1; i < Nodes.Count; i++) + { + GUI.DrawRectangle(spriteBatch, new Rectangle((int)Nodes[i].X - 3, (int)-Nodes[i].Y -3, 6, 6), Color.Red, true, 0.0f); + + if (Vector2.Distance(Game1.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), Nodes[i]) < 20.0f) + { + GUI.DrawRectangle(spriteBatch, new Rectangle((int)Nodes[i].X - 10, (int)-Nodes[i].Y - 10, 20, 20), Color.Red, false, 0.0f); + + if (selectedNodeIndex==null && selectedNodeIndex>0 && selectedNodeIndex0) { @@ -930,32 +953,6 @@ namespace Subsurface ObjectProperty.SaveProperties(this, element); - //var saveProperties = ObjectProperty.GetProperties(this); - //foreach (var property in saveProperties) - //{ - // object value = property.GetValue(); - // if (value == null) continue; - - // bool dontSave=false; - // foreach (var ini in property.Attributes.OfType()) - // { - // if (ini.defaultValue==value) - // { - // dontSave = true; - // break; - // } - // } - - // if (dontSave) continue; - - // element.Add(new XAttribute(property.Name.ToLower(), value)); - //} - - //if (tags.Count>0) - //{ - // element.Add(new XAttribute("tags",string.Join(", ",tags))); - //} - foreach (ItemComponent ic in components) { ic.Save(element); @@ -970,12 +967,22 @@ namespace Subsurface { string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0"); string[] rectValues = rectString.Split(','); + Rectangle rect = Rectangle.Empty; + if (rectValues.Length==4) + { + rect = new Rectangle( + int.Parse(rectValues[0]), + int.Parse(rectValues[1]), + int.Parse(rectValues[2]), + int.Parse(rectValues[3])); + } else + { + rect = new Rectangle( + int.Parse(rectValues[0]), + int.Parse(rectValues[1]), + 0, 0); + } - Rectangle rect = new Rectangle( - int.Parse(rectValues[0]), - int.Parse(rectValues[1]), - int.Parse(rectValues[2]), - int.Parse(rectValues[3])); string name = element.Attribute("name").Value; @@ -986,6 +993,12 @@ namespace Subsurface if (ip.Name != name) continue; + if (rect.Width==0 && rect.Height==0) + { + rect.Width = (int)ip.Size.X; + rect.Height = (int)ip.Size.Y; + } + Item item = new Item(rect, ip); item.ID = int.Parse(element.Attribute("ID").Value); diff --git a/Subsurface/Items/ItemPrefab.cs b/Subsurface/Items/ItemPrefab.cs index 6b81e7585..c06c83357 100644 --- a/Subsurface/Items/ItemPrefab.cs +++ b/Subsurface/Items/ItemPrefab.cs @@ -11,7 +11,7 @@ namespace Subsurface { class ItemPrefab : MapEntityPrefab { - static string contentFolder = "Content/Items/"; + //static string contentFolder = "Content/Items/"; string configFile; @@ -55,6 +55,11 @@ namespace Subsurface get { return offsetOnSelected; } } + public Vector2 Size + { + get { return size; } + } + public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam) { Vector2 position = Submarine.MouseToWorldGrid(cam); diff --git a/Subsurface/Map/Lights/Light.cs b/Subsurface/Map/Lights/Light.cs new file mode 100644 index 000000000..b2924d1c4 --- /dev/null +++ b/Subsurface/Map/Lights/Light.cs @@ -0,0 +1,61 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Subsurface.Lights +{ + class LightSource + { + + private static Texture2D lightTexture; + + private Color color; + + private float range; + + private Texture2D texture; + + public Vector2 Position; + + public Color Color + { + get { return color; } + set { color = value; } + } + + public float Range + { + get { return range; } + set + { + range = MathHelper.Clamp(value, 0.0f, 2048.0f); + } + } + + public LightSource(Vector2 position, float range, Color color) + { + Position = position; + this.range = range; + this.color = color; + + if (lightTexture == null) + { + lightTexture = Game1.TextureLoader.FromFile("Content/Lights/light.png"); + } + + texture = lightTexture; + + Game1.LightManager.AddLight(this); + } + + public void Draw(SpriteBatch spriteBatch) + { + Vector2 center = new Vector2(lightTexture.Width / 2, lightTexture.Height / 2); + float scale = range / ((float)lightTexture.Width / 2.0f); + spriteBatch.Draw(lightTexture, new Vector2(Position.X, -Position.Y), null, color, 0, center, scale, SpriteEffects.None, 1); + } + } +} diff --git a/Subsurface/Map/Lights/LightManager.cs b/Subsurface/Map/Lights/LightManager.cs index 749ce356e..b8eb9c6a7 100644 --- a/Subsurface/Map/Lights/LightManager.cs +++ b/Subsurface/Map/Lights/LightManager.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using System.Collections.Generic; namespace Subsurface.Lights { @@ -7,16 +8,126 @@ namespace Subsurface.Lights { public static Vector2 ViewPos; - public static bool FowEnabled = true; + public Color AmbientLight; - public static void DrawFow(GraphicsDevice graphics, Camera cam) + RenderTarget2D lightMap; + + private static Texture2D alphaClearTexture; + + private List lights; + + public bool FowEnabled = true; + + public bool LightingEnabled = true; + + public RenderTarget2D LightMap + { + get { return lightMap; } + } + + public LightManager(GraphicsDevice graphics) + { + lights = new List(); + + AmbientLight = new Color(80, 80, 80, 255); + + var pp = graphics.PresentationParameters; + + lightMap = new RenderTarget2D(graphics, Game1.GraphicsWidth, Game1.GraphicsHeight, false, + pp.BackBufferFormat, pp.DepthStencilFormat, pp.MultiSampleCount, + RenderTargetUsage.DiscardContents); + + + if (alphaClearTexture==null) + { + alphaClearTexture = Game1.TextureLoader.FromFile("Content/Lights/alphaOne.png"); + } + } + + public void AddLight(LightSource light) + { + lights.Add(light); + } + + public void RemoveLight(LightSource light) + { + lights.Remove(light); + } + + public void DrawFow(GraphicsDevice graphics, Camera cam, Vector2 pos) { if (!FowEnabled) return; foreach (ConvexHull convexHull in ConvexHull.list) { - convexHull.DrawShadows(graphics, cam, ViewPos); + convexHull.DrawShadows(graphics, cam, pos); } } + + public void DrawLightmap(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam) + { + graphics.SetRenderTarget(lightMap); + + //clear to some small ambient light + graphics.Clear(AmbientLight); + + foreach (LightSource light in lights) + { + //clear alpha to 1 + ClearAlphaToOne(graphics, spriteBatch); + + //draw all shadows + //write only to the alpha channel, which sets alpha to 0 + //graphics.RasterizerState = RasterizerState.CullNone; + //graphics.BlendState = CustomBlendStates.WriteToAlpha; + + //foreach (ConvexHull ch in ConvexHull.list) + //{ + // //draw shadow + // ch.DrawShadows(graphics, cam, light.Position); + //} + + //draw the light shape + //where Alpha is 0, nothing will be written + spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.MultiplyWithAlpha, null, null, null, null, cam.Transform); + light.Draw(spriteBatch); + spriteBatch.End(); + } + //clear alpha, to avoid messing stuff up later + ClearAlphaToOne(graphics, spriteBatch); + graphics.SetRenderTarget(null); + } + + private void ClearAlphaToOne(GraphicsDevice graphics, SpriteBatch spriteBatch) + { + spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.WriteToAlpha); + spriteBatch.Draw(alphaClearTexture, new Rectangle(0, 0,graphics.Viewport.Width, graphics.Viewport.Height), Color.White); + spriteBatch.End(); + } + } + + + class CustomBlendStates + { + static CustomBlendStates() + { + Multiplicative = new BlendState(); + Multiplicative.ColorSourceBlend = Multiplicative.AlphaSourceBlend = Blend.Zero; + Multiplicative.ColorDestinationBlend = Multiplicative.AlphaDestinationBlend = Blend.SourceColor; + Multiplicative.ColorBlendFunction = Multiplicative.AlphaBlendFunction = BlendFunction.Add; + + WriteToAlpha = new BlendState(); + WriteToAlpha.ColorWriteChannels = ColorWriteChannels.Alpha; + + MultiplyWithAlpha = new BlendState(); + MultiplyWithAlpha.ColorDestinationBlend = MultiplyWithAlpha.AlphaDestinationBlend = Blend.One; + MultiplyWithAlpha.ColorSourceBlend = MultiplyWithAlpha.AlphaSourceBlend = Blend.DestinationAlpha; + } + public static BlendState Multiplicative { get; private set; } + public static BlendState WriteToAlpha { get; private set; } + public static BlendState MultiplyWithAlpha { get; private set; } + + + } } diff --git a/Subsurface/Map/Map.cs b/Subsurface/Map/Map.cs index e48c16ab4..fb91ecd1f 100644 --- a/Subsurface/Map/Map.cs +++ b/Subsurface/Map/Map.cs @@ -22,9 +22,9 @@ namespace Subsurface private int seed; private int size; - private Texture2D iceTexture; - private Texture2D iceCraters; - private Texture2D iceCrack; + private static Texture2D iceTexture; + private static Texture2D iceCraters; + private static Texture2D iceCrack; private Location currentLocation; private Location selectedLocation; @@ -61,9 +61,9 @@ namespace Subsurface connections = new List(); - iceTexture = Game1.TextureLoader.FromFile("Content/Map/iceSurface.png"); - iceCraters = Game1.TextureLoader.FromFile("Content/Map/iceCraters.png"); - iceCrack = Game1.TextureLoader.FromFile("Content/Map/iceCrack.png"); + if (iceTexture==null) iceTexture = Game1.TextureLoader.FromFile("Content/Map/iceSurface.png"); + if (iceCraters == null) iceCraters = Game1.TextureLoader.FromFile("Content/Map/iceCraters.png"); + if (iceCrack == null) iceCrack = Game1.TextureLoader.FromFile("Content/Map/iceCrack.png"); Rand.SetSyncedSeed(this.seed); @@ -151,14 +151,16 @@ namespace Subsurface for (int i = connections.Count - 1; i >= 0; i--) { + i = Math.Min(i, connections.Count - 1); + LocationConnection connection = connections[i]; - for (int n = i - 1; n >= 0; n--) + for (int n = Math.Min(i - 1,connections.Count - 1); n >= 0; n--) { if (connection.Locations.Contains(connections[n].Locations[0]) && connection.Locations.Contains(connections[n].Locations[1])) { - connections.RemoveAt(i); + connections.RemoveAt(n); } } } diff --git a/Subsurface/Map/MapEntity.cs b/Subsurface/Map/MapEntity.cs index 33e751983..8ff2201a3 100644 --- a/Subsurface/Map/MapEntity.cs +++ b/Subsurface/Map/MapEntity.cs @@ -37,6 +37,21 @@ namespace Subsurface protected bool isSelected; + private static bool disableSelect; + public static bool DisableSelect + { + get { return disableSelect; } + set { + disableSelect = value; + if (disableSelect==true) + { + startMovingPos = Vector2.Zero; + selectionSize = Vector2.Zero; + selectionPos = Vector2.Zero; + } + } + } + public bool MoveWithLevel { get; @@ -174,6 +189,12 @@ namespace Subsurface { if (GUIComponent.MouseOn != null) return; + if (DisableSelect) + { + DisableSelect = false; + return; + } + foreach (MapEntity e in mapEntityList) { e.isHighlighted = false; @@ -189,8 +210,7 @@ namespace Subsurface if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.Delete)) { - foreach (MapEntity e in selectedList) - e.Remove(); + foreach (MapEntity e in selectedList) e.Remove(); selectedList.Clear(); } @@ -209,7 +229,7 @@ namespace Subsurface e.isSelected = false; } - if (highLightedEntity!=null) + if (highLightedEntity != null) highLightedEntity.isHighlighted = true; foreach (MapEntity e in selectedList) @@ -269,7 +289,6 @@ namespace Subsurface foreach (MapEntity e2 in selectedList) { - Debug.WriteLine(e.ID+", "+e2.ID); if (e.ID == e2.ID) alreadySelected = true; } @@ -359,6 +378,18 @@ namespace Subsurface editingHUD = null; } } + + public static void SelectEntity(MapEntity entity) + { + foreach (MapEntity e in selectedList) + { + e.isSelected = false; + } + selectedList.Clear(); + + entity.isSelected = true; + selectedList.Add(entity); + } public virtual void DrawEditing(SpriteBatch spriteBatch, Camera cam) {} diff --git a/Subsurface/Map/MapEntityPrefab.cs b/Subsurface/Map/MapEntityPrefab.cs index eda03ebec..08e1f8492 100644 --- a/Subsurface/Map/MapEntityPrefab.cs +++ b/Subsurface/Map/MapEntityPrefab.cs @@ -25,9 +25,7 @@ namespace Subsurface //is it possible to stretch the entity horizontally/vertically protected bool resizeHorizontal; protected bool resizeVertical; - - - + //which prefab has been selected for placing protected static MapEntityPrefab selected; @@ -46,7 +44,15 @@ namespace Subsurface get { return isLinkable; } } + public bool ResizeHorizontal + { + get { return resizeHorizontal; } + } + public bool ResizeVertical + { + get { return resizeVertical; } + } public static void Init() { diff --git a/Subsurface/Map/Submarine.cs b/Subsurface/Map/Submarine.cs index ca9de2c6d..627b6052e 100644 --- a/Subsurface/Map/Submarine.cs +++ b/Subsurface/Map/Submarine.cs @@ -825,6 +825,7 @@ namespace Subsurface foreach (Item item in Item.itemList) { + System.Diagnostics.Debug.WriteLine(item.ID); foreach (ItemComponent ic in item.components) { ic.OnMapLoaded(); diff --git a/Subsurface/Networking/GameClient.cs b/Subsurface/Networking/GameClient.cs index b31dfcd64..718139b60 100644 --- a/Subsurface/Networking/GameClient.cs +++ b/Subsurface/Networking/GameClient.cs @@ -74,8 +74,8 @@ namespace Subsurface.Networking // Create new instance of configs. Parameter is "application Id". It has to be same on client and server. NetPeerConfiguration Config = new NetPeerConfiguration("subsurface"); - //Config.SimulatedLoss = 0.2f; - //Config.SimulatedMinimumLatency = 0.25f; + Config.SimulatedLoss = 0.2f; + Config.SimulatedMinimumLatency = 0.25f; // Create new client, with previously created configs client = new NetClient(Config); @@ -541,8 +541,8 @@ namespace Subsurface.Networking break; } - int byteCount = Rand.Int(100); - for (int i = 0; i + /// sends some random data to the clients + /// use for debugging purposes + /// + public void SendRandomData() + { + NetOutgoingMessage msg = Server.CreateMessage(); + switch (Rand.Int(5)) + { + case 0: + msg.Write((byte)PacketTypes.NetworkEvent); + msg.Write((byte)Enum.GetNames(typeof(NetworkEventType)).Length); + msg.Write(Rand.Int(MapEntity.mapEntityList.Count)); + break; + case 1: + msg.Write((byte)PacketTypes.NetworkEvent); + msg.Write((byte)NetworkEventType.UpdateComponent); + msg.Write((int)Item.itemList[Rand.Int(Item.itemList.Count)].ID); + msg.Write(Rand.Int(8)); + break; + case 2: + msg.Write((byte)Enum.GetNames(typeof(PacketTypes)).Length); + break; + case 3: + msg.Write((byte)PacketTypes.UpdateNetLobby); + break; + } + + int bitCount = Rand.Int(100); + for (int i = 0; i < bitCount; i++) + { + msg.Write((Rand.Int(2) == 0) ? true : false); + } + SendMessage(msg, (Rand.Int(2) == 0) ? NetDeliveryMethod.ReliableOrdered : NetDeliveryMethod.Unreliable, null); + + } + public override void Disconnect() { Server.Shutdown(""); diff --git a/Subsurface/Screens/EditMapScreen.cs b/Subsurface/Screens/EditMapScreen.cs index e0f4c38b3..d6fa34720 100644 --- a/Subsurface/Screens/EditMapScreen.cs +++ b/Subsurface/Screens/EditMapScreen.cs @@ -255,16 +255,28 @@ namespace Subsurface if (characterMode) { - if (dummyCharacter != null && dummyCharacter.SelectedConstruction != null) + if (dummyCharacter != null) { - if (dummyCharacter.SelectedConstruction == dummyCharacter.ClosestItem) + foreach (Item item in dummyCharacter.SelectedItems) { - dummyCharacter.SelectedConstruction.DrawHUD(spriteBatch, dummyCharacter); + if (item == null) continue; + item.SetTransform(dummyCharacter.SimPosition, 0.0f); + + item.Update(cam, (float)deltaTime); } - else + + if (dummyCharacter.SelectedConstruction != null) { - dummyCharacter.SelectedConstruction = null; + if (dummyCharacter.SelectedConstruction == dummyCharacter.ClosestItem) + { + dummyCharacter.SelectedConstruction.DrawHUD(spriteBatch, dummyCharacter); + } + else + { + dummyCharacter.SelectedConstruction = null; + } } + } if (PlayerInput.GetMouseState.LeftButton != ButtonState.Pressed) diff --git a/Subsurface/Screens/GameScreen.cs b/Subsurface/Screens/GameScreen.cs index 5888156fe..6b6b58c43 100644 --- a/Subsurface/Screens/GameScreen.cs +++ b/Subsurface/Screens/GameScreen.cs @@ -147,6 +147,14 @@ namespace Subsurface public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch) { + + + Game1.LightManager.DrawLightmap(graphics, spriteBatch, cam); + + + + + //---------------------------------------------------------------------------------------- //1. draw the characters and the parts of the map that are behind them //---------------------------------------------------------------------------------------- @@ -282,7 +290,17 @@ namespace Subsurface if (Game1.Level != null) Game1.Level.Render(graphics, cam); - LightManager.DrawFow(graphics,cam); + if (Game1.LightManager.LightingEnabled) + { + //multiply scene with lightmap + spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Multiplicative); + spriteBatch.Draw(Game1.LightManager.LightMap, Vector2.Zero, Color.White); + spriteBatch.End(); + } + + + Game1.LightManager.DrawFow(graphics,cam,LightManager.ViewPos); + } } } diff --git a/Subsurface/Screens/NetLobbyScreen.cs b/Subsurface/Screens/NetLobbyScreen.cs index 6acb63cf7..c18d87205 100644 --- a/Subsurface/Screens/NetLobbyScreen.cs +++ b/Subsurface/Screens/NetLobbyScreen.cs @@ -148,7 +148,7 @@ namespace Subsurface public override void Select() { - Lights.LightManager.FowEnabled = false; + Game1.LightManager.FowEnabled = false; infoFrame.ClearChildren(); @@ -215,21 +215,23 @@ namespace Subsurface seedBox.Enabled = (Game1.Server != null); LevelSeed = ToolBox.RandomSeed(8); - var serverName = new GUITextBlock(new Rectangle(0, 0, 200, 30), - "Server: ", GUI.style, Alignment.Left, Alignment.TopLeft, infoFrame); + var serverName = new GUITextBox(new Rectangle(0, 0, 200, 20), null, null, Alignment.TopLeft, Alignment.TopLeft, GUI.style, infoFrame); serverName.TextGetter = GetServerName; + serverName.Enabled = Game1.Server != null; + serverName.OnTextChanged = ChangeServerName; + ServerName = "Server"; var serverMessage = new GUITextBox(new Rectangle(0, 30, 360, 70),null,null, Alignment.TopLeft, Alignment.TopLeft, GUI.style, infoFrame); - serverMessage.Enabled = false; + serverMessage.Enabled = Game1.Server != null; serverMessage.Wrap = true; + serverMessage.TextGetter = GetServerMessage; + serverMessage.OnTextChanged = UpdateServerMessage; if (IsServer && Game1.Server != null) { GUIButton startButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Start", Alignment.TopRight, GUI.style, infoFrame); startButton.OnClicked = Game1.Server.StartGame; - - serverMessage.Enabled = true; - + //mapList.OnSelected = new GUIListBox.OnSelectedHandler(Game1.server.UpdateNetLobby); modeList.OnSelected = Game1.Server.UpdateNetLobby; durationBar.OnMoved = Game1.Server.UpdateNetLobby; @@ -301,6 +303,24 @@ namespace Subsurface return true; } + public bool ChangeServerName(GUITextBox textBox, string text) + { + if (Game1.Server == null) return false; + ServerName = text; + Game1.Server.UpdateNetLobby(null); + + return true; + } + + public bool UpdateServerMessage(GUITextBox textBox, string text) + { + if (Game1.Server == null) return false; + ServerMessage = text; + Game1.Server.UpdateNetLobby(null); + + return true; + } + public void AddPlayer(Client client) { @@ -539,6 +559,7 @@ namespace Subsurface } msg.Write(ServerName); + msg.Write(ServerMessage); msg.Write(modeList.SelectedIndex-1); msg.Write(durationBar.BarScroll); @@ -558,50 +579,80 @@ namespace Subsurface public void ReadData(NetIncomingMessage msg) { - string mapName = msg.ReadString(); - string md5Hash = msg.ReadString(); + string mapName="", md5Hash=""; + + int modeIndex = 0; + float durationScroll = 0.0f; + string levelSeed = ""; + + try + { + mapName = msg.ReadString(); + md5Hash = msg.ReadString(); + + ServerName = msg.ReadString(); + ServerMessage = msg.ReadString(); + + modeIndex = msg.ReadInt32(); + + durationScroll = msg.ReadFloat(); + + levelSeed = msg.ReadString(); + } + + catch + { + return; + } TrySelectMap(mapName, md5Hash); - ServerName = msg.ReadString(); + modeList.Select(modeIndex); - //mapList.Select(msg.ReadInt32()); - modeList.Select(msg.ReadInt32()); + durationBar.BarScroll = durationScroll; - durationBar.BarScroll = msg.ReadFloat(); + LevelSeed = levelSeed; - LevelSeed = msg.ReadString(); - - int playerCount = msg.ReadInt32(); - for (int i = 0; i < playerCount; i++) + try { - int clientID = msg.ReadInt32(); - string jobName = msg.ReadString(); - - Client client = null; - GUITextBlock textBlock = null; - foreach (GUIComponent child in playerList.children) + int playerCount = msg.ReadInt32(); + + for (int i = 0; i < playerCount; i++) { - Client tempClient = child.UserData as Client; - if (tempClient == null || tempClient.ID != clientID) continue; - - client = tempClient; - textBlock = child as GUITextBlock; - break; - } - if (client == null) continue; + int clientID = msg.ReadInt32(); + string jobName = msg.ReadString(); - client.assignedJob = JobPrefab.List.Find(jp => jp.Name == jobName); + Client client = null; + GUITextBlock textBlock = null; + foreach (GUIComponent child in playerList.children) + { + Client tempClient = child.UserData as Client; + if (tempClient == null || tempClient.ID != clientID) continue; + + client = tempClient; + textBlock = child as GUITextBlock; + break; + } + if (client == null) continue; + + client.assignedJob = JobPrefab.List.Find(jp => jp.Name == jobName); - textBlock.Text = client.name + ((client.assignedJob==null) ? "" : " (" + client.assignedJob.Name + ")"); + textBlock.Text = client.name + ((client.assignedJob==null) ? "" : " (" + client.assignedJob.Name + ")"); - if (clientID == Game1.Client.ID) - { - Game1.Client.CharacterInfo.Job = new Job(client.assignedJob); - Game1.Client.CharacterInfo.Name = client.name; - UpdatePreviewPlayer(Game1.Client.CharacterInfo); + if (clientID == Game1.Client.ID) + { + Game1.Client.CharacterInfo.Job = new Job(client.assignedJob); + Game1.Client.CharacterInfo.Name = client.name; + UpdatePreviewPlayer(Game1.Client.CharacterInfo); + } } } + + catch + { + return; + } + } } diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 61944b51d..8c8b60537 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -68,6 +68,7 @@ + @@ -272,6 +273,13 @@ PreserveNewest + + PreserveNewest + + + Designer + PreserveNewest + PreserveNewest Designer @@ -380,6 +388,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -679,6 +693,10 @@ PreserveNewest + + + PreserveNewest + PreserveNewest @@ -763,6 +781,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Subsurface/Subsurface.csproj.user b/Subsurface/Subsurface.csproj.user index 505c3a0bf..693505ea4 100644 --- a/Subsurface/Subsurface.csproj.user +++ b/Subsurface/Subsurface.csproj.user @@ -9,6 +9,6 @@ en-US false - ProjectFiles + ShowAllFiles \ No newline at end of file diff --git a/Subsurface/Utils/Rand.cs b/Subsurface/Utils/Rand.cs index eefd649bc..a564feb9f 100644 --- a/Subsurface/Utils/Rand.cs +++ b/Subsurface/Utils/Rand.cs @@ -18,38 +18,19 @@ namespace Subsurface public static float Range(float minimum, float maximum, bool local = true) { - if (local) - { - return (float)localRandom.NextDouble() * (maximum - minimum) + minimum; - } - else - { - return (float)syncedRandom.NextDouble() * (maximum - minimum) + minimum; - } + return (float)(local ? localRandom : syncedRandom).NextDouble() * (maximum - minimum) + minimum; + } public static int Range(int minimum, int maximum, bool local = true) { - if (local) - { - return localRandom.Next(maximum - minimum) + minimum; - } - else - { - return syncedRandom.Next(maximum - minimum) + minimum; - } + return (local ? localRandom : syncedRandom).Next(maximum - minimum) + minimum; + } public static int Int(int max = int.MaxValue, bool local = true) { - if (local) - { - return localRandom.Next(max); - } - else - { - return syncedRandom.Next(max); - } + return (local ? localRandom : syncedRandom).Next(max); } public static Vector2 Vector(float length = 1.0f, bool local = true) diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index bc70bd488..fb768adb0 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ