/// <summary> Determines whether this bounding box intersects /// the given bounding box on any axes. </summary> public bool Intersects( BoundingBox other ) { if( Max.X >= other.Min.X && Min.X <= other.Max.X ) { if( Max.Y < other.Min.Y || Min.Y > other.Max.Y ) { return false; } return Max.Z >= other.Min.Z && Min.Z <= other.Max.Z; } return false; }
public bool TouchesAny( BoundingBox bounds, Predicate<byte> condition ) { Vector3I bbMin = Vector3I.Floor( bounds.Min ); Vector3I bbMax = Vector3I.Floor( bounds.Max ); for( int x = bbMin.X; x <= bbMax.X; x++ ) { for( int y = bbMin.Y; y <= bbMax.Y; y++ ) { for( int z = bbMin.Z; z <= bbMax.Z; z++ ) { if( !game.Map.IsValidPos( x, y, z ) ) continue; byte block = game.Map.GetBlock( x, y, z ); if( condition( block ) ) { float blockHeight = info.Height[block]; Vector3 min = new Vector3( x, y, z ); Vector3 max = new Vector3( x + 1, y + blockHeight, z + 1 ); BoundingBox blockBB = new BoundingBox( min, max ); if( blockBB.Intersects( bounds ) ) return true; } } } } return false; }
bool PushbackPlace( PickedPos selected, BoundingBox blockBB ) { Vector3 newP = game.LocalPlayer.Position; Vector3 oldP = game.LocalPlayer.Position; // Offset position by the closest face if( selected.BlockFace == CpeBlockFace.XMax ) newP.X = blockBB.Max.X + 0.5f; else if( selected.BlockFace == CpeBlockFace.ZMax ) newP.Z = blockBB.Max.Z + 0.5f; else if( selected.BlockFace == CpeBlockFace.XMin ) newP.X = blockBB.Min.X - 0.5f; else if( selected.BlockFace == CpeBlockFace.ZMin ) newP.Z = blockBB.Min.Z - 0.5f; else if( selected.BlockFace == CpeBlockFace.YMax ) newP.Y = blockBB.Min.Y + 1 + Entity.Adjustment; else if( selected.BlockFace == CpeBlockFace.YMin ) newP.Y = blockBB.Min.Y - game.LocalPlayer.CollisionSize.Y - Entity.Adjustment; Vector3I newLoc = Vector3I.Floor( newP ); bool validPos = newLoc.X >= 0 && newLoc.Y >= 0 && newLoc.Z >= 0 && newLoc.X < game.Map.Width && newP.Z < game.Map.Length; if( !validPos ) return false; game.LocalPlayer.Position = newP; if( !game.LocalPlayer.noClip && game.LocalPlayer.TouchesAny( CannotPassThrough ) ) { game.LocalPlayer.Position = oldP; return false; } game.LocalPlayer.Position = oldP; LocationUpdate update = LocationUpdate.MakePos( newP, false ); game.LocalPlayer.SetLocation( update, false ); return true; }
bool IntersectsOtherPlayers( Vector3I pos, byte newType ) { float height = game.BlockInfo.Height[newType]; BoundingBox blockBB = new BoundingBox( pos.X, pos.Y, pos.Z, pos.X + 1, pos.Y + height, pos.Z + 1 ); for( int id = 0; id < 255; id++ ) { Player player = game.Players[id]; if( player == null ) continue; if( player.CollisionBounds.Intersects( blockBB ) ) return true; } return false; }
bool CheckIsFree( PickedPos selected, byte newBlock ) { if( !CannotPassThrough( newBlock ) ) return true; if( IntersectsOtherPlayers( selected.TranslatedPos, newBlock ) ) return false; Vector3I pos = selected.TranslatedPos; float height = game.BlockInfo.Height[newBlock]; BoundingBox blockBB = new BoundingBox( pos.X, pos.Y, pos.Z, pos.X + 1, pos.Y + height, pos.Z + 1 ); BoundingBox localBB = game.LocalPlayer.CollisionBounds; if( game.LocalPlayer.noClip || !localBB.Intersects( blockBB ) ) return true; if( game.LocalPlayer.PushbackBlockPlacing ) { return PushbackPlace( selected, blockBB ); } else { localBB.Min.Y += 0.25f + Entity.Adjustment; if( localBB.Intersects( blockBB ) ) return false; // Push player up if they are jumping and trying to place a block underneath them. Vector3 p = game.LocalPlayer.Position; p.Y = pos.Y + height + Entity.Adjustment; LocationUpdate update = LocationUpdate.MakePos( p, false ); game.LocalPlayer.SetLocation( update, false ); return true; } }
bool CheckIsFree( Vector3I pos, byte newBlock ) { float height = game.BlockInfo.Height[newBlock]; BoundingBox blockBB = new BoundingBox( pos.X, pos.Y, pos.Z, pos.X + 1, pos.Y + height, pos.Z + 1 ); for( int id = 0; id < 255; id++ ) { Player player = game.Players[id]; if( player == null ) continue; if( player.CollisionBounds.Intersects( blockBB ) ) return false; } BoundingBox localBB = game.LocalPlayer.CollisionBounds; if( localBB.Intersects( blockBB ) ) { localBB.Min.Y += 0.25f + Entity.Adjustment; if( localBB.Intersects( blockBB ) ) return false; // Push player up if they are jumping and trying to place a block underneath them. Vector3 p = game.LocalPlayer.Position; p.Y = pos.Y + height + Entity.Adjustment; LocationUpdate update = LocationUpdate.MakePos( p, false ); game.LocalPlayer.SetLocation( update, false ); } return true; }
bool IntersectsOtherPlayers( Vector3 pos, byte newType ) { BoundingBox blockBB = new BoundingBox( pos + game.BlockInfo.MinBB[newType], pos + game.BlockInfo.MaxBB[newType] ); for( int id = 0; id < 255; id++ ) { Player player = game.Players[id]; if( player == null ) continue; BoundingBox bounds = player.CollisionBounds; bounds.Min.Y += 1/32f; // when player is exactly standing on top of ground if( bounds.Intersects( blockBB ) ) return true; } return false; }
bool CheckIsFree( PickedPos selected, byte newBlock ) { Vector3 pos = (Vector3)selected.TranslatedPos; if( !CannotPassThrough( newBlock ) ) return true; if( IntersectsOtherPlayers( pos, newBlock ) ) return false; BoundingBox blockBB = new BoundingBox( pos + game.BlockInfo.MinBB[newBlock], pos + game.BlockInfo.MaxBB[newBlock] ); BoundingBox localBB = game.LocalPlayer.CollisionBounds; if( game.LocalPlayer.Hacks.Noclip || !localBB.Intersects( blockBB ) ) return true; HacksComponent hacks = game.LocalPlayer.Hacks; if( hacks.CanPushbackBlocks && hacks.PushbackPlacing && hacks.Enabled ) return PushbackPlace( selected, blockBB ); localBB.Min.Y += 0.25f + Entity.Adjustment; if( localBB.Intersects( blockBB ) ) return false; // Push player up if they are jumping and trying to place a block underneath them. Vector3 p = game.LocalPlayer.Position; p.Y = pos.Y + game.BlockInfo.MaxBB[newBlock].Y + Entity.Adjustment; LocationUpdate update = LocationUpdate.MakePos( p, false ); game.LocalPlayer.SetLocation( update, false ); return true; }
/// <summary> Determines whether this bounding box intersects /// the given bounding box on the Z axis. </summary> public bool ZIntersects( BoundingBox box ) { return Max.Z >= box.Min.Z && Min.Z <= box.Max.Z; }
/// <summary> Determines whether this bounding box intersects /// the given bounding box on the Y axis. </summary> public bool YIntersects( BoundingBox box ) { return Max.Y >= box.Min.Y && Min.Y <= box.Max.Y; }
/// <summary> Determines whether this bounding box intersects /// the given bounding box on the X axis. </summary> public bool XIntersects( BoundingBox box ) { return Max.X >= box.Min.X && Min.X <= box.Max.X; }
/// <summary> Determines whether this bounding box entirely contains /// the given bounding box on all axes. </summary> public bool Contains( BoundingBox other ) { return other.Min.X >= Min.X && other.Min.Y >= Min.Y && other.Min.Z >= Min.Z && other.Max.X <= Max.X && other.Max.Y <= Max.Y && other.Max.Z <= Max.Z; }