38f1ddb...178a853: v0.8.9.1, removed content folder

This commit is contained in:
Joonas Rikkonen
2019-03-18 19:46:58 +02:00
parent 38f1ddb6fe
commit 6c0679c297
1054 changed files with 151673 additions and 144931 deletions
@@ -26,6 +26,10 @@ namespace Barotrauma
private float checkWallsTimer;
private float wanderZPhase;
private Vector2 obstacleDiff;
private float obstacleDist;
public Swarm Swarm;
Vector2 drawPosition;
@@ -71,12 +75,9 @@ namespace Barotrauma
Rand.Range(0.0f, prefab.WanderZAmount));
checkWallsTimer = Rand.Range(0.0f, CheckWallsInterval);
}
float ang;
Vector2 obstacleDiff;
public void Update(float deltaTime)
{
position += new Vector2(velocity.X, velocity.Y) * deltaTime;
@@ -109,30 +110,33 @@ namespace Barotrauma
var cells = Level.Loaded.GetCells(position, 1);
if (cells.Count > 0)
{
int cellCount = 0;
foreach (Voronoi2.VoronoiCell cell in cells)
{
obstacleDiff += cell.Center - position;
Vector2 diff = cell.Center - position;
if (diff.LengthSquared() > 5000.0f * 5000.0f) continue;
obstacleDiff += diff;
cellCount++;
}
if (cellCount > 0)
{
obstacleDiff /= cellCount;
obstacleDist = obstacleDiff.Length();
obstacleDiff = Vector2.Normalize(obstacleDiff);
}
obstacleDiff /= cells.Count;
obstacleDiff = Vector2.Normalize(obstacleDiff) * prefab.Speed;
}
}
}
if (Swarm!=null)
if (Swarm != null)
{
Vector2 midPoint = Swarm.MidPoint();
float midPointDist = Vector2.Distance(SimPosition, midPoint);
float midPointDist = Vector2.Distance(SimPosition, midPoint) * 100.0f;
if (midPointDist > Swarm.MaxDistance)
{
steeringManager.SteeringSeek(midPoint, (midPointDist / Swarm.MaxDistance) * prefab.Speed);
steeringManager.SteeringSeek(midPoint, ((midPointDist / Swarm.MaxDistance) - 1.0f) * prefab.Speed);
}
steeringManager.SteeringManual(deltaTime, Swarm.AvgVelocity() * Swarm.Cohesion);
}
if (prefab.WanderAmount > 0.0f)
@@ -140,26 +144,23 @@ namespace Barotrauma
steeringManager.SteeringWander(prefab.Speed);
}
//Level.Loaded.Size
if (obstacleDiff != Vector2.Zero)
{
steeringManager.SteeringSeek(SimPosition-obstacleDiff, prefab.Speed*2.0f);
steeringManager.SteeringManual(deltaTime, -obstacleDiff * (1.0f - obstacleDist / 5000.0f) * prefab.Speed);
}
steeringManager.Update(prefab.Speed);
if (prefab.WanderZAmount>0.0f)
if (prefab.WanderZAmount > 0.0f)
{
ang += Rand.Range(-prefab.WanderZAmount, prefab.WanderZAmount);
velocity.Z = (float)Math.Sin(ang)*prefab.Speed;
wanderZPhase += Rand.Range(-prefab.WanderZAmount, prefab.WanderZAmount);
velocity.Z = (float)Math.Sin(wanderZPhase) * prefab.Speed;
}
velocity = Vector3.Lerp(velocity, new Vector3(Steering.X, Steering.Y, velocity.Z), deltaTime);
}
public void Draw(SpriteBatch spriteBatch)
public void Draw(SpriteBatch spriteBatch, Camera cam)
{
float rotation = 0.0f;
if (!prefab.DisableRotation)
@@ -168,20 +169,18 @@ namespace Barotrauma
if (velocity.X < 0.0f) rotation -= MathHelper.Pi;
}
drawPosition = position;// +Level.Loaded.Position;
drawPosition = position;
if (depth > 0.0f)
{
Vector2 camOffset = drawPosition - GameMain.GameScreen.Cam.WorldViewCenter;
Vector2 camOffset = drawPosition - cam.WorldViewCenter;
drawPosition -= camOffset * (depth / MaxDepth) * 0.05f;
}
prefab.Sprite.Draw(spriteBatch,
new Vector2(drawPosition.X, -drawPosition.Y),
Color.Lerp(Color.White, Color.DarkBlue, (depth/MaxDepth)*0.3f),
rotation, (1.0f - (depth / MaxDepth) * 0.2f) * prefab.Scale,
velocity.X > 0.0f ? SpriteEffects.None : SpriteEffects.FlipHorizontally,
prefab.Sprite.Draw(spriteBatch,
new Vector2(drawPosition.X, -drawPosition.Y),
Color.Lerp(Color.White, Level.Loaded.BackgroundColor, (depth / MaxDepth) * 0.2f),
rotation, (1.0f - (depth / MaxDepth) * 0.2f) * prefab.Scale,
velocity.X > 0.0f ? SpriteEffects.None : SpriteEffects.FlipHorizontally,
(depth / MaxDepth));
}
}
@@ -191,6 +190,7 @@ namespace Barotrauma
public List<BackgroundCreature> Members;
public readonly float MaxDistance;
public readonly float Cohesion;
public Vector2 MidPoint()
{
@@ -213,23 +213,19 @@ namespace Barotrauma
if (Members.Count == 0) return Vector2.Zero;
Vector2 avgVel = Vector2.Zero;
foreach (BackgroundCreature member in Members)
{
avgVel += member.Velocity;
}
avgVel /= Members.Count;
avgVel /= Members.Count;
return avgVel;
}
public Swarm(List<BackgroundCreature> members, float maxDistance)
public Swarm(List<BackgroundCreature> members, float maxDistance, float cohesion)
{
this.Members = members;
this.MaxDistance = maxDistance;
Members = members;
MaxDistance = maxDistance;
Cohesion = cohesion;
foreach (BackgroundCreature bgSprite in members)
{
bgSprite.Swarm = this;
@@ -22,7 +22,7 @@ namespace Barotrauma
{
LoadConfig(configPath);
}
public BackgroundCreatureManager(List<string> files)
public BackgroundCreatureManager(IEnumerable<string> files)
{
foreach(var file in files)
{
@@ -92,7 +92,7 @@ namespace Barotrauma
}
if (amount > 0)
{
new Swarm(swarmMembers, prefab.SwarmRadius);
new Swarm(swarmMembers, prefab.SwarmRadius, prefab.SwarmCohesion);
}
}
}
@@ -126,12 +126,12 @@ namespace Barotrauma
}
}
public void Draw(SpriteBatch spriteBatch)
public void Draw(SpriteBatch spriteBatch, Camera cam)
{
foreach (BackgroundCreature sprite in activeSprites)
{
if (!sprite.Enabled) continue;
sprite.Draw(spriteBatch);
sprite.Draw(spriteBatch, cam);
}
}
}
@@ -13,8 +13,7 @@ namespace Barotrauma
public readonly float WanderZAmount;
public readonly int SwarmMin, SwarmMax;
public readonly float SwarmRadius;
public readonly float SwarmRadius, SwarmCohesion;
public readonly bool DisableRotation;
@@ -32,6 +31,7 @@ namespace Barotrauma
SwarmMax = element.GetAttributeInt("swarmmax", 1);
SwarmRadius = element.GetAttributeFloat("swarmradius", 200.0f);
SwarmCohesion = element.GetAttributeFloat("swarmcohesion", 0.2f);
DisableRotation = element.GetAttributeBool("disablerotation", false);
@@ -1,139 +0,0 @@
using Barotrauma.Particles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Barotrauma
{
partial class BackgroundSprite
{
public List<ParticleEmitter> ParticleEmitters;
public Sound Sound;
}
partial class BackgroundSpriteManager
{
private List<BackgroundSprite> visibleSprites = new List<BackgroundSprite>();
private Rectangle currentGridIndices;
partial void UpdateProjSpecific(float deltaTime)
{
foreach (BackgroundSprite s in visibleSprites)
{
if (s.ParticleEmitters != null)
{
for (int i = 0; i < s.ParticleEmitters.Count; i++)
{
Vector2 emitterPos = s.LocalToWorld(s.Prefab.EmitterPositions[i]);
s.ParticleEmitters[i].Emit(deltaTime, emitterPos);
}
}
if (s.Sound != null)
{
int sourceIndex;
Vector2 soundPos = s.LocalToWorld(new Vector2(s.Prefab.SoundPosition.X, s.Prefab.SoundPosition.Y));
if (!Sounds.SoundManager.IsPlaying(s.Sound, out sourceIndex))
{
s.Sound.Play(soundPos);
}
else
{
s.Sound.UpdatePosition(soundPos);
}
}
}
}
public void DrawSprites(SpriteBatch spriteBatch, Camera cam)
{
Rectangle indices = Rectangle.Empty;
indices.X = (int)Math.Floor(cam.WorldView.X / (float)GridSize);
if (indices.X >= spriteGrid.GetLength(0)) return;
indices.Y = (int)Math.Floor((cam.WorldView.Y - cam.WorldView.Height - Level.Loaded.BottomPos) / (float)GridSize);
if (indices.Y >= spriteGrid.GetLength(1)) return;
indices.Width = (int)Math.Floor(cam.WorldView.Right / (float)GridSize)+1;
if (indices.Width < 0) return;
indices.Height = (int)Math.Floor((cam.WorldView.Y - Level.Loaded.BottomPos) / (float)GridSize)+1;
if (indices.Height < 0) return;
indices.X = Math.Max(indices.X, 0);
indices.Y = Math.Max(indices.Y, 0);
indices.Width = Math.Min(indices.Width, spriteGrid.GetLength(0)-1);
indices.Height = Math.Min(indices.Height, spriteGrid.GetLength(1)-1);
float z = 0.0f;
if (currentGridIndices != indices)
{
visibleSprites.Clear();
for (int x = indices.X; x <= indices.Width; x++)
{
for (int y = indices.Y; y <= indices.Height; y++)
{
if (spriteGrid[x, y] == null) continue;
foreach (BackgroundSprite sprite in spriteGrid[x, y])
{
int drawOrderIndex = 0;
for (int i = 0; i < visibleSprites.Count; i++)
{
if (visibleSprites[i] == sprite)
{
drawOrderIndex = -1;
break;
}
if (visibleSprites[i].Position.Z < sprite.Position.Z)
{
break;
}
else
{
drawOrderIndex = i + 1;
}
}
if (drawOrderIndex >= 0)
{
visibleSprites.Insert(drawOrderIndex, sprite);
}
}
}
}
currentGridIndices = indices;
}
foreach (BackgroundSprite sprite in visibleSprites)
{
Vector2 camDiff = new Vector2(sprite.Position.X, sprite.Position.Y) - cam.WorldViewCenter;
camDiff.Y = -camDiff.Y;
sprite.Prefab.Sprite.Draw(
spriteBatch,
new Vector2(sprite.Position.X, -sprite.Position.Y) - camDiff * sprite.Position.Z / 10000.0f,
Color.Lerp(Color.White, Level.Loaded.BackgroundColor, sprite.Position.Z / 5000.0f),
sprite.Rotation + swingState * sprite.Prefab.SwingAmount,
sprite.Scale,
SpriteEffects.None,
z);
if (GameMain.DebugDraw)
{
GUI.DrawRectangle(spriteBatch, new Vector2(sprite.Position.X, -sprite.Position.Y), new Vector2(10.0f, 10.0f), Color.Red, true);
if (sprite.Trigger != null && sprite.Trigger.PhysicsBody != null)
{
sprite.Trigger.PhysicsBody.UpdateDrawPosition();
sprite.Trigger.PhysicsBody.DebugDraw(spriteBatch, Color.Cyan);
}
}
z += 0.0001f;
}
}
}
}
@@ -1,16 +0,0 @@
using Barotrauma.Particles;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma
{
partial class BackgroundSpritePrefab
{
public readonly List<ParticleEmitterPrefab> ParticleEmitterPrefabs;
public readonly List<Vector2> EmitterPositions;
public readonly XElement SoundElement;
public readonly Vector2 SoundPosition;
}
}
@@ -29,52 +29,52 @@ namespace Barotrauma
public static VertexPositionTexture[] GenerateWallShapes(List<VoronoiCell> cells, Level level)
{
float inwardThickness = 500.0f, outWardThickness = 30.0f;
float outWardThickness = 30.0f;
List<VertexPositionTexture> verticeList = new List<VertexPositionTexture>();
foreach (VoronoiCell cell in cells)
{
//if (cell.body == null) continue;
foreach (GraphEdge edge in cell.edges)
CompareCCW compare = new CompareCCW(cell.Center);
foreach (GraphEdge edge in cell.Edges)
{
if (edge.cell1 != null && edge.cell1.body == null && edge.cell1.CellType != CellType.Empty) edge.cell1 = null;
if (edge.cell2 != null && edge.cell2.body == null && edge.cell2.CellType != CellType.Empty) edge.cell2 = null;
if (edge.Cell1 != null && edge.Cell1.Body == null && edge.Cell1.CellType != CellType.Empty) edge.Cell1 = null;
if (edge.Cell2 != null && edge.Cell2.Body == null && edge.Cell2.CellType != CellType.Empty) edge.Cell2 = null;
CompareCCW compare = new CompareCCW(cell.Center);
if (compare.Compare(edge.point1, edge.point2) == -1)
if (compare.Compare(edge.Point1, edge.Point2) == -1)
{
var temp = edge.point1;
edge.point1 = edge.point2;
edge.point2 = temp;
var temp = edge.Point1;
edge.Point1 = edge.Point2;
edge.Point2 = temp;
}
}
}
foreach (VoronoiCell cell in cells)
{
//if (cell.body == null) continue;
foreach (GraphEdge edge in cell.edges)
foreach (GraphEdge edge in cell.Edges)
{
if (!edge.isSolid) continue;
if (!edge.IsSolid) continue;
GraphEdge leftEdge = cell.edges.Find(e => e != edge && (edge.point1 == e.point1 || edge.point1 == e.point2));
GraphEdge rightEdge = cell.edges.Find(e => e != edge && (edge.point2 == e.point1 || edge.point2 == e.point2));
GraphEdge leftEdge = cell.Edges.Find(e => e != edge && (edge.Point1 == e.Point1 || edge.Point1 == e.Point2));
GraphEdge rightEdge = cell.Edges.Find(e => e != edge && (edge.Point2 == e.Point1 || edge.Point2 == e.Point2));
Vector2 leftNormal = Vector2.Zero, rightNormal = Vector2.Zero;
if (leftEdge == null)
float inwardThickness1 = 100;
float inwardThickness2 = 100;
if (leftEdge != null && !leftEdge.IsSolid)
{
leftNormal = GetEdgeNormal(edge, cell);
leftNormal = edge.Point1 == leftEdge.Point1 ?
Vector2.Normalize(leftEdge.Point2 - leftEdge.Point1) :
Vector2.Normalize(leftEdge.Point1 - leftEdge.Point2);
inwardThickness1 = Vector2.Distance(leftEdge.Point1, leftEdge.Point2) / 2;
}
else
{
leftNormal = (leftEdge.isSolid) ?
Vector2.Normalize(GetEdgeNormal(leftEdge) + GetEdgeNormal(edge, cell)) :
Vector2.Normalize(leftEdge.Center - edge.point1);
leftNormal = Vector2.Normalize(cell.Center - edge.Point1);
inwardThickness1 = Vector2.Distance(edge.Point1, cell.Center) / 2;
}
if (!MathUtils.IsValid(leftNormal))
{
#if DEBUG
@@ -84,25 +84,26 @@ namespace Barotrauma
GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
"Invalid left normal (leftedge: " + leftEdge + ", rightedge: " + rightEdge + ", normal: " + leftNormal + ", seed: " + level.Seed + ")");
if (cell.body != null)
if (cell.Body != null)
{
GameMain.World.RemoveBody(cell.body);
cell.body = null;
GameMain.World.RemoveBody(cell.Body);
cell.Body = null;
}
leftNormal = Vector2.UnitX;
break;
}
if (rightEdge == null)
if (rightEdge != null && !rightEdge.IsSolid)
{
rightNormal = GetEdgeNormal(edge, cell);
rightNormal = edge.Point2 == rightEdge.Point1 ?
Vector2.Normalize(rightEdge.Point2 - rightEdge.Point1) :
Vector2.Normalize(rightEdge.Point1 - rightEdge.Point2);
inwardThickness2 = Vector2.Distance(rightEdge.Point1, rightEdge.Point2) / 2;
}
else
{
rightNormal = (rightEdge.isSolid) ?
Vector2.Normalize(GetEdgeNormal(rightEdge) + GetEdgeNormal(edge, cell)) :
Vector2.Normalize(rightEdge.Center - edge.point2);
rightNormal = Vector2.Normalize(cell.Center - edge.Point2);
inwardThickness2 = Vector2.Distance(edge.Point2, cell.Center) / 2;
}
if (!MathUtils.IsValid(rightNormal))
@@ -114,49 +115,54 @@ namespace Barotrauma
GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
"Invalid right normal (leftedge: " + leftEdge + ", rightedge: " + rightEdge + ", normal: " + rightNormal + ", seed: " + level.Seed + ")");
if (cell.body != null)
if (cell.Body != null)
{
GameMain.World.RemoveBody(cell.body);
cell.body = null;
GameMain.World.RemoveBody(cell.Body);
cell.Body = null;
}
rightNormal = Vector2.UnitX;
break;
}
float point1UV = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(edge.Point1 - cell.Center));
float point2UV = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(edge.Point2 - cell.Center));
//handle wrapping around 0/360
if (point1UV - point2UV > MathHelper.Pi)
{
point2UV += MathHelper.TwoPi;
}
//the texture wraps around the cell 4 times
//TODO: define the uv scale in level generation parameters?
point1UV = point1UV / MathHelper.TwoPi * 4;
point2UV = point2UV / MathHelper.TwoPi * 4;
for (int i = 0; i < 2; i++)
{
Vector2[] verts = new Vector2[3];
VertexPositionTexture[] vertPos = new VertexPositionTexture[3];
if (i == 0)
{
verts[0] = edge.point1 - leftNormal * outWardThickness;
verts[1] = edge.point2 - rightNormal * outWardThickness;
verts[2] = edge.point1 + leftNormal * inwardThickness;
verts[0] = edge.Point1 - leftNormal * outWardThickness;
verts[1] = edge.Point2 - rightNormal * outWardThickness;
verts[2] = edge.Point1 + leftNormal * inwardThickness1;
vertPos[0] = new VertexPositionTexture(new Vector3(verts[0], 0.0f), Vector2.Zero);
vertPos[1] = new VertexPositionTexture(new Vector3(verts[1], 0.0f), Vector2.UnitX);
vertPos[2] = new VertexPositionTexture(new Vector3(verts[2], 0.0f), new Vector2(0, 0.5f));
vertPos[0] = new VertexPositionTexture(new Vector3(verts[0], 0.0f), new Vector2(point1UV, 0.0f));
vertPos[1] = new VertexPositionTexture(new Vector3(verts[1], 0.0f), new Vector2(point2UV, 0.0f));
vertPos[2] = new VertexPositionTexture(new Vector3(verts[2], 0.0f), new Vector2(point1UV, 0.5f));
}
else
{
verts[0] = edge.point1 + leftNormal * inwardThickness;
verts[1] = edge.point2 - rightNormal * outWardThickness;
verts[2] = edge.point2 + rightNormal * inwardThickness;
vertPos[0] = new VertexPositionTexture(new Vector3(verts[0], 0.0f), new Vector2(0.0f, 0.5f));
vertPos[1] = new VertexPositionTexture(new Vector3(verts[1], 0.0f), Vector2.UnitX);
vertPos[2] = new VertexPositionTexture(new Vector3(verts[2], 0.0f), new Vector2(1.0f, 0.5f));
}
var comparer = new CompareCCW((verts[0] + verts[1] + verts[2]) / 3.0f);
Array.Sort(verts, vertPos, comparer);
for (int j = 0; j < 3; j++)
{
verticeList.Add(vertPos[j]);
verts[0] = edge.Point1 + leftNormal * inwardThickness1;
verts[1] = edge.Point2 - rightNormal * outWardThickness;
verts[2] = edge.Point2 + rightNormal * inwardThickness2;
vertPos[0] = new VertexPositionTexture(new Vector3(verts[0], 0.0f), new Vector2(point1UV, 0.5f));
vertPos[1] = new VertexPositionTexture(new Vector3(verts[1], 0.0f), new Vector2(point2UV, 0.0f));
vertPos[2] = new VertexPositionTexture(new Vector3(verts[2], 0.0f), new Vector2(point2UV, 0.5f));
}
verticeList.AddRange(vertPos);
}
}
}
@@ -1,5 +1,10 @@
using Microsoft.Xna.Framework;
using Barotrauma.Networking;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using FarseerPhysics.Dynamics;
using System.Linq;
using System.Collections.Generic;
namespace Barotrauma
{
@@ -8,11 +13,42 @@ namespace Barotrauma
private LevelRenderer renderer;
private BackgroundCreatureManager backgroundCreatureManager;
public LevelRenderer Renderer => renderer;
public void ReloadTextures()
{
renderer.ReloadTextures();
HashSet<Texture2D> uniqueTextures = new HashSet<Texture2D>();
HashSet<Sprite> uniqueSprites = new HashSet<Sprite>();
var allLevelObjects = levelObjectManager.GetAllObjects();
foreach (var levelObj in allLevelObjects)
{
if (levelObj.Prefab.Sprite != null &&
!uniqueTextures.Contains(levelObj.Prefab.Sprite.Texture))
{
uniqueTextures.Add(levelObj.Prefab.Sprite.Texture);
uniqueSprites.Add(levelObj.Prefab.Sprite);
}
if (levelObj.Prefab.SpecularSprite != null &&
!uniqueTextures.Contains(levelObj.Prefab.SpecularSprite.Texture))
{
uniqueTextures.Add(levelObj.Prefab.SpecularSprite.Texture);
uniqueSprites.Add(levelObj.Prefab.SpecularSprite);
}
}
foreach (Sprite sprite in uniqueSprites)
{
sprite.ReloadTexture();
}
}
public void DrawFront(SpriteBatch spriteBatch)
public void DrawFront(SpriteBatch spriteBatch, Camera cam)
{
if (renderer == null) return;
renderer.Draw(spriteBatch);
renderer.Draw(spriteBatch, cam);
if (GameMain.DebugDraw)
{
@@ -43,13 +79,37 @@ namespace Barotrauma
public void DrawBack(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam)
{
float brightness = MathHelper.Clamp(1.1f + (cam.Position.Y - Size.Y) / 100000.0f, 0.1f, 1.0f);
GameMain.LightManager.AmbientLight = new Color(backgroundColor * brightness, 1.0f);
float brightness = MathHelper.Clamp(1.1f + (cam.Position.Y - Size.Y) / 100000.0f, 0.1f, 1.0f);
var lightColorHLS = generationParams.AmbientLightColor.RgbToHLS();
lightColorHLS.Y *= brightness;
graphics.Clear(backgroundColor);
GameMain.LightManager.AmbientLight = ToolBox.HLSToRGB(lightColorHLS);
graphics.Clear(BackgroundColor);
if (renderer == null) return;
renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager, backgroundCreatureManager);
renderer.DrawBackground(spriteBatch, cam, levelObjectManager, backgroundCreatureManager);
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
if (GameMain.Server != null) return;
foreach (LevelWall levelWall in extraWalls)
{
if (levelWall.Body.BodyType == BodyType.Static) continue;
Vector2 bodyPos = new Vector2(
msg.ReadSingle(),
msg.ReadSingle());
levelWall.MoveState = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 16);
if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f)
{
levelWall.Body.SetTransform(bodyPos, levelWall.Body.Rotation);
}
}
}
}
}
@@ -0,0 +1,291 @@
using Barotrauma.Lights;
using Barotrauma.Particles;
using Barotrauma.Sounds;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Barotrauma.SpriteDeformations;
using Lidgren.Network;
using System.Linq;
using FarseerPhysics.Dynamics;
namespace Barotrauma
{
partial class LevelObject
{
public float SwingTimer;
public float ScaleOscillateTimer;
public float CurrentSwingAmount;
public Vector2 CurrentScaleOscillation;
public float CurrentRotation;
private List<SpriteDeformation> spriteDeformations = new List<SpriteDeformation>();
public Vector2 CurrentScale
{
get;
private set;
} = Vector2.One;
public LightSource[] LightSources
{
get;
private set;
}
public LevelTrigger[] LightSourceTriggers
{
get;
private set;
}
public ParticleEmitter[] ParticleEmitters
{
get;
private set;
}
public LevelTrigger[] ParticleEmitterTriggers
{
get;
private set;
}
public RoundSound[] Sounds
{
get;
private set;
}
public SoundChannel[] SoundChannels
{
get;
private set;
}
public LevelTrigger[] SoundTriggers
{
get;
private set;
}
public Vector2[,] CurrentSpriteDeformation
{
get;
private set;
}
partial void InitProjSpecific()
{
CurrentSwingAmount = Prefab.SwingAmountRad;
CurrentScaleOscillation = Prefab.ScaleOscillation;
SwingTimer = Rand.Range(0.0f, MathHelper.TwoPi);
ScaleOscillateTimer = Rand.Range(0.0f, MathHelper.TwoPi);
if (Prefab.ParticleEmitterPrefabs != null)
{
ParticleEmitters = new ParticleEmitter[Prefab.ParticleEmitterPrefabs.Count];
ParticleEmitterTriggers = new LevelTrigger[Prefab.ParticleEmitterPrefabs.Count];
for (int i = 0; i < Prefab.ParticleEmitterPrefabs.Count; i++)
{
ParticleEmitters[i] = new ParticleEmitter(Prefab.ParticleEmitterPrefabs[i]);
ParticleEmitterTriggers[i] = Prefab.ParticleEmitterTriggerIndex[i] > -1 ?
Triggers[Prefab.ParticleEmitterTriggerIndex[i]] : null;
}
}
if (Prefab.LightSourceParams != null)
{
LightSources = new LightSource[Prefab.LightSourceParams.Count];
LightSourceTriggers = new LevelTrigger[Prefab.LightSourceParams.Count];
for (int i = 0; i < Prefab.LightSourceParams.Count; i++)
{
LightSources[i] = new LightSource(Prefab.LightSourceParams[i])
{
Position = new Vector2(Position.X, Position.Y),
IsBackground = true
};
LightSourceTriggers[i] = Prefab.LightSourceTriggerIndex[i] > -1 ?
Triggers[Prefab.LightSourceTriggerIndex[i]] : null;
}
}
Sounds = new RoundSound[Prefab.Sounds.Count];
SoundChannels = new SoundChannel[Prefab.Sounds.Count];
SoundTriggers = new LevelTrigger[Prefab.Sounds.Count];
for (int i = 0; i < Prefab.Sounds.Count; i++)
{
Sounds[i] = Submarine.LoadRoundSound(Prefab.Sounds[i].SoundElement, false);
SoundTriggers[i] = Prefab.Sounds[i].TriggerIndex > -1 ? Triggers[Prefab.Sounds[i].TriggerIndex] : null;
}
int j = 0;
foreach (XElement subElement in Prefab.Config.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() != "deformablesprite") continue;
foreach (XElement animationElement in subElement.Elements())
{
var newDeformation = SpriteDeformation.Load(animationElement, Prefab.Name);
if (newDeformation != null)
{
newDeformation.DeformationParams = Prefab.SpriteDeformations[j].DeformationParams;
spriteDeformations.Add(newDeformation);
j++;
}
}
}
}
public void Update(float deltaTime)
{
if (ParticleEmitters != null)
{
for (int i = 0; i < ParticleEmitters.Length; i++)
{
if (ParticleEmitterTriggers[i] != null && !ParticleEmitterTriggers[i].IsTriggered) continue;
Vector2 emitterPos = LocalToWorld(Prefab.EmitterPositions[i]);
ParticleEmitters[i].Emit(deltaTime, emitterPos, hullGuess: null,
angle: ParticleEmitters[i].Prefab.CopyEntityAngle ? Rotation : 0.0f);
}
}
CurrentRotation = Rotation;
if (ActivePrefab.SwingFrequency > 0.0f)
{
SwingTimer += deltaTime * ActivePrefab.SwingFrequency;
SwingTimer = SwingTimer % MathHelper.TwoPi;
//lerp the swing amount to the correct value to prevent it from abruptly changing to a different value
//when a trigger changes the swing amoung
CurrentSwingAmount = MathHelper.Lerp(CurrentSwingAmount, ActivePrefab.SwingAmountRad, deltaTime * 10.0f);
if (ActivePrefab.SwingAmountRad > 0.0f)
{
CurrentRotation += (float)Math.Sin(SwingTimer) * CurrentSwingAmount;
}
}
CurrentScale = Vector2.One * Scale;
if (ActivePrefab.ScaleOscillationFrequency > 0.0f)
{
ScaleOscillateTimer += deltaTime * ActivePrefab.ScaleOscillationFrequency;
ScaleOscillateTimer = ScaleOscillateTimer % MathHelper.TwoPi;
CurrentScaleOscillation = Vector2.Lerp(CurrentScaleOscillation, ActivePrefab.ScaleOscillation, deltaTime * 10.0f);
float sin = (float)Math.Sin(ScaleOscillateTimer);
CurrentScale *= new Vector2(
1.0f + sin * CurrentScaleOscillation.X,
1.0f + sin * CurrentScaleOscillation.Y);
}
if (LightSources != null)
{
for (int i = 0; i < LightSources.Length; i++)
{
if (LightSourceTriggers[i] != null) LightSources[i].Enabled = LightSourceTriggers[i].IsTriggered;
LightSources[i].Rotation = -CurrentRotation;
LightSources[i].SpriteScale = CurrentScale;
}
}
if (spriteDeformations.Count > 0)
{
UpdateDeformations(deltaTime);
}
for (int i = 0; i < Sounds.Length; i++)
{
if (SoundTriggers[i] == null || SoundTriggers[i].IsTriggered)
{
RoundSound roundSound = Sounds[i];
Vector2 soundPos = LocalToWorld(new Vector2(Prefab.Sounds[i].Position.X, Prefab.Sounds[i].Position.Y));
if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), soundPos) <
roundSound.Range * roundSound.Range)
{
if (SoundChannels[i] == null || !SoundChannels[i].IsPlaying)
{
SoundChannels[i] = roundSound.Sound.Play(roundSound.Volume, roundSound.Range, soundPos);
}
SoundChannels[i].Position = new Vector3(soundPos.X, soundPos.Y, 0.0f);
}
}
else if (SoundChannels[i] != null && SoundChannels[i].IsPlaying)
{
SoundChannels[i].Dispose();
SoundChannels[i] = null;
}
}
}
private void UpdateDeformations(float deltaTime)
{
foreach (SpriteDeformation deformation in spriteDeformations)
{
if (deformation is PositionalDeformation positionalDeformation)
{
UpdatePositionalDeformation(positionalDeformation, deltaTime);
}
deformation.Update(deltaTime);
}
CurrentSpriteDeformation = SpriteDeformation.GetDeformation(spriteDeformations, ActivePrefab.DeformableSprite.Size);
foreach (LightSource lightSource in LightSources)
{
if (lightSource?.DeformableLightSprite != null)
{
lightSource.DeformableLightSprite.Deform(CurrentSpriteDeformation);
}
}
}
private void UpdatePositionalDeformation(PositionalDeformation positionalDeformation, float deltaTime)
{
Matrix matrix = ActivePrefab.DeformableSprite.GetTransform(
Position,
ActivePrefab.DeformableSprite.Origin,
CurrentRotation,
Vector2.One * Scale);
Matrix rotationMatrix = Matrix.CreateRotationZ(CurrentRotation);
foreach (LevelTrigger trigger in Triggers)
{
foreach (Entity triggerer in trigger.Triggerers)
{
Vector2 moveAmount = triggerer.WorldPosition - trigger.TriggererPosition[triggerer];
moveAmount = Vector2.Transform(moveAmount, rotationMatrix);
moveAmount /= (ActivePrefab.DeformableSprite.Size * Scale);
moveAmount.Y = -moveAmount.Y;
positionalDeformation.Deform(trigger.WorldPosition, moveAmount, deltaTime, Matrix.Invert(matrix) *
Matrix.CreateScale(1.0f / ActivePrefab.DeformableSprite.Size.X, 1.0f / ActivePrefab.DeformableSprite.Size.Y, 1));
}
}
}
public void ClientRead(NetBuffer msg)
{
for (int i = 0; i < Triggers.Count; i++)
{
if (!Triggers[i].UseNetworkSyncing) continue;
Triggers[i].ClientRead(msg);
}
}
partial void RemoveProjSpecific()
{
for (int i = 0; i < Sounds.Length; i++)
{
SoundChannels[i]?.Dispose();
SoundChannels[i] = null;
}
if (LightSources != null)
{
for (int i = 0; i < LightSources.Length; i++)
{
LightSources[i].Remove();
}
LightSources = null;
}
}
}
}
@@ -0,0 +1,174 @@
using Barotrauma.Networking;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
partial class LevelObjectManager
{
private List<LevelObject> visibleObjectsBack = new List<LevelObject>();
private List<LevelObject> visibleObjectsFront = new List<LevelObject>();
private Rectangle currentGridIndices;
partial void UpdateProjSpecific(float deltaTime)
{
foreach (LevelObject obj in visibleObjectsBack)
{
obj.Update(deltaTime);
}
foreach (LevelObject obj in visibleObjectsFront)
{
obj.Update(deltaTime);
}
}
public IEnumerable<LevelObject> GetVisibleObjects()
{
return visibleObjectsBack.Union(visibleObjectsFront);
}
/// <summary>
/// Checks which level objects are in camera view and adds them to the visibleObjects lists
/// </summary>
private void RefreshVisibleObjects(Rectangle currentIndices)
{
visibleObjectsBack.Clear();
visibleObjectsFront.Clear();
for (int x = currentIndices.X; x <= currentIndices.Width; x++)
{
for (int y = currentIndices.Y; y <= currentIndices.Height; y++)
{
if (objectGrid[x, y] == null) continue;
foreach (LevelObject obj in objectGrid[x, y])
{
var objectList = obj.Position.Z >= 0 ? visibleObjectsBack : visibleObjectsFront;
int drawOrderIndex = 0;
for (int i = 0; i < objectList.Count; i++)
{
if (objectList[i] == obj)
{
drawOrderIndex = -1;
break;
}
if (objectList[i].Position.Z < obj.Position.Z)
{
break;
}
else
{
drawOrderIndex = i + 1;
}
}
if (drawOrderIndex >= 0)
{
objectList.Insert(drawOrderIndex, obj);
}
}
}
}
currentGridIndices = currentIndices;
}
public void DrawObjects(SpriteBatch spriteBatch, Camera cam, bool drawFront, bool specular = false)
{
Rectangle indices = Rectangle.Empty;
indices.X = (int)Math.Floor(cam.WorldView.X / (float)GridSize);
if (indices.X >= objectGrid.GetLength(0)) return;
indices.Y = (int)Math.Floor((cam.WorldView.Y - cam.WorldView.Height - Level.Loaded.BottomPos) / (float)GridSize);
if (indices.Y >= objectGrid.GetLength(1)) return;
indices.Width = (int)Math.Floor(cam.WorldView.Right / (float)GridSize) + 1;
if (indices.Width < 0) return;
indices.Height = (int)Math.Floor((cam.WorldView.Y - Level.Loaded.BottomPos) / (float)GridSize) + 1;
if (indices.Height < 0) return;
indices.X = Math.Max(indices.X, 0);
indices.Y = Math.Max(indices.Y, 0);
indices.Width = Math.Min(indices.Width, objectGrid.GetLength(0) - 1);
indices.Height = Math.Min(indices.Height, objectGrid.GetLength(1) - 1);
float z = 0.0f;
if (currentGridIndices != indices)
{
RefreshVisibleObjects(indices);
}
var objectList = drawFront ? visibleObjectsFront : visibleObjectsBack;
foreach (LevelObject obj in objectList)
{
Vector2 camDiff = new Vector2(obj.Position.X, obj.Position.Y) - cam.WorldViewCenter;
camDiff.Y = -camDiff.Y;
Sprite activeSprite = specular ? obj.ActivePrefab.SpecularSprite : obj.ActivePrefab.Sprite;
activeSprite?.Draw(
spriteBatch,
new Vector2(obj.Position.X, -obj.Position.Y) - camDiff * obj.Position.Z / 10000.0f,
Color.Lerp(Color.White, Level.Loaded.BackgroundTextureColor, obj.Position.Z / 5000.0f),
activeSprite.Origin,
obj.CurrentRotation,
obj.CurrentScale,
SpriteEffects.None,
z);
if (specular) continue;
if (obj.ActivePrefab.DeformableSprite != null)
{
if (obj.CurrentSpriteDeformation != null)
{
obj.ActivePrefab.DeformableSprite.Deform(obj.CurrentSpriteDeformation);
}
else
{
obj.ActivePrefab.DeformableSprite.Reset();
}
obj.ActivePrefab.DeformableSprite?.Draw(cam,
new Vector3(new Vector2(obj.Position.X, obj.Position.Y) - camDiff * obj.Position.Z / 10000.0f, z * 10.0f),
obj.ActivePrefab.DeformableSprite.Origin,
obj.CurrentRotation,
obj.CurrentScale,
Color.Lerp(Color.White, Level.Loaded.BackgroundTextureColor, obj.Position.Z / 5000.0f));
}
if (GameMain.DebugDraw)
{
GUI.DrawRectangle(spriteBatch, new Vector2(obj.Position.X, -obj.Position.Y), new Vector2(10.0f, 10.0f), Color.Red, true);
foreach (LevelTrigger trigger in obj.Triggers)
{
if (trigger.PhysicsBody == null) continue;
GUI.DrawLine(spriteBatch, new Vector2(obj.Position.X, -obj.Position.Y), new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y), Color.Cyan, 0, 3);
Vector2 flowForce = trigger.GetWaterFlowVelocity();
if (flowForce.LengthSquared() > 1)
{
flowForce.Y = -flowForce.Y;
GUI.DrawLine(spriteBatch, new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y), new Vector2(trigger.WorldPosition.X, -trigger.WorldPosition.Y) + flowForce * 10, Color.Orange, 0, 5);
}
trigger.PhysicsBody.UpdateDrawPosition();
trigger.PhysicsBody.DebugDraw(spriteBatch, trigger.IsTriggered ? Color.Cyan : Color.DarkCyan);
}
}
z += 0.0001f;
}
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
int objIndex = msg.ReadRangedInteger(0, objects.Count);
objects[objIndex].ClientRead(msg);
}
}
}
@@ -0,0 +1,180 @@
using Barotrauma.Lights;
using Barotrauma.Particles;
using Barotrauma.SpriteDeformations;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Linq;
namespace Barotrauma
{
partial class LevelObjectPrefab
{
public class SoundConfig
{
public readonly XElement SoundElement;
public readonly Vector2 Position;
public readonly int TriggerIndex;
public SoundConfig(XElement element, int triggerIndex)
{
SoundElement = element;
Position = element.GetAttributeVector2("position", Vector2.Zero);
TriggerIndex = triggerIndex;
}
}
public List<int> ParticleEmitterTriggerIndex
{
get;
private set;
}
public List<ParticleEmitterPrefab> ParticleEmitterPrefabs
{
get;
private set;
}
public List<Vector2> EmitterPositions
{
get;
private set;
}
public List<SoundConfig> Sounds
{
get;
private set;
} = new List<SoundConfig>();
public List<int> LightSourceTriggerIndex
{
get;
private set;
} = new List<int>();
public List<LightSourceParams> LightSourceParams
{
get;
private set;
} = new List<Lights.LightSourceParams>();
/// <summary>
/// Only used for editing sprite deformation parameters. The actual LevelObjects use separate SpriteDeformation instances.
/// </summary>
public List<SpriteDeformation> SpriteDeformations
{
get;
private set;
} = new List<SpriteDeformation>();
partial void InitProjSpecific(XElement element)
{
LoadElementsProjSpecific(element, -1);
}
private void LoadElementsProjSpecific(XElement element, int parentTriggerIndex)
{
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "leveltrigger":
case "trigger":
LoadElementsProjSpecific(subElement, LevelTriggerElements.IndexOf(subElement));
break;
case "lightsource":
LightSourceTriggerIndex.Add(parentTriggerIndex);
LightSourceParams.Add(new LightSourceParams(subElement));
break;
case "particleemitter":
if (ParticleEmitterPrefabs == null)
{
ParticleEmitterPrefabs = new List<ParticleEmitterPrefab>();
EmitterPositions = new List<Vector2>();
ParticleEmitterTriggerIndex = new List<int>();
}
ParticleEmitterPrefabs.Add(new ParticleEmitterPrefab(subElement));
ParticleEmitterTriggerIndex.Add(parentTriggerIndex);
EmitterPositions.Add(subElement.GetAttributeVector2("position", Vector2.Zero));
break;
case "sound":
Sounds.Add(new SoundConfig(subElement, parentTriggerIndex));
break;
case "deformablesprite":
foreach (XElement deformElement in subElement.Elements())
{
var deformation = SpriteDeformation.Load(deformElement, Name);
if (deformation != null)
{
SpriteDeformations.Add(deformation);
}
}
break;
}
}
}
public void Save(XElement element)
{
this.Config = element;
SerializableProperty.SerializeProperties(this, element);
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "childobject":
case "lightsource":
subElement.Remove();
break;
case "deformablesprite":
subElement.RemoveNodes();
foreach (SpriteDeformation deformation in SpriteDeformations)
{
var deformationElement = new XElement("SpriteDeformation");
deformation.Save(deformationElement);
subElement.Add(deformationElement);
}
break;
}
}
foreach (LightSourceParams lightSourceParams in LightSourceParams)
{
var lightElement = new XElement("LightSource");
SerializableProperty.SerializeProperties(lightSourceParams, lightElement);
element.Add(lightElement);
}
foreach (ChildObject childObj in ChildObjects)
{
element.Add(new XElement("ChildObject",
new XAttribute("names", string.Join(", ", childObj.AllowedNames)),
new XAttribute("mincount", childObj.MinCount),
new XAttribute("maxcount", childObj.MaxCount)));
}
foreach (KeyValuePair<string, float> overrideCommonness in OverrideCommonness)
{
bool elementFound = false;
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() == "overridecommonness"
&& subElement.GetAttributeString("leveltype", "") == overrideCommonness.Key)
{
subElement.Attribute("commonness").Value = overrideCommonness.Value.ToString("G", CultureInfo.InvariantCulture);
elementFound = true;
break;
}
}
if (!elementFound)
{
element.Add(new XElement("overridecommonness",
new XAttribute("leveltype", overrideCommonness.Key),
new XAttribute("commonness", overrideCommonness.Value.ToString("G", CultureInfo.InvariantCulture))));
}
}
}
}
}
@@ -0,0 +1,19 @@
using Lidgren.Network;
namespace Barotrauma
{
partial class LevelTrigger
{
public void ClientRead(NetBuffer msg)
{
if (ForceFluctuationStrength > 0.0f)
{
currentForceFluctuation = msg.ReadRangedSingle(0.0f, 1.0f, 8);
}
if (stayTriggeredDelay > 0.0f)
{
triggeredTimer = msg.ReadRangedSingle(0.0f, stayTriggeredDelay, 16);
}
}
}
}
@@ -1,3 +1,4 @@
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
@@ -10,41 +11,21 @@ namespace Barotrauma
{
private static BasicEffect wallEdgeEffect, wallCenterEffect;
private static Sprite background, backgroundTop;
private static Sprite dustParticles;
private static Texture2D shaftTexture;
private Vector2 dustOffset;
private Vector2 defaultDustVelocity;
private Vector2 dustVelocity;
Vector2 dustOffset;
private RasterizerState cullNone;
private Level level;
private VertexBuffer wallVertices, bodyVertices;
public static Sprite Background
{
get
{
if (background == null) background = new Sprite("Content/Map/background2.png", Vector2.Zero);
return background;
}
}
public static Sprite BackgroundTop
{
get
{
if (backgroundTop == null) backgroundTop = new Sprite("Content/Map/background.png", Vector2.Zero);
return backgroundTop;
}
}
public LevelRenderer(Level level)
{
if (shaftTexture == null) shaftTexture = TextureLoader.FromFile("Content/Map/iceWall.png");
defaultDustVelocity = Vector2.UnitY * 10.0f;
if (background == null) background = new Sprite("Content/Map/background2.png", Vector2.Zero);
if (backgroundTop == null) backgroundTop = new Sprite("Content/Map/background.png", Vector2.Zero);
if (dustParticles == null) dustParticles = new Sprite("Content/Map/dustparticles.png", Vector2.Zero);
cullNone = new RasterizerState() { CullMode = CullMode.None };
if (wallEdgeEffect == null)
{
@@ -53,7 +34,7 @@ namespace Barotrauma
DiffuseColor = new Vector3(0.8f, 0.8f, 0.8f),
VertexColorEnabled = true,
TextureEnabled = true,
Texture = shaftTexture
Texture = level.GenerationParams.WallEdgeSprite.Texture
};
wallEdgeEffect.CurrentTechnique = wallEdgeEffect.Techniques["BasicEffect_Texture"];
}
@@ -64,18 +45,56 @@ namespace Barotrauma
{
VertexColorEnabled = true,
TextureEnabled = true,
Texture = backgroundTop.Texture
Texture = level.GenerationParams.WallSprite.Texture
};
wallCenterEffect.CurrentTechnique = wallCenterEffect.Techniques["BasicEffect_Texture"];
}
this.level = level;
}
public void Update(float deltaTime)
public void ReloadTextures()
{
dustOffset -= Vector2.UnitY * 10.0f * deltaTime;
while (dustOffset.Y <= -2048.0f) dustOffset.Y += 2048.0f;
level.GenerationParams.WallEdgeSprite.ReloadTexture();
wallEdgeEffect.Texture = level.GenerationParams.WallEdgeSprite.Texture;
level.GenerationParams.WallSprite.ReloadTexture();
wallCenterEffect.Texture = level.GenerationParams.WallSprite.Texture;
}
public void Update(float deltaTime, Camera cam)
{
//calculate the sum of the forces of nearby level triggers
//and use it to move the dust texture and water distortion effect
Vector2 currentDustVel = defaultDustVelocity;
foreach (LevelObject levelObject in level.LevelObjectManager.GetVisibleObjects())
{
//use the largest water flow velocity of all the triggers
Vector2 objectMaxFlow = Vector2.Zero;
foreach (LevelTrigger trigger in levelObject.Triggers)
{
Vector2 vel = trigger.GetWaterFlowVelocity(cam.WorldViewCenter);
if (vel.LengthSquared() > objectMaxFlow.LengthSquared())
{
objectMaxFlow = vel;
}
}
currentDustVel += objectMaxFlow;
}
dustVelocity = Vector2.Lerp(dustVelocity, currentDustVel, deltaTime);
WaterRenderer.Instance?.ScrollWater(dustVelocity, deltaTime);
if (level.GenerationParams.WaterParticles != null)
{
Vector2 waterTextureSize = level.GenerationParams.WaterParticles.size * level.GenerationParams.WaterParticleScale;
dustOffset += new Vector2(dustVelocity.X, -dustVelocity.Y) * level.GenerationParams.WaterParticleScale * deltaTime;
while (dustOffset.X <= -waterTextureSize.X) dustOffset.X += waterTextureSize.X;
while (dustOffset.X >= waterTextureSize.X) dustOffset.X -= waterTextureSize.X;
while (dustOffset.Y <= -waterTextureSize.Y) dustOffset.Y += waterTextureSize.Y;
while (dustOffset.Y >= waterTextureSize.Y) dustOffset.Y -= waterTextureSize.Y;
}
}
public static VertexPositionColorTexture[] GetColoredVertices(VertexPositionTexture[] vertices, Color color)
@@ -113,7 +132,7 @@ namespace Barotrauma
}
public void DrawBackground(SpriteBatch spriteBatch, Camera cam,
BackgroundSpriteManager backgroundSpriteManager = null,
LevelObjectManager backgroundSpriteManager = null,
BackgroundCreatureManager backgroundCreatureManager = null)
{
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap);
@@ -123,21 +142,24 @@ namespace Barotrauma
backgroundPos.Y = -backgroundPos.Y;
backgroundPos *= 0.05f;
if (backgroundPos.Y < 1024)
{
if (backgroundPos.Y < 0)
if (backgroundPos.Y < 0 && level.GenerationParams.BackgroundTopSprite != null)
{
var backgroundTop = level.GenerationParams.BackgroundTopSprite;
backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024));
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
color: level.BackgroundColor);
color: level.BackgroundTextureColor);
}
if (backgroundPos.Y > -1024)
if (backgroundPos.Y > -1024 && level.GenerationParams.BackgroundSprite != null)
{
var background = level.GenerationParams.BackgroundSprite;
background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024);
background.DrawTiled(spriteBatch,
(backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
new Vector2(GameMain.GraphicsWidth, (int)Math.Ceiling(1024 - backgroundPos.Y)),
color: level.BackgroundColor);
color: level.BackgroundTextureColor);
}
}
@@ -145,129 +167,151 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
SamplerState.LinearWrap, DepthStencilState.Default, null, null,
cam.Transform);
SamplerState.LinearWrap, DepthStencilState.DepthRead, null, null,
cam.Transform);
if (backgroundSpriteManager != null) backgroundSpriteManager.DrawSprites(spriteBatch, cam);
if (backgroundCreatureManager != null) backgroundCreatureManager.Draw(spriteBatch);
if (backgroundSpriteManager != null) backgroundSpriteManager.DrawObjects(spriteBatch, cam, drawFront: false);
if (backgroundCreatureManager != null) backgroundCreatureManager.Draw(spriteBatch, cam);
Rectangle srcRect = new Rectangle(0, 0, 2048, 2048);
Vector2 origin = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
Vector2 offset = -origin + dustOffset;
while (offset.X <= -srcRect.Width) offset.X += srcRect.Width;
while (offset.X > 0.0f) offset.X -= srcRect.Width;
while (offset.Y <= -srcRect.Height) offset.Y += srcRect.Height;
while (offset.Y > 0.0f) offset.Y -= srcRect.Height;
for (int i = 0; i < 4; i++)
if (level.GenerationParams.WaterParticles != null)
{
float scale = 1.0f - i * 0.2f;
float recipScale = 1.0f / scale;
float textureScale = level.GenerationParams.WaterParticleScale;
//alpha goes from 1.0 to 0.0 when scale is in the range of 0.5-0.25
float alpha = (cam.Zoom * scale) < 0.5f ? (cam.Zoom * scale - 0.25f) * 40.0f : 1.0f;
if (alpha <= 0.0f) continue;
Rectangle srcRect = new Rectangle(0, 0, 2048, 2048);
Vector2 origin = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
Vector2 offset = -origin + dustOffset;
while (offset.X <= -srcRect.Width * textureScale) offset.X += srcRect.Width * textureScale;
while (offset.X > 0.0f) offset.X -= srcRect.Width * textureScale;
while (offset.Y <= -srcRect.Height * textureScale) offset.Y += srcRect.Height * textureScale;
while (offset.Y > 0.0f) offset.Y -= srcRect.Height * textureScale;
for (int i = 0; i < 4; i++)
{
float scale = (1.0f - i * 0.2f);
Vector2 offsetS = offset * scale + new Vector2(cam.WorldView.Width, cam.WorldView.Height) * (1.0f - scale) * 0.5f - new Vector2(256.0f * i);
while (offsetS.X <= -srcRect.Width * scale) offsetS.X += srcRect.Width * scale;
while (offsetS.X > 0.0f) offsetS.X -= srcRect.Width * scale;
while (offsetS.Y <= -srcRect.Height * scale) offsetS.Y += srcRect.Height * scale;
while (offsetS.Y > 0.0f) offsetS.Y -= srcRect.Height * scale;
//alpha goes from 1.0 to 0.0 when scale is in the range of 0.1 - 0.05
float alpha = (cam.Zoom * scale) < 0.1f ? (cam.Zoom * scale - 0.05f) * 20.0f : 1.0f;
if (alpha <= 0.0f) continue;
dustParticles.DrawTiled(spriteBatch, origin + offsetS, new Vector2(cam.WorldView.Width - offsetS.X, cam.WorldView.Height - offsetS.Y),
rect: srcRect, color: Color.White * alpha, textureScale: new Vector2(scale));
Vector2 offsetS = offset * scale
+ new Vector2(cam.WorldView.Width, cam.WorldView.Height) * (1.0f - scale) * 0.5f
- new Vector2(256.0f * i);
float texScale = scale * textureScale;
while (offsetS.X <= -srcRect.Width * texScale) offsetS.X += srcRect.Width * texScale;
while (offsetS.X > 0.0f) offsetS.X -= srcRect.Width * texScale;
while (offsetS.Y <= -srcRect.Height * texScale) offsetS.Y += srcRect.Height * texScale;
while (offsetS.Y > 0.0f) offsetS.Y -= srcRect.Height * texScale;
level.GenerationParams.WaterParticles.DrawTiled(
spriteBatch, origin + offsetS,
new Vector2(cam.WorldView.Width - offsetS.X, cam.WorldView.Height - offsetS.Y),
rect: srcRect, color: Color.White * alpha, textureScale: new Vector2(texScale));
}
}
spriteBatch.End();
RenderWalls(GameMain.Instance.GraphicsDevice, cam);
RenderWalls(GameMain.Instance.GraphicsDevice, cam, specular: false);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
SamplerState.LinearClamp, DepthStencilState.Default, null, null,
cam.Transform);
if (backgroundSpriteManager != null) backgroundSpriteManager.DrawObjects(spriteBatch, cam, drawFront: true);
spriteBatch.End();
}
public void Draw(SpriteBatch spriteBatch)
public void Draw(SpriteBatch spriteBatch, Camera cam)
{
if (GameMain.DebugDraw)
if (GameMain.DebugDraw && cam.Zoom > 0.05f)
{
var cells = level.GetCells(GameMain.GameScreen.Cam.WorldViewCenter, 2);
var cells = level.GetCells(cam.WorldViewCenter, 2);
foreach (VoronoiCell cell in cells)
{
GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y-10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);
GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y - 10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);
GUI.DrawLine(spriteBatch,
new Vector2(cell.edges[0].point1.X, -cell.edges[0].point1.Y),
new Vector2(cell.Center.X, -cell.Center.Y),
Color.Blue*0.5f);
foreach (GraphEdge edge in cell.edges)
GUI.DrawLine(spriteBatch,
new Vector2(cell.Edges[0].Point1.X + cell.Translation.X, -(cell.Edges[0].Point1.Y + cell.Translation.Y)),
new Vector2(cell.Center.X, -(cell.Center.Y)),
Color.Blue * 0.5f);
foreach (GraphEdge edge in cell.Edges)
{
GUI.DrawLine(spriteBatch, new Vector2(edge.point1.X, -edge.point1.Y),
new Vector2(edge.point2.X, -edge.point2.Y), cell.body==null ? Color.Cyan*0.5f : Color.White);
GUI.DrawLine(spriteBatch, new Vector2(edge.Point1.X + cell.Translation.X, -(edge.Point1.Y + cell.Translation.Y)),
new Vector2(edge.Point2.X + cell.Translation.X, -(edge.Point2.Y + cell.Translation.Y)), cell.Body == null ? Color.Cyan * 0.5f : Color.White);
}
foreach (Vector2 point in cell.bodyVertices)
foreach (Vector2 point in cell.BodyVertices)
{
GUI.DrawRectangle(spriteBatch, new Vector2(point.X, -point.Y), new Vector2(10.0f, 10.0f), Color.White, true);
GUI.DrawRectangle(spriteBatch, new Vector2(point.X + cell.Translation.X, -(point.Y + cell.Translation.Y)), new Vector2(10.0f, 10.0f), Color.White, true);
}
}
foreach (List<Vector2> nodeList in level.SmallTunnels)
foreach (List<Point> nodeList in level.SmallTunnels)
{
for (int i = 1; i<nodeList.Count; i++)
for (int i = 1; i < nodeList.Count; i++)
{
GUI.DrawLine(spriteBatch,
new Vector2(nodeList[i-1].X, -nodeList[i - 1].Y),
new Vector2(nodeList[i].X, -nodeList[i].Y),
GUI.DrawLine(spriteBatch,
new Vector2(nodeList[i - 1].X, -nodeList[i - 1].Y),
new Vector2(nodeList[i].X, -nodeList[i].Y),
Color.Lerp(Color.Yellow, Color.Red, i / (float)nodeList.Count), 0, 10);
}
}
foreach (var ruin in level.Ruins)
{
ruin.DebugDraw(spriteBatch);
}
}
Vector2 pos = new Vector2(0.0f, -level.Size.Y);
if (GameMain.GameScreen.Cam.WorldView.Y >= -pos.Y - 1024)
if (cam.WorldView.Y >= -pos.Y - 1024)
{
pos.X = GameMain.GameScreen.Cam.WorldView.X -1024;
int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 1024 + 4.0f) * 1024);
pos.X = cam.WorldView.X -1024;
int width = (int)(Math.Ceiling(cam.WorldView.Width / 1024 + 4.0f) * 1024);
GUI.DrawRectangle(spriteBatch,new Rectangle(
(int)(MathUtils.Round(pos.X, 1024)),
-GameMain.GameScreen.Cam.WorldView.Y,
-cam.WorldView.Y,
width,
(int)(GameMain.GameScreen.Cam.WorldView.Y + pos.Y) - 30),
(int)(cam.WorldView.Y + pos.Y) - 30),
Color.Black, true);
spriteBatch.Draw(shaftTexture,
spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)pos.Y-1000, width, 1024),
new Rectangle(0, 0, width, -1024),
level.BackgroundColor, 0.0f,
level.BackgroundTextureColor, 0.0f,
Vector2.Zero,
SpriteEffects.None, 0.0f);
}
if (GameMain.GameScreen.Cam.WorldView.Y - GameMain.GameScreen.Cam.WorldView.Height < level.SeaFloorTopPos + 1024)
if (cam.WorldView.Y - cam.WorldView.Height < level.SeaFloorTopPos + 1024)
{
pos = new Vector2(GameMain.GameScreen.Cam.WorldView.X - 1024, -level.BottomPos);
pos = new Vector2(cam.WorldView.X - 1024, -level.BottomPos);
int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 1024 + 4.0f) * 1024);
int width = (int)(Math.Ceiling(cam.WorldView.Width / 1024 + 4.0f) * 1024);
GUI.DrawRectangle(spriteBatch, new Rectangle(
(int)(MathUtils.Round(pos.X, 1024)),
(int)-(level.BottomPos - 30),
width,
(int)(level.BottomPos - (GameMain.GameScreen.Cam.WorldView.Y - GameMain.GameScreen.Cam.WorldView.Height))),
(int)(level.BottomPos - (cam.WorldView.Y - cam.WorldView.Height))),
Color.Black, true);
spriteBatch.Draw(shaftTexture,
spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)-level.BottomPos, width, 1024),
new Rectangle(0, 0, width, -1024),
level.BackgroundColor, 0.0f,
level.BackgroundTextureColor, 0.0f,
Vector2.Zero,
SpriteEffects.FlipVertically, 0.0f);
}
}
public void RenderWalls(GraphicsDevice graphicsDevice, Camera cam)
public void RenderWalls(GraphicsDevice graphicsDevice, Camera cam, bool specular)
{
if (wallVertices == null) return;
@@ -276,9 +320,11 @@ namespace Barotrauma
if (!renderLevel && !renderSeaFloor) return;
wallEdgeEffect.World = cam.ShaderTransform
Matrix transformMatrix = cam.ShaderTransform
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 100) * 0.5f;
wallCenterEffect.World = wallEdgeEffect.World;
wallEdgeEffect.World = transformMatrix;
wallCenterEffect.World = transformMatrix;
graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
wallCenterEffect.CurrentTechnique.Passes[0].Apply();
@@ -288,15 +334,19 @@ namespace Barotrauma
graphicsDevice.SetVertexBuffer(bodyVertices);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(bodyVertices.VertexCount / 3.0f));
}
if (renderSeaFloor)
foreach (LevelWall wall in level.ExtraWalls)
{
foreach (LevelWall wall in level.ExtraWalls)
{
graphicsDevice.SetVertexBuffer(wall.BodyVertices);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.BodyVertices.VertexCount / 3.0f));
}
if (!renderSeaFloor && wall == level.SeaFloor) continue;
wallCenterEffect.World = wall.GetTransform() * transformMatrix;
wallCenterEffect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.SetVertexBuffer(wall.BodyVertices);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.BodyVertices.VertexCount / 3.0f));
}
var defaultRasterizerState = graphicsDevice.RasterizerState;
graphicsDevice.RasterizerState = cullNone;
wallEdgeEffect.World = transformMatrix;
wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
if (renderLevel)
@@ -305,28 +355,27 @@ namespace Barotrauma
graphicsDevice.SetVertexBuffer(wallVertices);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wallVertices.VertexCount / 3.0f));
}
if (renderSeaFloor)
foreach (LevelWall wall in level.ExtraWalls)
{
foreach (LevelWall wall in level.ExtraWalls)
{
graphicsDevice.SetVertexBuffer(wall.WallVertices);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallVertices.VertexCount / 3.0f));
}
}
if (!renderSeaFloor && wall == level.SeaFloor) continue;
wallEdgeEffect.World = wall.GetTransform() * transformMatrix;
wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.SetVertexBuffer(wall.WallVertices);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallVertices.VertexCount / 3.0f));
}
graphicsDevice.RasterizerState = defaultRasterizerState;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (wallVertices!=null) wallVertices.Dispose();
if (wallVertices != null) wallVertices.Dispose();
if (bodyVertices != null) bodyVertices.Dispose();
}
}
}
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
@@ -18,6 +19,14 @@ namespace Barotrauma
get { return bodyVertices; }
}
public Matrix GetTransform()
{
return body.BodyType == FarseerPhysics.Dynamics.BodyType.Static ?
Matrix.Identity :
Matrix.CreateRotationZ(body.Rotation) *
Matrix.CreateTranslation(new Vector3(ConvertUnits.ToDisplayUnits(body.Position), 0.0f));
}
public void SetWallVertices(VertexPositionTexture[] vertices, Color color)
{
wallVertices = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
@@ -5,18 +5,12 @@ namespace Barotrauma.RuinGeneration
{
partial class Ruin
{
public void Draw(SpriteBatch spriteBatch)
public void DebugDraw(SpriteBatch spriteBatch)
{
//foreach (BTRoom room in leaves)
//{
// GUI.DrawRectangle(spriteBatch, room.Rect, Color.White);
//}
//foreach (Corridor corr in corridors)
//{
// GUI.DrawRectangle(spriteBatch, corr.Rect, Color.Blue);
//}
foreach (RuinShape shape in allShapes)
{
GUI.DrawString(spriteBatch, new Vector2(shape.Center.X, -shape.Center.Y - 50), shape.DistanceFromEntrance.ToString(), Color.White, Color.Black * 0.5f, font: GUI.LargeFont);
}
foreach (Line line in walls)
{
GUI.DrawLine(spriteBatch, new Vector2(line.A.X, -line.A.Y), new Vector2(line.B.X, -line.B.Y), Color.Red, 0.0f, 10);
@@ -2,18 +2,58 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Barotrauma
{
struct WaterVertexData
{
float DistortStrengthX;
float DistortStrengthY;
float WaterAlpha;
float WaterColorStrength;
public WaterVertexData(float distortStrengthX, float distortStrengthY, float waterAlpha, float waterColorStrength)
{
DistortStrengthX = distortStrengthX;
DistortStrengthY = distortStrengthY;
WaterAlpha = waterAlpha;
WaterColorStrength = waterColorStrength;
}
public static implicit operator Color(WaterVertexData wd)
{
return new Color(wd.DistortStrengthX, wd.DistortStrengthY, wd.WaterAlpha, wd.WaterColorStrength);
}
}
class WaterRenderer : IDisposable
{
const int DefaultBufferSize = 1500;
public static WaterRenderer Instance;
private Vector2 wavePos;
public const int DefaultBufferSize = 2000;
public const int DefaultIndoorsBufferSize = 3000;
public static Vector2 DistortionScale = new Vector2(0.5f, 0.5f);
public static Vector2 DistortionStrength = new Vector2(0.5f, 0.5f);
public static float BlurAmount = 0.0f;
public Vector2 WavePos
{
get;
private set;
}
public readonly Color waterColor = new Color(0.75f * 0.5f, 0.8f * 0.5f, 0.9f * 0.5f, 1.0f);
public readonly WaterVertexData IndoorsWaterColor = new WaterVertexData(0.1f, 0.1f, 0.5f, 1.0f);
public readonly WaterVertexData IndoorsSurfaceTopColor = new WaterVertexData(0.5f, 0.5f, 0.0f, 1.0f);
public readonly WaterVertexData IndoorsSurfaceBottomColor = new WaterVertexData(0.2f, 0.1f, 0.9f, 1.0f);
public VertexPositionTexture[] vertices = new VertexPositionTexture[DefaultBufferSize];
public Dictionary<EntityGrid, VertexPositionColorTexture[]> IndoorsVertices = new Dictionary<EntityGrid, VertexPositionColorTexture[]>();// VertexPositionColorTexture[DefaultBufferSize * 2];
public Effect waterEffect
public Effect WaterEffect
{
get;
private set;
@@ -21,29 +61,23 @@ namespace Barotrauma
private BasicEffect basicEffect;
public int PositionInBuffer = 0;
public Dictionary<EntityGrid, int> PositionInIndoorsBuffer = new Dictionary<EntityGrid, int>();
private Texture2D waterTexture;
public Texture2D WaterTexture
{
get { return waterTexture; }
}
public Texture2D WaterTexture { get; }
public WaterRenderer(GraphicsDevice graphicsDevice, ContentManager content)
{
#if WINDOWS
waterEffect = content.Load<Effect>("watershader");
WaterEffect = content.Load<Effect>("Effects/watershader");
#endif
#if LINUX
#if LINUX || OSX
waterEffect = content.Load<Effect>("watershader_opengl");
WaterEffect = content.Load<Effect>("Effects/watershader_opengl");
#endif
waterTexture = TextureLoader.FromFile("Content/waterbump.png");
waterEffect.Parameters["xWaveWidth"].SetValue(0.05f);
waterEffect.Parameters["xWaveHeight"].SetValue(0.05f);
waterEffect.Parameters["xWaterBumpMap"].SetValue(waterTexture);
WaterTexture = TextureLoader.FromFile("Content/Effects/waterbump.png");
WaterEffect.Parameters["xWaterBumpMap"].SetValue(WaterTexture);
WaterEffect.Parameters["waterColor"].SetValue(waterColor.ToVector4());
if (basicEffect == null)
{
@@ -54,46 +88,122 @@ namespace Barotrauma
}
}
public void RenderBack(SpriteBatch spriteBatch, RenderTarget2D texture, float blurAmount = 0.0f)
public void RenderWater(SpriteBatch spriteBatch, RenderTarget2D texture, Camera cam)
{
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.LinearWrap, null, null, waterEffect);
waterEffect.CurrentTechnique = waterEffect.Techniques["WaterShader"];
waterEffect.Parameters["xWavePos"].SetValue(wavePos);
waterEffect.Parameters["xBlurDistance"].SetValue(blurAmount);
//waterEffect.CurrentTechnique.Passes[0].Apply();
spriteBatch.GraphicsDevice.BlendState = BlendState.AlphaBlend;
//#if WINDOWS
waterEffect.Parameters["xTexture"].SetValue(texture);
spriteBatch.Draw(texture, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
//#elif LINUX
WaterEffect.Parameters["xTexture"].SetValue(texture);
Vector2 distortionStrength = cam == null ? DistortionStrength : DistortionStrength * cam.Zoom;
WaterEffect.Parameters["xWaveWidth"].SetValue(DistortionStrength.X);
WaterEffect.Parameters["xWaveHeight"].SetValue(DistortionStrength.Y);
if (BlurAmount > 0.0f)
{
WaterEffect.CurrentTechnique = WaterEffect.Techniques["WaterShaderBlurred"];
WaterEffect.Parameters["xBlurDistance"].SetValue(BlurAmount / 100.0f);
}
else
{ WaterEffect.CurrentTechnique = WaterEffect.Techniques["WaterShader"];
WaterEffect.Parameters["xBlurDistance"].SetValue(BlurAmount / 100.0f);
}
// spriteBatch.Draw(texture, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
//#endif
spriteBatch.End();
Vector2 offset = WavePos;
if (cam != null)
{
offset += (cam.Position - new Vector2(cam.WorldView.Width / 2.0f, -cam.WorldView.Height / 2.0f));
offset.Y += cam.WorldView.Height;
offset.X += cam.WorldView.Width;
offset *= DistortionScale;
}
offset.Y = -offset.Y;
WaterEffect.Parameters["xUvOffset"].SetValue(new Vector2((offset.X / GameMain.GraphicsWidth) % 1.0f, (offset.Y / GameMain.GraphicsHeight) % 1.0f));
WaterEffect.Parameters["xBumpPos"].SetValue(Vector2.Zero);
if (cam != null)
{
WaterEffect.Parameters["xBumpScale"].SetValue(new Vector2(
(float)cam.WorldView.Width / GameMain.GraphicsWidth * DistortionScale.X,
(float)cam.WorldView.Height / GameMain.GraphicsHeight * DistortionScale.Y));
WaterEffect.Parameters["xTransform"].SetValue(cam.ShaderTransform
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f);
WaterEffect.Parameters["xUvTransform"].SetValue(cam.ShaderTransform
* Matrix.CreateOrthographicOffCenter(0, spriteBatch.GraphicsDevice.Viewport.Width * 2, spriteBatch.GraphicsDevice.Viewport.Height * 2, 0, 0, 1) * Matrix.CreateTranslation(0.5f, 0.5f, 0.0f));
}
else
{
WaterEffect.Parameters["xBumpScale"].SetValue(new Vector2(1.0f, 1.0f));
WaterEffect.Parameters["xTransform"].SetValue(Matrix.Identity * Matrix.CreateTranslation(-1.0f, 1.0f, 0.0f));
WaterEffect.Parameters["xUvTransform"].SetValue(Matrix.CreateScale(0.5f, -0.5f, 0.0f));
}
WaterEffect.CurrentTechnique.Passes[0].Apply();
VertexPositionColorTexture[] verts = new VertexPositionColorTexture[6];
Rectangle view = cam != null ? cam.WorldView : spriteBatch.GraphicsDevice.Viewport.Bounds;
var corners = new Vector3[4];
corners[0] = new Vector3(view.X, view.Y, 0.1f);
corners[1] = new Vector3(view.Right, view.Y, 0.1f);
corners[2] = new Vector3(view.Right, view.Y - view.Height, 0.1f);
corners[3] = new Vector3(view.X, view.Y - view.Height, 0.1f);
WaterVertexData backGroundColor = new WaterVertexData(0.1f, 0.1f, 0.5f, 0.1f);
verts[0] = new VertexPositionColorTexture(corners[0], backGroundColor, Vector2.Zero);
verts[1] = new VertexPositionColorTexture(corners[1], backGroundColor, Vector2.Zero);
verts[2] = new VertexPositionColorTexture(corners[2], backGroundColor, Vector2.Zero);
verts[3] = new VertexPositionColorTexture(corners[0], backGroundColor, Vector2.Zero);
verts[4] = new VertexPositionColorTexture(corners[2], backGroundColor, Vector2.Zero);
verts[5] = new VertexPositionColorTexture(corners[3], backGroundColor, Vector2.Zero);
spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, 2);
foreach (KeyValuePair<EntityGrid, VertexPositionColorTexture[]> subVerts in IndoorsVertices)
{
if (!PositionInIndoorsBuffer.ContainsKey(subVerts.Key) || PositionInIndoorsBuffer[subVerts.Key] == 0) continue;
offset = WavePos;
if (subVerts.Key.Submarine != null) { offset -= subVerts.Key.Submarine.WorldPosition; }
if (cam != null)
{
offset += cam.Position - new Vector2(cam.WorldView.Width / 2.0f, -cam.WorldView.Height / 2.0f);
offset.Y += cam.WorldView.Height;
offset.X += cam.WorldView.Width;
offset *= DistortionScale;
}
offset.Y = -offset.Y;
WaterEffect.Parameters["xUvOffset"].SetValue(new Vector2((offset.X / GameMain.GraphicsWidth) % 1.0f, (offset.Y / GameMain.GraphicsHeight) % 1.0f));
WaterEffect.CurrentTechnique.Passes[0].Apply();
spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, subVerts.Value, 0, PositionInIndoorsBuffer[subVerts.Key] / 3);
}
}
public void ScrollWater(float deltaTime)
public void ScrollWater(Vector2 vel, float deltaTime)
{
wavePos.X += 0.006f * deltaTime;
wavePos.Y += 0.006f * deltaTime;
WavePos = WavePos - vel * deltaTime;
}
public void Render(GraphicsDevice graphicsDevice, Camera cam, RenderTarget2D texture, Matrix transform)
public void RenderAir(GraphicsDevice graphicsDevice, Camera cam, RenderTarget2D texture, Matrix transform)
{
if (vertices == null) return;
if (vertices.Length < 0) return;
if (vertices == null || vertices.Length < 0 || PositionInBuffer <= 0) return;
basicEffect.Texture = texture;
basicEffect.View = Matrix.Identity;
basicEffect.World = transform
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f * Matrix.CreateTranslation(0.0f,0.0f,0f);
basicEffect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.SamplerStates[0] = SamplerState.PointWrap;
graphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3);
graphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, vertices, 0, PositionInBuffer / 3);
}
public void ResetBuffers()
{
PositionInBuffer = 0;
PositionInIndoorsBuffer.Clear();
IndoorsVertices.Clear();
}
public void Dispose()
@@ -106,10 +216,10 @@ namespace Barotrauma
{
if (!disposing) return;
if (waterEffect != null)
if (WaterEffect != null)
{
waterEffect.Dispose();
waterEffect = null;
WaterEffect.Dispose();
WaterEffect = null;
}
if (basicEffect != null)