diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index b3c8354ea..9c3245dc4 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -133,7 +133,11 @@ - + + + + + diff --git a/Subsurface/Content/Items/Electricity/signalitems.xml b/Subsurface/Content/Items/Electricity/signalitems.xml index c9f705ebc..a559427d4 100644 --- a/Subsurface/Content/Items/Electricity/signalitems.xml +++ b/Subsurface/Content/Items/Electricity/signalitems.xml @@ -295,7 +295,7 @@ - + diff --git a/Subsurface/Content/Lights/lightcone.png b/Subsurface/Content/Lights/lightcone.png new file mode 100644 index 000000000..45ebc2640 Binary files /dev/null and b/Subsurface/Content/Lights/lightcone.png differ diff --git a/Subsurface/Source/Items/Components/Holdable/Propulsion.cs b/Subsurface/Source/Items/Components/Holdable/Propulsion.cs index f3a6e285d..eb63e15d4 100644 --- a/Subsurface/Source/Items/Components/Holdable/Propulsion.cs +++ b/Subsurface/Source/Items/Components/Holdable/Propulsion.cs @@ -11,6 +11,8 @@ namespace Barotrauma.Items.Components private string particles; + private float useState; + private ParticlePrefab.DrawTargetType usableIn; [HasDefaultValue(0.0f, false)] @@ -50,6 +52,10 @@ namespace Barotrauma.Items.Components if (character == null) return false; if (!character.IsKeyDown(InputType.Aim) || character.Stun>0.0f) return false; + IsActive = true; + useState = 0.1f; + + if (character.AnimController.InWater) { if (usableIn == ParticlePrefab.DrawTargetType.Air) return true; @@ -91,12 +97,13 @@ namespace Barotrauma.Items.Components return true; } - - public override void Draw(SpriteBatch spriteBatch, bool editing = false) + + public override void Update(float deltaTime, Camera cam) { - IsActive = false; + useState -= deltaTime; + + if (useState <= 0.0f) IsActive = false; } - - + } } diff --git a/Subsurface/Source/Items/Components/Signal/LightComponent.cs b/Subsurface/Source/Items/Components/Signal/LightComponent.cs index 57b9e5958..fda6b782f 100644 --- a/Subsurface/Source/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/LightComponent.cs @@ -18,6 +18,8 @@ namespace Barotrauma.Items.Components private float flicker; + private bool castShadows; + [Editable, HasDefaultValue(100.0f, true)] public float Range { @@ -28,6 +30,17 @@ namespace Barotrauma.Items.Components } } + [Editable, HasDefaultValue(true, true)] + public bool CastShadows + { + get { return castShadows; } + set + { + castShadows = value; + if (light != null) light.CastShadows = value; + } + } + [Editable, HasDefaultValue(false, true)] public bool IsOn { @@ -87,17 +100,20 @@ namespace Barotrauma.Items.Components public LightComponent(Item item, XElement element) : base (item, element) { - light = new LightSource(item.Position, 100.0f, Color.White, item.CurrentHull == null ? null : item.CurrentHull.Submarine); + light = new LightSource(element); + light.Submarine = item.CurrentHull == null ? null : item.CurrentHull.Submarine; + light.Position = item.Position; + light.CastShadows = castShadows; IsActive = true; - foreach (XElement subElement in element.Elements()) - { - if (subElement.Name.ToString().ToLowerInvariant() != "sprite") continue; - light.LightSprite = new Sprite(subElement); - light.LightSprite.Origin = light.LightSprite.size / 2.0f; - break; - } + //foreach (XElement subElement in element.Elements()) + //{ + // if (subElement.Name.ToString().ToLowerInvariant() != "sprite") continue; + + // light.LightSprite = new Sprite(subElement); + // break; + //} } public override void Update(float deltaTime, Camera cam) @@ -115,6 +131,7 @@ namespace Barotrauma.Items.Components if (item.body != null) { light.Position = item.Position; + light.Rotation = item.body.Dir > 0.0f ? item.body.Rotation : item.body.Rotation - MathHelper.Pi; if (!item.body.Enabled) { @@ -150,9 +167,9 @@ namespace Barotrauma.Items.Components public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, bool editing = false) { - if (light.LightSprite != null && (item.body==null || item.body.Enabled)) + if (light.LightSprite != null && (item.body == null || item.body.Enabled)) { - light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, 0.0f, 1.0f, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, item.Sprite.Depth-0.0001f); + light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, 0.0f, 1.0f, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, item.Sprite.Depth - 0.0001f); } } diff --git a/Subsurface/Source/Items/ItemPrefab.cs b/Subsurface/Source/Items/ItemPrefab.cs index 75738453e..e75d2e392 100644 --- a/Subsurface/Source/Items/ItemPrefab.cs +++ b/Subsurface/Source/Items/ItemPrefab.cs @@ -229,17 +229,15 @@ namespace Barotrauma ImpactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 0.0f); - string categoriesStr = ToolBox.GetAttributeString(element, "category", "Misc"); - string[] categories = categoriesStr.Split(','); + MapEntityCategory category; - for (int i = 0; i < categories.Length; i++) + if (!Enum.TryParse(ToolBox.GetAttributeString(element, "category", "Misc"), true, out category)) { - MapEntityCategory category; - if (Enum.TryParse(ToolBox.GetAttributeString(element, "category", "Misc"), out category)) - { - Category = i == 0 ? category : Category | category; - } + category = MapEntityCategory.Misc; } + + Category = category; + string spriteColorStr = ToolBox.GetAttributeString(element, "spritecolor", "1.0,1.0,1.0,1.0"); SpriteColor = new Color(ToolBox.ParseToVector4(spriteColorStr)); diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index 433daa49b..0f39b9b32 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -64,6 +64,12 @@ namespace Barotrauma.Lights private Rectangle boundingBox; + public Entity ParentEntity + { + get { return parentEntity; } + + } + public bool Enabled { get; @@ -302,9 +308,13 @@ namespace Barotrauma.Lights { if (!Enabled) return; + Vector2 lightSourcePos = light.Position; + + if (light.Submarine==null && parentEntity != null && parentEntity.Submarine != null) lightSourcePos -= parentEntity.Submarine.Position; + CachedShadow cachedShadow = null; - if (cachedShadows.TryGetValue(light, out cachedShadow) && - (light.Position == cachedShadow.LightPos || Vector2.DistanceSquared(light.Position, cachedShadow.LightPos) < 1.0f)) + if (cachedShadows.TryGetValue(light, out cachedShadow) && + (lightSourcePos == cachedShadow.LightPos || Vector2.DistanceSquared(lightSourcePos, cachedShadow.LightPos) < 1.0f)) { } @@ -315,17 +325,17 @@ namespace Barotrauma.Lights // lightPos = light.Position; //} - CalculateShadowVertices(light.Position, los); + CalculateShadowVertices(lightSourcePos, los); if (cachedShadow != null) { - cachedShadow.LightPos = light.Position; + cachedShadow.LightPos = lightSourcePos; cachedShadow.ShadowBuffer.SetData(shadowVertices, 0, shadowVertices.Length); cachedShadow.ShadowVertexCount = shadowVertexCount; } else { - cachedShadow = new CachedShadow(shadowVertices, penumbraVertices, light.Position, shadowVertexCount, 0); + cachedShadow = new CachedShadow(shadowVertices, penumbraVertices, lightSourcePos, shadowVertexCount, 0); RemoveCachedShadow(light); cachedShadows.Add(light, cachedShadow); } diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index d352300b7..994ecb146 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework.Graphics; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; namespace Barotrauma.Lights { @@ -122,7 +123,7 @@ namespace Barotrauma.Lights foreach (LightSource light in lights) { - if (light.hullsInRange.Count == 0 || light.Color.A < 0.01f || light.Range < 1.0f) continue; + if (!light.hullsInRange.Any() || light.Color.A < 0.01f || light.Range < 1.0f) continue; if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; //clear alpha to 1 @@ -135,7 +136,7 @@ namespace Barotrauma.Lights foreach (ConvexHull ch in light.hullsInRange) { - if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, ch.BoundingBox)) continue; + //if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, ch.BoundingBox)) continue; //draw shadow ch.DrawShadows(graphics, cam, light, shadowTransform, false); } @@ -152,7 +153,7 @@ namespace Barotrauma.Lights foreach (LightSource light in lights) { - if (light.hullsInRange.Count > 0 || light.Color.A < 0.01f) continue; + if (light.hullsInRange.Any() || light.Color.A < 0.01f) continue; //if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; light.Draw(spriteBatch); @@ -163,10 +164,6 @@ namespace Barotrauma.Lights //clear alpha, to avoid messing stuff up later ClearAlphaToOne(graphics, spriteBatch); graphics.SetRenderTarget(null); - - if (!ObstructVision) return; - - } public void UpdateObstructVision(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, Vector2 lookAtPosition) diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index c1b79f52d..5460e51a4 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -22,8 +22,12 @@ namespace Barotrauma.Lights public Sprite LightSprite; + private Sprite overrideLightTexture; + public Entity Submarine; + public bool CastShadows; + //what was the range of the light when HullsInRange were last updated private float prevHullUpdateRange; @@ -45,6 +49,12 @@ namespace Barotrauma.Lights } } + public float Rotation + { + get; + set; + } + public Vector2 WorldPosition { get { return (Submarine == null) ? position : position + Submarine.Position; } @@ -84,17 +94,24 @@ namespace Barotrauma.Lights } public LightSource (XElement element) - :this(Vector2.Zero, 100.0f, Color.White, null) + : this(Vector2.Zero, 100.0f, Color.White, null) { float range = ToolBox.GetAttributeFloat(element, "range", 100.0f); Color color = new Color(ToolBox.GetAttributeVector4(element, "color", Vector4.One)); + CastShadows = ToolBox.GetAttributeBool(element, "castshadows", true); + foreach (XElement subElement in element.Elements()) { - if (subElement.Name.ToString().ToLowerInvariant() != "sprite") continue; - - LightSprite = new Sprite(subElement); - LightSprite.Origin = LightSprite.size / 2.0f; + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "sprite": + LightSprite = new Sprite(subElement); + break; + case "lighttexture": + overrideLightTexture = new Sprite(subElement); + break; + } } } @@ -108,6 +125,8 @@ namespace Barotrauma.Lights this.range = range; this.color = color; + CastShadows = true; + texture = LightTexture; GameMain.LightManager.AddLight(this); @@ -115,12 +134,25 @@ namespace Barotrauma.Lights public void UpdateHullsInRange() { + if (!CastShadows) return; + hullsInRange.Clear(); if (range < 1.0f || color.A < 0.01f) return; foreach (ConvexHull ch in ConvexHull.list) { - if (MathUtils.CircleIntersectsRectangle(position, range, ch.BoundingBox)) hullsInRange.Add(ch); + if (Submarine == null && ch.ParentEntity.Submarine != null) + { + if (MathUtils.CircleIntersectsRectangle(position - ch.ParentEntity.Submarine.Position, range, ch.BoundingBox)) + { + hullsInRange.Add(ch); + } + } + else if (MathUtils.CircleIntersectsRectangle(position, range, ch.BoundingBox)) + { + hullsInRange.Add(ch); + } + } } @@ -128,15 +160,25 @@ namespace Barotrauma.Lights { if (range > 1.0f) { - Vector2 center = new Vector2(LightTexture.Width / 2, LightTexture.Height / 2); - float scale = range / (lightTexture.Width / 2.0f); + if (overrideLightTexture == null) + { + Vector2 center = new Vector2(LightTexture.Width / 2, LightTexture.Height / 2); + float scale = range / (lightTexture.Width / 2.0f); - spriteBatch.Draw(lightTexture, new Vector2(WorldPosition.X, -WorldPosition.Y), null, color, 0, center, scale, SpriteEffects.None, 1); + spriteBatch.Draw(lightTexture, new Vector2(WorldPosition.X, -WorldPosition.Y), null, color, 0, center, scale, SpriteEffects.None, 1); + } + else + { + overrideLightTexture.Draw(spriteBatch, + new Vector2(WorldPosition.X, -WorldPosition.Y), Color, + overrideLightTexture.Origin, -Rotation, + new Vector2(overrideLightTexture.size.X/overrideLightTexture.SourceRect.Width, overrideLightTexture.size.Y/overrideLightTexture.SourceRect.Height)); + } } if (LightSprite != null) { - LightSprite.Draw(spriteBatch, new Vector2(WorldPosition.X, -WorldPosition.Y), Color); + LightSprite.Draw(spriteBatch, new Vector2(WorldPosition.X, -WorldPosition.Y), Color, LightSprite.Origin); } }