Files
LuaCsForBarotraumaEP/BarotraumaClient/Source/Screens/GameScreen.cs
2017-06-14 18:24:11 -03:00

326 lines
13 KiB
C#

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
namespace Barotrauma
{
partial class GameScreen : Screen
{
private Color waterColor = new Color(0.75f, 0.8f, 0.9f, 1.0f);
private BlurEffect lightBlur;
readonly RenderTarget2D renderTargetBackground;
readonly RenderTarget2D renderTarget;
readonly RenderTarget2D renderTargetWater;
readonly RenderTarget2D renderTargetAir;
private Effect damageEffect;
private Texture2D damageStencil;
public BackgroundCreatureManager BackgroundCreatureManager;
public GameScreen(GraphicsDevice graphics, ContentManager content)
{
cam = new Camera();
cam.Translate(new Vector2(-10.0f, 50.0f));
renderTargetBackground = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
renderTarget = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
renderTargetWater = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundCreaturePrefabs);
if (files.Count > 0)
BackgroundCreatureManager = new BackgroundCreatureManager(files);
else
BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml");
#if LINUX
var blurEffect = content.Load<Effect>("blurshader_opengl");
damageEffect = content.Load<Effect>("damageshader_opengl");
#else
var blurEffect = content.Load<Effect>("blurshader");
damageEffect = content.Load<Effect>("damageshader");
#endif
damageStencil = TextureLoader.FromFile("Content/Map/walldamage.png");
damageEffect.Parameters["xStencil"].SetValue(damageStencil);
damageEffect.Parameters["aMultiplier"].SetValue(50.0f);
damageEffect.Parameters["cMultiplier"].SetValue(200.0f);
lightBlur = new BlurEffect(blurEffect, 0.001f, 0.001f);
}
public override void AddToGUIUpdateList()
{
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null)
{
if (Character.Controlled.SelectedConstruction == Character.Controlled.ClosestItem)
{
Character.Controlled.SelectedConstruction.AddToGUIUpdateList();
}
}
if (GameMain.GameSession != null) GameMain.GameSession.AddToGUIUpdateList();
Character.AddAllToGUIUpdateList();
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
cam.UpdateTransform(true);
Submarine.CullEntities(cam);
DrawMap(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null)
{
if (Character.Controlled.SelectedConstruction == Character.Controlled.ClosestItem)
{
Character.Controlled.SelectedConstruction.DrawHUD(spriteBatch, cam, Character.Controlled);
}
}
if (Character.Controlled != null && cam != null) Character.Controlled.DrawHUD(spriteBatch, cam);
if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch);
if (Character.Controlled == null && !GUI.DisableHUD)
{
for (int i = 0; i < Submarine.MainSubs.Length; i++)
{
if (Submarine.MainSubs[i] != null)
{
Color indicatorColor = i == 0 ? Color.LightBlue * 0.5f : Color.Red * 0.5f;
DrawSubmarineIndicator(spriteBatch, Submarine.MainSubs[i], indicatorColor);
}
}
}
GUI.Draw((float)deltaTime, spriteBatch, cam);
spriteBatch.End();
}
public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch)
{
foreach (Submarine sub in Submarine.Loaded)
{
sub.UpdateTransform();
}
GameMain.ParticleManager.UpdateTransforms();
GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision;
GameMain.LightManager.UpdateLightMap(graphics, spriteBatch, cam, lightBlur.Effect);
if (Character.Controlled != null)
{
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled.CursorWorldPosition);
}
//----------------------------------------------------------------------------------------
//1. draw the background, characters and the parts of the submarine that are behind them
//----------------------------------------------------------------------------------------
graphics.SetRenderTarget(renderTargetBackground);
if (Level.Loaded == null)
{
graphics.Clear(new Color(11, 18, 26, 255));
}
else
{
Level.Loaded.DrawBack(graphics, spriteBatch, cam, BackgroundCreatureManager);
}
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null, null, null, null,
cam.Transform);
Submarine.DrawBack(spriteBatch, false, s => s is Structure);
spriteBatch.End();
graphics.SetRenderTarget(renderTarget);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque);
spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null, null, null, null,
cam.Transform);
Submarine.DrawBack(spriteBatch, false, s => !(s is Structure));
foreach (Character c in Character.CharacterList) c.Draw(spriteBatch);
spriteBatch.End();
//----------------------------------------------------------------------------------------
//draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater
graphics.SetRenderTarget(renderTargetWater);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), waterColor);
spriteBatch.End();
#if LINUX
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.NonPremultiplied,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#else
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#endif
GameMain.ParticleManager.Draw(spriteBatch, true, Particles.ParticleBlendState.AlphaBlend);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Additive,
null, DepthStencilState.Default, null, null,
cam.Transform);
GameMain.ParticleManager.Draw(spriteBatch, true, Particles.ParticleBlendState.Additive);
spriteBatch.End();
//----------------------------------------------------------------------------------------
//draw the rendertarget and particles that are only supposed to be drawn in air into renderTargetAir
graphics.SetRenderTarget(renderTargetAir);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
#if LINUX
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.NonPremultiplied,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#else
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
#endif
GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.AlphaBlend);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Additive,
null, DepthStencilState.DepthRead, null, null,
cam.Transform);
GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive);
spriteBatch.End();
if (Character.Controlled != null && GameMain.LightManager.LosEnabled)
{
graphics.SetRenderTarget(renderTarget);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.Opaque, null, null, null, lightBlur.Effect);
spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend, SamplerState.LinearWrap,
null, null, null,
cam.Transform);
Submarine.DrawDamageable(spriteBatch, null, false);
Submarine.DrawFront(spriteBatch, false, s => s is Structure);
spriteBatch.End();
GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect, true);
}
graphics.SetRenderTarget(null);
//----------------------------------------------------------------------------------------
//2. pass the renderTarget to the water shader to do the water effect
//----------------------------------------------------------------------------------------
Hull.renderer.RenderBack(spriteBatch, renderTargetWater);
Array.Clear(Hull.renderer.vertices, 0, Hull.renderer.vertices.Length);
Hull.renderer.PositionInBuffer = 0;
foreach (Hull hull in Hull.hullList)
{
hull.Render(graphics, cam);
}
Hull.renderer.Render(graphics, cam, renderTargetAir, Cam.ShaderTransform);
//----------------------------------------------------------------------------------------
//3. draw the sections of the map that are on top of the water
//----------------------------------------------------------------------------------------
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend, SamplerState.LinearWrap,
null, null, null,
cam.Transform);
Submarine.DrawFront(spriteBatch, false, null);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.NonPremultiplied, SamplerState.LinearWrap,
null, null,
damageEffect,
cam.Transform);
Submarine.DrawDamageable(spriteBatch, damageEffect, false);
spriteBatch.End();
GameMain.LightManager.DrawLightMap(spriteBatch, lightBlur.Effect);
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend, SamplerState.LinearWrap,
null, null, null,
cam.Transform);
if (Level.Loaded != null) Level.Loaded.DrawFront(spriteBatch);
foreach (Character c in Character.CharacterList) c.DrawFront(spriteBatch, cam);
spriteBatch.End();
if (Character.Controlled != null && GameMain.LightManager.LosEnabled)
{
GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect, false);
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullNone, null);
float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f);
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
Color.Lerp(GameMain.LightManager.AmbientLight * 0.5f, Color.Red, r));
spriteBatch.End();
}
}
}
}