mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-08 21:46:38 -04:00
83 lines
2.8 KiB
C#
83 lines
2.8 KiB
C#
using System;
|
|
using OpenTK;
|
|
|
|
namespace ClassicalSharp.Particles {
|
|
|
|
public sealed class TerrainParticle : Particle {
|
|
|
|
const float gravity = 2.4f;
|
|
double maxY = 0;
|
|
|
|
public TerrainParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime, TextureRectangle rec )
|
|
: base( game, pos, velocity, lifetime, rec ) {
|
|
maxY = Position.Y;
|
|
}
|
|
|
|
public override void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ) {
|
|
Position = Vector3.Lerp( lastPos, nextPos, t );
|
|
Vector3 p111, p121, p212, p222;
|
|
TranslatePoints( out p111, out p121, out p212, out p222 );
|
|
Map map = game.Map;
|
|
FastColour col = map.IsLit( Vector3I.Floor( Position ) ) ? map.Sunlight : map.Shadowlight;
|
|
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( p111, Rectangle.U1, Rectangle.V2, col );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( p121, Rectangle.U1, Rectangle.V1, col );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( p222, Rectangle.U2, Rectangle.V1, col );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( p212, Rectangle.U2, Rectangle.V2, col );
|
|
}
|
|
|
|
public override bool Tick( double delta ) {
|
|
lastPos = Position = nextPos;
|
|
Velocity.Y -= gravity * (float)delta;
|
|
int startY = (int)Math.Floor( Position.Y );
|
|
Position += Velocity * (float)delta;
|
|
int endY = (int)Math.Floor( Position.Y );
|
|
Utils.Clamp( ref Position.X, 0, game.Map.Width - 0.01f );
|
|
Utils.Clamp( ref Position.Z, 0, game.Map.Length - 0.01f );
|
|
|
|
if( endY <= startY ) {
|
|
for( int y = startY; y >= endY; y-- ) {
|
|
if( y < 0 ) {
|
|
return CollideWithGround( 0 ) ? true : base.Tick( delta );
|
|
}
|
|
byte block = GetBlock( (int)Position.X, y, (int)Position.Z );
|
|
if( block == 0 || game.BlockInfo.IsSprite( block ) || game.BlockInfo.IsLiquid( block ) )
|
|
continue;
|
|
|
|
float groundHeight = y + game.BlockInfo.BlockHeight( block );
|
|
if( Position.Y < groundHeight ) {
|
|
return CollideWithGround( groundHeight ) ? true : base.Tick( delta );
|
|
}
|
|
}
|
|
}
|
|
nextPos = Position;
|
|
Position = lastPos;
|
|
return base.Tick( delta );
|
|
}
|
|
|
|
byte GetBlock( int x, int y, int z ) {
|
|
// If particles are spawned at the top of the map, they can occasionally
|
|
// go outside the top of the map. This is okay, so handle this case.
|
|
if( y >= game.Map.Height ) return 0;
|
|
return game.Map.GetBlock( x, y, z );
|
|
}
|
|
|
|
bool CollideWithGround( float y ) {
|
|
if( y > maxY ) {
|
|
// prevent the particle teleporting up when a block is
|
|
// placed on top of the particle, simply die instead.
|
|
return true;
|
|
}
|
|
Position.Y = y;
|
|
maxY = y;
|
|
Velocity = Vector3.Zero;
|
|
nextPos = Position;
|
|
Position = lastPos;
|
|
return false;
|
|
}
|
|
|
|
public override void Dispose() {
|
|
}
|
|
}
|
|
}
|