152 lines
4.7 KiB
C#
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
|
|
}
|
|
}
|
|
}
|