From a6f5ba2f3b0dc8db1705f7d1919b412224cc45e7 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 27 Jun 2015 10:22:29 +1000 Subject: [PATCH] Fix reach distance being too short in some circumstances. (Thanks Cheesse), partially addresses #27. --- Game/Game.InputHandling.cs | 6 +++--- Physics/Picking.cs | 37 +++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Game/Game.InputHandling.cs b/Game/Game.InputHandling.cs index e7f716a8d..18e7d77d2 100644 --- a/Game/Game.InputHandling.cs +++ b/Game/Game.InputHandling.cs @@ -148,15 +148,15 @@ namespace ClassicalSharp { if( !Map.IsValidPos( pos ) ) return; 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 ); UpdateBlock( pos.X, pos.Y, pos.Z, (byte)block ); } } } - bool CanReplace( byte block ) { - return block == 0 || ( BlockInfo.IsLiquid( block ) && !CanPlace[block] && !CanDelete[block] ); + internal bool CanPick( byte block ) { + return !( block == 0 || ( BlockInfo.IsLiquid( block ) && !CanPlace[block] && !CanDelete[block] ) ); } public KeyMap Keys = new KeyMap(); diff --git a/Physics/Picking.cs b/Physics/Picking.cs index bf1a0c034..d1b814529 100644 --- a/Physics/Picking.cs +++ b/Physics/Picking.cs @@ -71,27 +71,27 @@ namespace ClassicalSharp { // For each step, determine which distance to the next voxel boundary is lowest (i.e. // which voxel boundary is nearest) and walk that way. while( iterations < 10000 ) { - Vector3 pos = new Vector3( x, y, z ); - if( Utils.DistanceSquared( pos, origin ) >= reachSquared ) { + byte block = map.IsValidPos( x, y, z ) ? map.GetBlock( x, y, z ) : (byte)0; + 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; return; } - iterations++; - byte block; - if( map.IsValidPos( x, y, z ) && ( block = map.GetBlock( x, y, z ) ) != 0 ) { - bool cantPickBlock = !window.CanPlace[block] && !window.CanDelete[block] && info.IsLiquid( block ); - if( !cantPickBlock ) { - // This cell falls on the path of the ray. Now perform an additional bounding box test, - // since some blocks do not occupy a whole cell. - float height = info.BlockHeight( block ); - 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; - } + if( window.CanPick( block ) ) { + // This cell falls on the path of the ray. Now perform an additional bounding box test, + // since some blocks do not occupy a whole cell. + float t0, t1; + if( IntersectionUtils.RayIntersectsBox( origin, dir, min, max, out t0, out t1 ) ) { + pickedPos.UpdateBlockPos( min, max, origin, dir, t0, t1 ); + return; } } @@ -108,12 +108,13 @@ namespace ClassicalSharp { z += stepZ; tMax.Z += tDelta.Z; } + iterations++; } throw new InvalidOperationException( "did over 10000 iterations in GetPickedBlockPos(). " + "Something has gone wrong. (dir: " + dir + ")" ); } } - + public class PickedPos { public Vector3 Min, Max;