diff --git a/ClassicalSharp/2D/Screens/BlockSelectScreen.cs b/ClassicalSharp/2D/Screens/BlockSelectScreen.cs
index bfc87d59d..5a8bc0b83 100644
--- a/ClassicalSharp/2D/Screens/BlockSelectScreen.cs
+++ b/ClassicalSharp/2D/Screens/BlockSelectScreen.cs
@@ -140,7 +140,6 @@ namespace ClassicalSharp {
int index = 0;
SplitUppercase( origName, ref index );
normalNames[i] = buffer.ToString();
- Console.WriteLine( buffer.ToString() );
}
}
diff --git a/ClassicalSharp/Entities/Entity.cs b/ClassicalSharp/Entities/Entity.cs
index beea68d28..44529f29a 100644
--- a/ClassicalSharp/Entities/Entity.cs
+++ b/ClassicalSharp/Entities/Entity.cs
@@ -38,9 +38,13 @@ namespace ClassicalSharp {
/// Returns the size of the model that is used for collision detection.
public virtual Vector3 CollisionSize {
- get { return new Vector3( 8/16f, 28.5f/16f, 8/16f );
- //Model.CollisionSize; TODO: for non humanoid models
- }
+ get { UpdateModel(); return Model.CollisionSize; }
+ }
+
+ void UpdateModel() {
+ BlockModel model = Model as BlockModel;
+ if( model != null )
+ model.CalcState( byte.Parse( ModelName ) );
}
/// Bounding box of the model that collision detection
@@ -103,9 +107,7 @@ namespace ClassicalSharp {
/// bounding box of this entity are lava or still lava.
protected bool TouchesAnyLava() {
BoundingBox bounds = CollisionBounds.Expand( liqExpand );
- // 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.
- bounds.Max.Y -= 4/16f;
+ AdjustLiquidTestBounds( ref bounds );
return TouchesAny( bounds,
b => b == (byte)Block.Lava || b == (byte)Block.StillLava );
}
@@ -121,9 +123,17 @@ namespace ClassicalSharp {
/// bounding box of this entity are water or still water.
protected bool TouchesAnyWater() {
BoundingBox bounds = CollisionBounds.Expand( liqExpand );
- bounds.Max.Y -= 4/16f;
+ 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 );
+ }
}
}
\ No newline at end of file
diff --git a/ClassicalSharp/Entities/LocalPlayer.cs b/ClassicalSharp/Entities/LocalPlayer.cs
index f2989efb3..417709ec1 100644
--- a/ClassicalSharp/Entities/LocalPlayer.cs
+++ b/ClassicalSharp/Entities/LocalPlayer.cs
@@ -165,26 +165,25 @@ namespace ClassicalSharp {
}
if( !jumping ) {
- canLiquidJump = false;
- return;
+ canLiquidJump = false; return;
}
bool touchWater = TouchesAnyWater();
bool touchLava = TouchesAnyLava();
+ Console.WriteLine( touchWater );
if( touchWater || touchLava ) {
BoundingBox bounds = CollisionBounds;
int feetY = Utils.Floor( bounds.Min.Y ), bodyY = feetY + 1;
int headY = Utils.Floor( bounds.Max.Y );
+ if( bodyY > headY ) bodyY = headY;
bounds.Max.Y = bounds.Min.Y = feetY;
bool liquidFeet = TouchesAny( bounds, StandardLiquid );
- bounds.Max.Y = bounds.Min.Y = bodyY;
- bool liquidBody = TouchesAny( bounds, StandardLiquid );
- bounds.Max.Y = bounds.Min.Y = headY;
- bool liquidHead = TouchesAny( bounds, StandardLiquid );
+ bounds.Min.Y = Math.Min( bodyY, headY );
+ bounds.Max.Y = Math.Max( bodyY, headY );
+ bool liquidRest = TouchesAny( bounds, StandardLiquid );
- bool pastJumpPoint = liquidFeet && !(liquidBody || liquidHead)
- && (Position.Y % 1 >= 0.4);
+ bool pastJumpPoint = liquidFeet && !liquidRest && (Position.Y % 1 >= 0.4);
if( !pastJumpPoint ) {
canLiquidJump = true;
Velocity.Y += speeding ? 0.08f : 0.04f;
diff --git a/ClassicalSharp/Entities/PhysicsEntity.cs b/ClassicalSharp/Entities/PhysicsEntity.cs
index f3cdfc0f9..908f58ade 100644
--- a/ClassicalSharp/Entities/PhysicsEntity.cs
+++ b/ClassicalSharp/Entities/PhysicsEntity.cs
@@ -85,7 +85,7 @@ namespace ClassicalSharp {
int elements = (max.X + 1 - min.X) * (max.Y + 1 - min.Y) * (max.Z + 1 - min.Z);
if( elements > stateCache.Length ) {
stateCache = new State[elements];
- }
+ }
BoundingBox blockBB = default( BoundingBox );
// Order loops so that we minimise cache misses
@@ -160,27 +160,17 @@ namespace ClassicalSharp {
ref BoundingBox entityBB, ref BoundingBox entityExtentBB ) {
float yDist = blockBB.Max.Y - entityBB.Min.Y;
if( yDist > 0 && yDist <= StepSize + 0.01f ) {
-
// Adjust entity bounding box to include the block being tested
BoundingBox adjFinalBB = finalBB;
adjFinalBB.Min.X = Math.Min( finalBB.Min.X, blockBB.Min.X + Adjustment );
adjFinalBB.Max.X = Math.Max( finalBB.Max.X, blockBB.Max.X - Adjustment );
- adjFinalBB.Min.Y = (float)Math.Ceiling( blockBB.Max.Y ) + Adjustment;
+ adjFinalBB.Min.Y = blockBB.Max.Y + Adjustment;
adjFinalBB.Max.Y = adjFinalBB.Min.Y + size.Y;
adjFinalBB.Min.Z = Math.Min( finalBB.Min.Z, blockBB.Min.Z + Adjustment );
adjFinalBB.Max.Z = Math.Max( finalBB.Max.Z, blockBB.Max.Z - Adjustment );
- Vector3I min = Vector3I.Floor( adjFinalBB.Min );
- Vector3I max = Vector3I.Floor( adjFinalBB.Max );
- for( int x = min.X; x <= max.X; x++ ) {
- for( int y = min.Y; y <= max.Y; y++ ) {
- for( int z = min.Z; z <= max.Z; z++ ) {
- if( info.CollideType[GetPhysicsBlockId( x, y, z )] == BlockCollideType.Solid )
- return false;
- }
- }
- }
-
+ if( !CanSlideThrough( ref adjFinalBB ) )
+ return false;
Position.Y = blockBB.Max.Y + Adjustment;
onGround = true;
ClipY( ref size, ref entityBB, ref entityExtentBB );
@@ -189,6 +179,27 @@ namespace ClassicalSharp {
return false;
}
+ bool CanSlideThrough( ref BoundingBox adjFinalBB ) {
+ Vector3I bbMin = Vector3I.Floor( adjFinalBB.Min );
+ Vector3I bbMax = Vector3I.Floor( adjFinalBB.Max );
+
+ 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++ )
+ {
+ byte block = GetPhysicsBlockId( 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( adjFinalBB ) )
+ continue;
+ if( info.CollideType[GetPhysicsBlockId( x, y, z )] == BlockCollideType.Solid )
+ return false;
+ }
+ return true;
+ }
+
void ClipX( ref Vector3 size, ref BoundingBox entityBB, ref BoundingBox entityExtentBB ) {
Velocity.X = 0;
entityBB.Min.X = entityExtentBB.Min.X = Position.X - size.X / 2;
diff --git a/ClassicalSharp/Generator/Noise.cs b/ClassicalSharp/Generator/Noise.cs
index 6de73366a..c09e096bf 100644
--- a/ClassicalSharp/Generator/Noise.cs
+++ b/ClassicalSharp/Generator/Noise.cs
@@ -14,9 +14,7 @@ namespace ClassicalSharp.Generator {
public sealed class ImprovedNoise : Noise {
public ImprovedNoise( Random rnd ) {
- // make a random initial permutation based on rnd's seed,
- // shuffle using fisher-yates
-
+ // shuffle randomly using fisher-yates
for( int i = 0; i < 256; i++ )
p[i] = (byte)i;
@@ -28,7 +26,6 @@ namespace ClassicalSharp.Generator {
p[i + 256] = p[i];
}
- // TODO: need to half this maybe?
public override double Compute( double x, double y ) {
int xFloor = x >= 0 ? (int)x : (int)x - 1;
int yFloor = y >= 0 ? (int)y : (int)y - 1;
diff --git a/ClassicalSharp/Model/BlockModel.cs b/ClassicalSharp/Model/BlockModel.cs
index bcce00bb4..bd14567c9 100644
--- a/ClassicalSharp/Model/BlockModel.cs
+++ b/ClassicalSharp/Model/BlockModel.cs
@@ -10,8 +10,9 @@ namespace ClassicalSharp.Model {
byte block = (byte)Block.Air;
float blockHeight;
TerrainAtlas1D atlas;
- const float adjust = 0.1f, extent = 0.5f;
+ const float extent = 0.5f, adjust = 0.5f/16f;
bool bright;
+ Vector3 minBB, maxBB;
public BlockModel( Game game ) : base( game ) {
}
@@ -30,13 +31,27 @@ namespace ClassicalSharp.Model {
}
public override Vector3 CollisionSize {
- get { return new Vector3( 1 - adjust, blockHeight - adjust, 1 - adjust ); }
+ get { return (maxBB - minBB) - new Vector3( adjust ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -extent, 0f, -extent, extent, blockHeight, extent ); }
}
+ public void CalcState( byte block ) {
+ if( block == 0 ) {
+ blockHeight = 1;
+ bright = false;
+ minBB = Vector3.Zero;
+ maxBB = Vector3.One;
+ } else {
+ blockHeight = game.BlockInfo.Height[block];
+ bright = game.BlockInfo.FullBright[block];
+ minBB = game.BlockInfo.MinBB[block];
+ maxBB = game.BlockInfo.MaxBB[block];
+ }
+ }
+
int lastTexId = -1;
protected override void DrawPlayerModel( Player p ) {
// TODO: using 'is' is ugly, but means we can avoid creating
@@ -49,14 +64,12 @@ namespace ClassicalSharp.Model {
} else {
block = Byte.Parse( p.ModelName );
}
- if( block == 0 ) {
- blockHeight = 1;
+
+ CalcState( block );
+ if( block == 0 )
return;
- }
lastTexId = -1;
- blockHeight = game.BlockInfo.Height[block];
atlas = game.TerrainAtlas1D;
- bright = game.BlockInfo.FullBright[block];
if( game.BlockInfo.IsSprite[block] ) {
SpriteXQuad( TileSide.Right, true );
@@ -135,7 +148,7 @@ namespace ClassicalSharp.Model {
float p1, p2;
if( firstPart ) { // Need to break into two quads for when drawing a sprite model in hand.
- rec.U1 = 0.5f; p1 = -5.5f/16; p2 = 0.0f/16;
+ rec.U1 = 0.5f; p1 = -5.5f/16; p2 = 0.0f/16;
} else {
rec.U2 = 0.5f; p1 = 0.0f/16; p2 = 5.5f/16;
}
@@ -155,7 +168,7 @@ namespace ClassicalSharp.Model {
float x1, x2, z1, z2;
if( firstPart ) {
- rec.U1 = 0; rec.U2 = 0.5f; x1 = -5.5f/16;
+ rec.U1 = 0; rec.U2 = 0.5f; x1 = -5.5f/16;
x2 = 0.0f/16; z1 = 5.5f/16; z2 = 0.0f/16;
} else {
rec.U1 = 0.5f; rec.U2 = 1f; x1 = 0.0f/16;
diff --git a/ClassicalSharp/Model/SpiderModel.cs b/ClassicalSharp/Model/SpiderModel.cs
index e7bab0b56..54b351534 100644
--- a/ClassicalSharp/Model/SpiderModel.cs
+++ b/ClassicalSharp/Model/SpiderModel.cs
@@ -50,7 +50,6 @@ namespace ClassicalSharp.Model {
DrawPart( Link );
DrawPart( End );
- // TODO: leg animations
float rotX = (float)(Math.Sin( p.walkTime ) * p.swing * Math.PI);
float rotZ = (float)(Math.Cos( p.walkTime * 2 ) * p.swing * Math.PI / 16f);
float rotY = (float)(Math.Sin( p.walkTime * 2 ) * p.swing * Math.PI / 32f);