Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelWall.cs
2019-03-18 20:39:27 +02:00

152 lines
4.7 KiB
C#

using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using Voronoi2;
namespace Barotrauma
{
partial class LevelWall : IDisposable
{
private List<VoronoiCell> cells;
public List<VoronoiCell> Cells
{
get { return cells; }
}
private Body body;
public Body Body
{
get { return body; }
}
private float moveState;
private float moveLength;
private Vector2 moveAmount;
public Vector2 MoveAmount
{
get { return moveAmount; }
set
{
moveAmount = value;
moveLength = moveAmount.Length();
}
}
public float MoveSpeed;
private Vector2? originalPos;
public float MoveState
{
get { return moveState; }
set { moveState = MathHelper.Clamp(value, 0.0f, MathHelper.TwoPi); }
}
public LevelWall(List<Vector2> vertices, Color color, Level level, bool giftWrap = false)
{
if (giftWrap)
{
vertices = MathUtils.GiftWrap(vertices);
}
VoronoiCell wallCell = new VoronoiCell(vertices.ToArray());
for (int i = 0; i < wallCell.Edges.Count; i++)
{
wallCell.Edges[i].Cell1 = wallCell;
wallCell.Edges[i].IsSolid = true;
}
cells = new List<VoronoiCell>() { wallCell };
body = CaveGenerator.GeneratePolygons(cells, level, out List<Vector2[]> triangles);
#if CLIENT
List<VertexPositionTexture> bodyVertices = CaveGenerator.GenerateRenderVerticeList(triangles);
SetBodyVertices(bodyVertices.ToArray(), color);
SetWallVertices(CaveGenerator.GenerateWallShapes(cells, level), color);
#endif
}
public LevelWall(List<Vector2> edgePositions, Vector2 extendAmount, Color color, Level level)
{
cells = new List<VoronoiCell>();
for (int i = 0; i < edgePositions.Count - 1; i++)
{
Vector2[] vertices = new Vector2[4];
vertices[0] = edgePositions[i];
vertices[1] = edgePositions[i + 1];
vertices[2] = vertices[0] + extendAmount;
vertices[3] = vertices[1] + extendAmount;
VoronoiCell wallCell = new VoronoiCell(vertices);
wallCell.CellType = CellType.Edge;
wallCell.Edges[0].Cell1 = wallCell;
wallCell.Edges[1].Cell1 = wallCell;
wallCell.Edges[2].Cell1 = wallCell;
wallCell.Edges[3].Cell1 = wallCell;
wallCell.Edges[0].IsSolid = true;
if (i > 1)
{
wallCell.Edges[3].Cell2 = cells[i - 1];
cells[i - 1].Edges[1].Cell2 = wallCell;
}
cells.Add(wallCell);
}
body = CaveGenerator.GeneratePolygons(cells, level, out List<Vector2[]> triangles);
body.CollisionCategories = Physics.CollisionLevel;
#if CLIENT
List<VertexPositionTexture> bodyVertices = CaveGenerator.GenerateRenderVerticeList(triangles);
SetBodyVertices(bodyVertices.ToArray(), color);
SetWallVertices(CaveGenerator.GenerateWallShapes(cells, level), color);
#endif
}
public void Update(float deltaTime)
{
if (body.BodyType == BodyType.Static) return;
Vector2 bodyPos = ConvertUnits.ToDisplayUnits(body.Position);
Cells.ForEach(c => c.Translation = bodyPos);
if (!originalPos.HasValue) originalPos = bodyPos;
if (moveLength > 0.0f && MoveSpeed > 0.0f)
{
moveState += MoveSpeed / moveLength * deltaTime;
moveState %= MathHelper.TwoPi;
Vector2 targetPos = ConvertUnits.ToSimUnits(originalPos.Value + moveAmount * (float)Math.Sin(moveState));
body.ApplyForce((targetPos - body.Position).ClampLength(1.0f) * body.Mass);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
#if CLIENT
if (wallVertices != null)
{
wallVertices.Dispose();
wallVertices = null;
}
if (bodyVertices != null)
{
BodyVertices.Dispose();
bodyVertices = null;
}
#endif
}
}
}