diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 6d0b466df..1dfda18d7 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -496,6 +496,7 @@ PreserveNewest + PreserveNewest Designer @@ -803,6 +804,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -1105,6 +1109,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Subsurface/Content/Content.mgcb b/Subsurface/Content/Content.mgcb index e7b71d44b..3b1a5e869 100644 --- a/Subsurface/Content/Content.mgcb +++ b/Subsurface/Content/Content.mgcb @@ -43,3 +43,9 @@ /processorParam:DebugMode=Auto /build:blurshader.fx +#begin damageshader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:damageshader.fx + diff --git a/Subsurface/Content/Map/walldamage.png b/Subsurface/Content/Map/walldamage.png new file mode 100644 index 000000000..4938b9a8f Binary files /dev/null and b/Subsurface/Content/Map/walldamage.png differ diff --git a/Subsurface/Content/damageshader.fx b/Subsurface/Content/damageshader.fx new file mode 100644 index 000000000..3736cf220 --- /dev/null +++ b/Subsurface/Content/damageshader.fx @@ -0,0 +1,34 @@ + +Texture xTexture; +sampler TextureSampler : register (s0) = sampler_state { Texture = ; }; + +Texture xStencil; +sampler StencilSampler = sampler_state { Texture = ; }; + + +float cutoff; +float multiplier; + +float4 main(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 +{ + float4 c = tex2D(TextureSampler, texCoord); + + float4 stencilColor = tex2D(StencilSampler, texCoord); + + float a = stencilColor.a - cutoff; + + clip(a); + + a = min(a * multiplier, 1.0f); + c = lerp(c, stencilColor, 1.0f - a); + + return c * a; +} + +technique StencilShader +{ + pass Pass1 + { + PixelShader = compile ps_4_0_level_9_3 main(); + } +} diff --git a/Subsurface/Content/damageshader.xnb b/Subsurface/Content/damageshader.xnb new file mode 100644 index 000000000..efa2c33c0 Binary files /dev/null and b/Subsurface/Content/damageshader.xnb differ diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 6473e1d35..33171d373 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -370,6 +370,13 @@ namespace Barotrauma public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) + { + Draw(spriteBatch, editing, back, null); + } + + private static float prevCutoff; + + public void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null) { if (prefab.sprite == null) return; @@ -382,14 +389,32 @@ namespace Barotrauma } Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition; - if(sections.Length == 1) - prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), new Vector2(rect.Width, rect.Height), Vector2.Zero, color,Point.Zero); + if (sections.Length == 1) + { + prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), new Vector2(rect.Width, rect.Height), Vector2.Zero, color, Point.Zero); + return; + } foreach (WallSection s in sections) { + if (damageEffect != null) + { + float newCutoff = Math.Min((s.damage / prefab.MaxHealth)*0.5f - 0.2f, 0.1f); + + if (Math.Abs(newCutoff - prevCutoff) > 0.01f) + { + damageEffect.Parameters["cutoff"].SetValue(newCutoff); + + damageEffect.CurrentTechnique.Passes[0].Apply(); + + prevCutoff = newCutoff; + } + } + Point offset = new Point(Math.Abs(rect.Location.X - s.rect.Location.X), Math.Abs(rect.Location.Y - s.rect.Location.Y)); - if (sections.Length != 1 && s.damage < prefab.MaxHealth) - prefab.sprite.DrawTiled(spriteBatch, new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), Vector2.Zero, color, offset); + if (sections.Length != 1) + prefab.sprite.DrawTiled(spriteBatch, new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), Vector2.Zero, color, offset); + if (s.isHighLighted) { @@ -399,12 +424,12 @@ namespace Barotrauma } s.isHighLighted = false; - - if (s.damage < 0.01f) continue; - GUI.DrawRectangle(spriteBatch, - new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), - Color.Black * (s.damage / prefab.MaxHealth), true); + //if (s.damage < 0.01f) continue; + + //GUI.DrawRectangle(spriteBatch, + // new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), + // Color.Black * (s.damage / prefab.MaxHealth), true); } /* if(_convexHulls == null) return; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 587269b26..52b3ee368 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -149,7 +149,7 @@ namespace Barotrauma { get { - return subBody.Position; + return subBody ==null ? Vector2.Zero : subBody.Position; } } @@ -287,11 +287,25 @@ namespace Barotrauma { for (int i = 0; i < MapEntity.mapEntityList.Count; i++) { + if (MapEntity.mapEntityList[i] is Structure) continue; if (MapEntity.mapEntityList[i].Sprite == null || MapEntity.mapEntityList[i].Sprite.Depth < 0.5f) MapEntity.mapEntityList[i].Draw(spriteBatch, editing, false); } } + public static void DrawDamageable(SpriteBatch spriteBatch, Effect damageEffect, bool editing = false) + { + for (int i = 0; i < MapEntity.mapEntityList.Count; i++) + { + var structure = MapEntity.mapEntityList[i] as Structure; + if (structure == null || structure.Sprite.Depth > 0.5f) continue; + + structure.Draw(spriteBatch, editing, false, damageEffect); + } + damageEffect.Parameters["cutoff"].SetValue(0.5f); + } + + public static void DrawBack(SpriteBatch spriteBatch, bool editing = false) { for (int i = 0; i < MapEntity.mapEntityList.Count; i++) diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 611616aad..5e665cbf7 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -18,6 +18,10 @@ namespace Barotrauma private BlurEffect lightBlur; + private Effect damageEffect; + + private Texture2D damageStencil; + public BackgroundCreatureManager BackgroundCreatureManager; public Camera Cam @@ -46,6 +50,13 @@ namespace Barotrauma var blurEffect = content.Load("blurshader"); #endif + damageStencil = TextureLoader.FromFile("Content/Map/walldamage.png"); + + damageEffect = content.Load("damageshader"); + // damageEffect.Parameters["cutoff"].SetValue(0.5f); + damageEffect.Parameters["xStencil"].SetValue(damageStencil); + + lightBlur = new BlurEffect(blurEffect, 0.001f, 0.001f); @@ -160,7 +171,10 @@ namespace Barotrauma public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) { - cam.UpdateTransform(true); + cam.UpdateTransform(true); + + + //damageStencil = TextureLoader.FromFile("Content/Map/background.png"); DrawMap(graphics, spriteBatch); @@ -324,6 +338,19 @@ namespace Barotrauma Submarine.DrawFront(spriteBatch); spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.Immediate, + BlendState.AlphaBlend, SamplerState.LinearWrap, + null, null, + damageEffect, + cam.Transform); + damageEffect.Parameters["cutoff"].SetValue(-0.2f); + damageEffect.Parameters["multiplier"].SetValue(5.0f); + + Submarine.DrawDamageable(spriteBatch, damageEffect); + + spriteBatch.End(); + GameMain.LightManager.DrawLightMap(spriteBatch, cam, lightBlur.Effect);