Fix reach distance being too short in some circumstances. (Thanks Cheesse), partially addresses #27.

This commit is contained in:
UnknownShadow200 2015-06-27 10:22:29 +10:00
parent f3794aa002
commit a6f5ba2f3b
2 changed files with 22 additions and 21 deletions

View File

@ -148,15 +148,15 @@ namespace ClassicalSharp {
if( !Map.IsValidPos( pos ) ) return; if( !Map.IsValidPos( pos ) ) return;
Block block = HeldBlock; Block block = HeldBlock;
if( CanReplace( Map.GetBlock( pos ) ) && CanPlace[(int)block] ) { if( !CanPick( Map.GetBlock( pos ) ) && CanPlace[(int)block] ) {
Network.SendSetBlock( pos.X, pos.Y, pos.Z, true, (byte)block ); Network.SendSetBlock( pos.X, pos.Y, pos.Z, true, (byte)block );
UpdateBlock( pos.X, pos.Y, pos.Z, (byte)block ); UpdateBlock( pos.X, pos.Y, pos.Z, (byte)block );
} }
} }
} }
bool CanReplace( byte block ) { internal bool CanPick( byte block ) {
return block == 0 || ( BlockInfo.IsLiquid( block ) && !CanPlace[block] && !CanDelete[block] ); return !( block == 0 || ( BlockInfo.IsLiquid( block ) && !CanPlace[block] && !CanDelete[block] ) );
} }
public KeyMap Keys = new KeyMap(); public KeyMap Keys = new KeyMap();

View File

@ -71,27 +71,27 @@ namespace ClassicalSharp {
// For each step, determine which distance to the next voxel boundary is lowest (i.e. // For each step, determine which distance to the next voxel boundary is lowest (i.e.
// which voxel boundary is nearest) and walk that way. // which voxel boundary is nearest) and walk that way.
while( iterations < 10000 ) { while( iterations < 10000 ) {
Vector3 pos = new Vector3( x, y, z ); byte block = map.IsValidPos( x, y, z ) ? map.GetBlock( x, y, z ) : (byte)0;
if( Utils.DistanceSquared( pos, origin ) >= reachSquared ) { float height = block == 0 ? 1 : info.BlockHeight( block );
Vector3 min = new Vector3( x, y, z );
Vector3 max = new Vector3( x + 1, y + height, z + 1 );
float dx = Math.Min( Math.Abs( origin.X - min.X ), Math.Abs( origin.X - max.X ) );
float dy = Math.Min( Math.Abs( origin.Y - min.Y ), Math.Abs( origin.Y - max.Y ) );
float dz = Math.Min( Math.Abs( origin.Z - min.Z ), Math.Abs( origin.Z - max.Z ) );
if( dx * dx + dy * dy + dz * dz > reachSquared ) {
pickedPos.Valid = false; pickedPos.Valid = false;
return; return;
} }
iterations++;
byte block; if( window.CanPick( block ) ) {
if( map.IsValidPos( x, y, z ) && ( block = map.GetBlock( x, y, z ) ) != 0 ) { // This cell falls on the path of the ray. Now perform an additional bounding box test,
bool cantPickBlock = !window.CanPlace[block] && !window.CanDelete[block] && info.IsLiquid( block ); // since some blocks do not occupy a whole cell.
if( !cantPickBlock ) { float t0, t1;
// This cell falls on the path of the ray. Now perform an additional bounding box test, if( IntersectionUtils.RayIntersectsBox( origin, dir, min, max, out t0, out t1 ) ) {
// since some blocks do not occupy a whole cell. pickedPos.UpdateBlockPos( min, max, origin, dir, t0, t1 );
float height = info.BlockHeight( block ); return;
Vector3 min = new Vector3( x, y, z );
Vector3 max = new Vector3( x + 1, y + height, z + 1 );
float t0, t1;
if( IntersectionUtils.RayIntersectsBox( origin, dir, min, max, out t0, out t1 ) ) {
pickedPos.UpdateBlockPos( min, max, origin, dir, t0, t1 );
return;
}
} }
} }
@ -108,6 +108,7 @@ namespace ClassicalSharp {
z += stepZ; z += stepZ;
tMax.Z += tDelta.Z; tMax.Z += tDelta.Z;
} }
iterations++;
} }
throw new InvalidOperationException( "did over 10000 iterations in GetPickedBlockPos(). " + throw new InvalidOperationException( "did over 10000 iterations in GetPickedBlockPos(). " +
"Something has gone wrong. (dir: " + dir + ")" ); "Something has gone wrong. (dir: " + dir + ")" );