mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
Modularise Entity and Player class more.
This commit is contained in:
parent
eb3bbc168a
commit
2cb3322c34
@ -148,6 +148,7 @@
|
||||
<Compile Include="Entities\Components\HacksComponent.cs" />
|
||||
<Compile Include="Entities\Components\InterpolatedComponent.cs" />
|
||||
<Compile Include="Entities\Components\PhysicsComponent.cs" />
|
||||
<Compile Include="Entities\Entity.Bounds.cs" />
|
||||
<Compile Include="Entities\Entity.cs" />
|
||||
<Compile Include="Entities\EntityList.cs" />
|
||||
<Compile Include="Entities\LocalPlayer.cs" />
|
||||
|
94
ClassicalSharp/Entities/Entity.Bounds.cs
Normal file
94
ClassicalSharp/Entities/Entity.Bounds.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using ClassicalSharp.Model;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp {
|
||||
|
||||
/// <summary> Contains a model, along with position, velocity, and rotation.
|
||||
/// May also contain other fields and properties. </summary>
|
||||
public abstract partial class Entity {
|
||||
|
||||
/// <summary> Returns the bounding box that contains the model, assuming it is not rotated. </summary>
|
||||
public BoundingBox PickingBounds {
|
||||
get { UpdateModel(); return Model.PickingBounds.Offset( Position ); }
|
||||
}
|
||||
|
||||
/// <summary> Bounding box of the model that collision detection
|
||||
/// is performed with, in world coordinates. </summary>
|
||||
public virtual BoundingBox CollisionBounds {
|
||||
get {
|
||||
Vector3 pos = Position;
|
||||
Vector3 size = CollisionSize;
|
||||
return new BoundingBox( pos.X - size.X / 2, pos.Y, pos.Z - size.Z / 2,
|
||||
pos.X + size.X / 2, pos.Y + size.Y, pos.Z + size.Z / 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity satisfy the given condition. </summary>
|
||||
public bool TouchesAny( Predicate<byte> condition ) {
|
||||
return TouchesAny( CollisionBounds, condition );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// given bounding box satisfy the given condition. </summary>
|
||||
public bool TouchesAny( BoundingBox bounds, Predicate<byte> condition ) {
|
||||
Vector3I bbMin = Vector3I.Floor( bounds.Min );
|
||||
Vector3I bbMax = Vector3I.Floor( bounds.Max );
|
||||
|
||||
// Order loops so that we minimise cache misses
|
||||
for( int y = bbMin.Y; y <= bbMax.Y; y++ )
|
||||
for( int z = bbMin.Z; z <= bbMax.Z; z++ )
|
||||
for( int x = bbMin.X; x <= bbMax.X; x++ )
|
||||
{
|
||||
if( !game.Map.IsValidPos( x, y, z ) ) continue;
|
||||
byte block = game.Map.GetBlock( x, y, z );
|
||||
Vector3 min = new Vector3( x, y, z ) + info.MinBB[block];
|
||||
Vector3 max = new Vector3( x, y, z ) + info.MaxBB[block];
|
||||
|
||||
BoundingBox blockBB = new BoundingBox( min, max );
|
||||
if( !blockBB.Intersects( bounds ) ) continue;
|
||||
if( condition( block ) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary> Constant offset used to avoid floating point roundoff errors. </summary>
|
||||
public const float Adjustment = 0.001f;
|
||||
static readonly Vector3 liqExpand = new Vector3( 0.25f/16f, 0/16f, 0.25f/16f );
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are lava or still lava. </summary>
|
||||
protected bool TouchesAnyLava() {
|
||||
BoundingBox bounds = CollisionBounds.Expand( liqExpand );
|
||||
AdjustLiquidTestBounds( ref bounds );
|
||||
return TouchesAny( bounds,
|
||||
b => b == (byte)Block.Lava || b == (byte)Block.StillLava );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are rope. </summary>
|
||||
protected bool TouchesAnyRope() {
|
||||
BoundingBox bounds = CollisionBounds;
|
||||
bounds.Max.Y += 0.5f/16f;
|
||||
return TouchesAny( bounds, b => b == (byte)Block.Rope );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are water or still water. </summary>
|
||||
protected bool TouchesAnyWater() {
|
||||
BoundingBox bounds = CollisionBounds.Expand( liqExpand );
|
||||
AdjustLiquidTestBounds( ref bounds );
|
||||
return TouchesAny( bounds,
|
||||
b => b == (byte)Block.Water || b == (byte)Block.StillWater );
|
||||
}
|
||||
|
||||
void AdjustLiquidTestBounds( ref BoundingBox bounds ) {
|
||||
// Even though we collide with lava 3 blocks above our feet, vanilla client thinks
|
||||
// that we do not.. so we have to maintain compatibility here.
|
||||
float height = bounds.Max.Y - bounds.Min.Y;
|
||||
const float pHeight = (28.5f - 4f)/16f;
|
||||
bounds.Max.Y = bounds.Min.Y + Math.Min( height, pHeight );
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ namespace ClassicalSharp {
|
||||
|
||||
/// <summary> Contains a model, along with position, velocity, and rotation.
|
||||
/// May also contain other fields and properties. </summary>
|
||||
public abstract class Entity {
|
||||
public abstract partial class Entity {
|
||||
|
||||
public Entity( Game game ) {
|
||||
this.game = game;
|
||||
@ -49,28 +49,12 @@ namespace ClassicalSharp {
|
||||
get { UpdateModel(); return Model.CollisionSize; }
|
||||
}
|
||||
|
||||
/// <summary> Returns the bounding box that contains the model, assuming it is not rotated. </summary>
|
||||
public BoundingBox PickingBounds {
|
||||
get { UpdateModel(); return Model.PickingBounds.Offset( Position ); }
|
||||
}
|
||||
|
||||
void UpdateModel() {
|
||||
BlockModel model = Model as BlockModel;
|
||||
if( model != null )
|
||||
model.CalcState( byte.Parse( ModelName ) );
|
||||
}
|
||||
|
||||
/// <summary> Bounding box of the model that collision detection
|
||||
/// is performed with, in world coordinates. </summary>
|
||||
public virtual BoundingBox CollisionBounds {
|
||||
get {
|
||||
Vector3 pos = Position;
|
||||
Vector3 size = CollisionSize;
|
||||
return new BoundingBox( pos.X - size.X / 2, pos.Y, pos.Z - size.Z / 2,
|
||||
pos.X + size.X / 2, pos.Y + size.Y, pos.Z + size.Z / 2 );
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void Tick( double delta );
|
||||
|
||||
public abstract void SetLocation( LocationUpdate update, bool interpolate );
|
||||
@ -84,71 +68,23 @@ namespace ClassicalSharp {
|
||||
/// <remarks> Assumes that RenderModel was previously called this frame. </remarks>
|
||||
public abstract void RenderName();
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity satisfy the given condition. </summary>
|
||||
public bool TouchesAny( Predicate<byte> condition ) {
|
||||
return TouchesAny( CollisionBounds, condition );
|
||||
/// <summary> Gets the position of the player's eye in the world. </summary>
|
||||
public Vector3 EyePosition {
|
||||
get { return new Vector3( Position.X, Position.Y + Model.GetEyeY( this ), Position.Z ); }
|
||||
}
|
||||
|
||||
/// <summary> Gets the block just underneath the player's feet position. </summary>
|
||||
public Block BlockUnderFeet {
|
||||
get { return GetBlock( new Vector3( Position.X, Position.Y - 0.01f, Position.Z ) ); }
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// given bounding box satisfy the given condition. </summary>
|
||||
public bool TouchesAny( BoundingBox bounds, Predicate<byte> condition ) {
|
||||
Vector3I bbMin = Vector3I.Floor( bounds.Min );
|
||||
Vector3I bbMax = Vector3I.Floor( bounds.Max );
|
||||
|
||||
// Order loops so that we minimise cache misses
|
||||
for( int y = bbMin.Y; y <= bbMax.Y; y++ )
|
||||
for( int z = bbMin.Z; z <= bbMax.Z; z++ )
|
||||
for( int x = bbMin.X; x <= bbMax.X; x++ )
|
||||
{
|
||||
if( !game.Map.IsValidPos( x, y, z ) ) continue;
|
||||
byte block = game.Map.GetBlock( x, y, z );
|
||||
Vector3 min = new Vector3( x, y, z ) + info.MinBB[block];
|
||||
Vector3 max = new Vector3( x, y, z ) + info.MaxBB[block];
|
||||
|
||||
BoundingBox blockBB = new BoundingBox( min, max );
|
||||
if( !blockBB.Intersects( bounds ) ) continue;
|
||||
if( condition( block ) ) return true;
|
||||
}
|
||||
return false;
|
||||
/// <summary> Gets the block at player's eye position. </summary>
|
||||
public Block BlockAtHead {
|
||||
get { return GetBlock( EyePosition ); }
|
||||
}
|
||||
|
||||
/// <summary> Constant offset used to avoid floating point roundoff errors. </summary>
|
||||
public const float Adjustment = 0.001f;
|
||||
static readonly Vector3 liqExpand = new Vector3( 0.25f/16f, 0/16f, 0.25f/16f );
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are lava or still lava. </summary>
|
||||
protected bool TouchesAnyLava() {
|
||||
BoundingBox bounds = CollisionBounds.Expand( liqExpand );
|
||||
AdjustLiquidTestBounds( ref bounds );
|
||||
return TouchesAny( bounds,
|
||||
b => b == (byte)Block.Lava || b == (byte)Block.StillLava );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are rope. </summary>
|
||||
protected bool TouchesAnyRope() {
|
||||
BoundingBox bounds = CollisionBounds;
|
||||
bounds.Max.Y += 0.5f/16f;
|
||||
return TouchesAny( bounds, b => b == (byte)Block.Rope );
|
||||
}
|
||||
|
||||
/// <summary> Determines whether any of the blocks that intersect the
|
||||
/// bounding box of this entity are water or still water. </summary>
|
||||
protected bool TouchesAnyWater() {
|
||||
BoundingBox bounds = CollisionBounds.Expand( liqExpand );
|
||||
AdjustLiquidTestBounds( ref bounds );
|
||||
return TouchesAny( bounds,
|
||||
b => b == (byte)Block.Water || b == (byte)Block.StillWater );
|
||||
}
|
||||
|
||||
void AdjustLiquidTestBounds( ref BoundingBox bounds ) {
|
||||
// Even though we collide with lava 3 blocks above our feet, vanilla client thinks
|
||||
// that we do not.. so we have to maintain compatibility here.
|
||||
float height = bounds.Max.Y - bounds.Min.Y;
|
||||
const float pHeight = (28.5f - 4f)/16f;
|
||||
bounds.Max.Y = bounds.Min.Y + Math.Min( height, pHeight );
|
||||
protected Block GetBlock( Vector3 coords ) {
|
||||
return (Block)game.Map.SafeGetBlock( Vector3I.Floor( coords ) );
|
||||
}
|
||||
}
|
||||
}
|
@ -228,6 +228,12 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveOldest<T>(T[] array, ref int count) {
|
||||
for( int i = 0; i < array.Length - 1; i++ )
|
||||
array[i] = array[i + 1];
|
||||
count--;
|
||||
}
|
||||
|
||||
internal bool HandleKeyDown( Key key ) {
|
||||
KeyMap keys = game.InputHandler.Keys;
|
||||
if( key == keys[KeyBinding.Respawn] && Hacks.CanRespawn ) {
|
||||
|
@ -11,11 +11,6 @@ namespace ClassicalSharp {
|
||||
|
||||
public abstract partial class Player : Entity {
|
||||
|
||||
/// <summary> Gets the position of the player's eye in the world. </summary>
|
||||
public Vector3 EyePosition {
|
||||
get { return new Vector3( Position.X, Position.Y + Model.GetEyeY( this ), Position.Z ); }
|
||||
}
|
||||
|
||||
public string DisplayName, SkinName, SkinIdentifier;
|
||||
public SkinType SkinType;
|
||||
internal AnimatedComponent anim;
|
||||
@ -28,20 +23,6 @@ namespace ClassicalSharp {
|
||||
SetModel( "humanoid" );
|
||||
}
|
||||
|
||||
/// <summary> Gets the block just underneath the player's feet position. </summary>
|
||||
public Block BlockUnderFeet {
|
||||
get { return GetBlock( new Vector3( Position.X, Position.Y - 0.01f, Position.Z ) ); }
|
||||
}
|
||||
|
||||
/// <summary> Gets the block at player's eye position. </summary>
|
||||
public Block BlockAtHead {
|
||||
get { return GetBlock( EyePosition ); }
|
||||
}
|
||||
|
||||
protected Block GetBlock( Vector3 coords ) {
|
||||
return (Block)game.Map.SafeGetBlock( Vector3I.Floor( coords ) );
|
||||
}
|
||||
|
||||
protected void CheckSkin() {
|
||||
DownloadedItem item;
|
||||
game.AsyncDownloader.TryGetItem( SkinIdentifier, out item );
|
||||
@ -113,11 +94,5 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveOldest<T>(T[] array, ref int count) {
|
||||
for( int i = 0; i < array.Length - 1; i++ )
|
||||
array[i] = array[i + 1];
|
||||
count--;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,16 +17,12 @@ namespace ClassicalSharp.Model {
|
||||
public BlockModel( Game game ) : base( game ) {
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return false; }
|
||||
}
|
||||
public override bool Bobbing { get { return false; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return height + 0.075f; }
|
||||
}
|
||||
public override float NameYOffset { get { return height + 0.075f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
byte block = Byte.Parse( player.ModelName );
|
||||
public override float GetEyeY( Entity entity ) {
|
||||
byte block = Byte.Parse( entity.ModelName );
|
||||
float minY = game.BlockInfo.MinBB[block].Y;
|
||||
float maxY = game.BlockInfo.MaxBB[block].Y;
|
||||
return block == 0 ? 1 : (minY + maxY) / 2;
|
||||
|
@ -32,17 +32,11 @@ namespace ClassicalSharp.Model {
|
||||
return new ModelPart( index - 2 * 4, 2 * 4 );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 1.0125f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 1.0125f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 14/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 14/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 8/16f, 12/16f, 8/16f ); }
|
||||
|
@ -23,17 +23,11 @@ namespace ClassicalSharp.Model {
|
||||
.SetTexOrigin( 0, 16 ) );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 1.7f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 1.7f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 22/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 22/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 8/16f, 26/16f, 8/16f ); }
|
||||
|
@ -32,7 +32,7 @@ namespace ClassicalSharp.Model {
|
||||
public abstract float NameYOffset { get; }
|
||||
|
||||
/// <summary> Vertical offset from the model's feet/base that the model's eye is located. </summary>
|
||||
public abstract float GetEyeY( Player player );
|
||||
public abstract float GetEyeY( Entity entity );
|
||||
|
||||
/// <summary> The size of the bounding box that is used when
|
||||
/// performing collision detection for this model. </summary>
|
||||
|
@ -22,17 +22,11 @@ namespace ClassicalSharp.Model {
|
||||
.SetTexOrigin( 0, 16 ) );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 1.075f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 1.075f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 12/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 12/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 14/16f, 14/16f, 14/16f ); }
|
||||
|
@ -40,17 +40,11 @@ namespace ClassicalSharp.Model {
|
||||
SetSlim.Hat = Set.Hat;
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 2.1375f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 2.1375f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 26/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 26/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 8/16f + 0.6f/16f, 28.1f/16f, 8/16f + 0.6f/16f ); }
|
||||
|
@ -44,17 +44,11 @@ namespace ClassicalSharp.Model {
|
||||
FurRightLegBack = BuildBox( legDesc.SetModelBounds( 0.5f, 5.5f, 4.5f, 5.5f, 12.5f, 9.5f ) );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return Fur ? 1.48125f: 1.075f; }
|
||||
}
|
||||
public override float NameYOffset { get { return Fur ? 1.48125f: 1.075f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 20/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 20/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 14/16f, 20/16f, 14/16f ); }
|
||||
|
@ -22,17 +22,11 @@ namespace ClassicalSharp.Model {
|
||||
.SetTexOrigin( 40, 16 ) );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 2.075f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 2.075f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 26/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 26/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 8/16f, 30/16f, 8/16f ); }
|
||||
|
@ -20,17 +20,11 @@ namespace ClassicalSharp.Model {
|
||||
.SetTexOrigin( 18, 0 ) );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 1.0125f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 1.0125f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 8/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 8/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 15/16f, 12/16f, 15/16f ); }
|
||||
|
@ -22,17 +22,11 @@ namespace ClassicalSharp.Model {
|
||||
.SetTexOrigin( 40, 16 ) );
|
||||
}
|
||||
|
||||
public override bool Bobbing {
|
||||
get { return true; }
|
||||
}
|
||||
public override bool Bobbing { get { return true; } }
|
||||
|
||||
public override float NameYOffset {
|
||||
get { return 2.075f; }
|
||||
}
|
||||
public override float NameYOffset { get { return 2.075f; } }
|
||||
|
||||
public override float GetEyeY( Player player ) {
|
||||
return 26/16f;
|
||||
}
|
||||
public override float GetEyeY( Entity entity ) { return 26/16f; }
|
||||
|
||||
public override Vector3 CollisionSize {
|
||||
get { return new Vector3( 8/16f, 30/16f, 8/16f ); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user