mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Upgrade GetLookingBlock
This commit is contained in:
parent
ba6a954f45
commit
4aa6c1c99f
11 changed files with 213 additions and 74 deletions
|
|
@ -12,6 +12,8 @@ namespace MinecraftClient.Mapping
|
|||
/// </summary>
|
||||
public struct Block
|
||||
{
|
||||
public static readonly Block Air = new(0);
|
||||
|
||||
/// <summary>
|
||||
/// Get or set global block ID to Material mapping
|
||||
/// The global Palette is a concept introduced with Minecraft 1.13
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ namespace MinecraftClient.Mapping
|
|||
/// </summary>
|
||||
public struct Location
|
||||
{
|
||||
public static readonly Location Zero = new(0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The X Coordinate
|
||||
/// </summary>
|
||||
|
|
@ -26,17 +28,6 @@ namespace MinecraftClient.Mapping
|
|||
/// </summary>
|
||||
public double Z;
|
||||
|
||||
/// <summary>
|
||||
/// Get location with zeroed coordinates
|
||||
/// </summary>
|
||||
public static Location Zero
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Location(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new location
|
||||
/// </summary>
|
||||
|
|
|
|||
135
MinecraftClient/Mapping/RaycastHelper.cs
Normal file
135
MinecraftClient/Mapping/RaycastHelper.cs
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using MinecraftClient.Protocol;
|
||||
|
||||
namespace MinecraftClient.Mapping
|
||||
{
|
||||
public static class RaycastHelper
|
||||
{
|
||||
public static Tuple<bool, Location, Block> RaycastBlock(McClient handler, double maxDistance, bool includeFluids)
|
||||
{
|
||||
return RaycastBlock(handler.GetWorld(), handler.GetCurrentLocation(), handler.GetYaw(), handler.GetPitch(), maxDistance, includeFluids);
|
||||
}
|
||||
|
||||
public static Tuple<bool, Location, Block> RaycastBlock(World world, Location playerLocation, float yaw, float pitch, double maxDistance, bool includeFluids)
|
||||
{
|
||||
Location camera = playerLocation.EyesLocation();
|
||||
Location rotation = MathHelper.GetRotationVector(yaw, pitch);
|
||||
Location end = camera + (rotation * maxDistance);
|
||||
return Raycast(world, camera, end, includeFluids);
|
||||
}
|
||||
|
||||
public static Tuple<bool, Location, Entity> RaycastEntity(McClient handler, double maxDistance)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static Block CheckRaycastResult(World world, Location location, bool includeFluids)
|
||||
{
|
||||
Block block = world.GetBlock(location);
|
||||
|
||||
if (!includeFluids && MaterialExtensions.IsLiquid(block.Type))
|
||||
return Block.Air;
|
||||
else
|
||||
return block;
|
||||
}
|
||||
|
||||
public static Tuple<bool, Location, Block> Raycast(World world, Location start, Location end, bool includeFluids)
|
||||
{
|
||||
if (start == end)
|
||||
return new(false, Location.Zero, Block.Air);
|
||||
|
||||
double start_x = MathHelper.Lerp(-1.0E-7, start.X, end.X);
|
||||
double start_y = MathHelper.Lerp(-1.0E-7, start.Y, end.Y);
|
||||
double start_z = MathHelper.Lerp(-1.0E-7, start.Z, end.Z);
|
||||
double end_x = MathHelper.Lerp(-1.0E-7, end.X, start.X);
|
||||
double end_y = MathHelper.Lerp(-1.0E-7, end.Y, start.Y);
|
||||
double end_z = MathHelper.Lerp(-1.0E-7, end.Z, start.Z);
|
||||
|
||||
Location res_location = new(Math.Floor(start_x), Math.Floor(start_y), Math.Floor(start_z));
|
||||
Block block = CheckRaycastResult(world, res_location, includeFluids);
|
||||
if (block.Type != Material.Air)
|
||||
return new(true, res_location, block);
|
||||
|
||||
double dx = end_x - start_x;
|
||||
double dy = end_y - start_y;
|
||||
double dz = end_z - start_z;
|
||||
int dx_sign = Math.Sign(dx);
|
||||
int dy_sign = Math.Sign(dy);
|
||||
int dz_sign = Math.Sign(dz);
|
||||
double x_step = dx_sign == 0 ? double.MaxValue : (double)dx_sign / dx;
|
||||
double y_step = dy_sign == 0 ? double.MaxValue : (double)dy_sign / dy;
|
||||
double z_step = dz_sign == 0 ? double.MaxValue : (double)dz_sign / dz;
|
||||
double x_frac = x_step * (dx_sign > 0 ? 1.0 - MathHelper.FractionalPart(start_x) : MathHelper.FractionalPart(start_x));
|
||||
double y_frac = y_step * (dy_sign > 0 ? 1.0 - MathHelper.FractionalPart(start_y) : MathHelper.FractionalPart(start_y));
|
||||
double z_frac = z_step * (dz_sign > 0 ? 1.0 - MathHelper.FractionalPart(start_z) : MathHelper.FractionalPart(start_z));
|
||||
|
||||
while (x_frac <= 1.0 || y_frac <= 1.0 || z_frac <= 1.0)
|
||||
{
|
||||
if (x_frac < y_frac)
|
||||
{
|
||||
if (x_frac < z_frac)
|
||||
{
|
||||
res_location.X += dx_sign;
|
||||
x_frac += x_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_location.Z += dz_sign;
|
||||
z_frac += z_step;
|
||||
}
|
||||
}
|
||||
else if (y_frac < z_frac)
|
||||
{
|
||||
res_location.Y += dy_sign;
|
||||
y_frac += y_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_location.Z += dz_sign;
|
||||
z_frac += z_step;
|
||||
}
|
||||
|
||||
block = CheckRaycastResult(world, res_location, includeFluids);
|
||||
if (block.Type != Material.Air)
|
||||
return new(true, res_location, block);
|
||||
}
|
||||
|
||||
return new(false, Location.Zero, Block.Air);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MathHelper
|
||||
{
|
||||
public static Location GetRotationVector(float yaw, float pitch)
|
||||
{
|
||||
float yaw_rad = -yaw * (MathF.PI / 180);
|
||||
(float yaw_sin, float yaw_cos) = MathF.SinCos(yaw_rad);
|
||||
|
||||
float pitch_rad = pitch * (MathF.PI / 180);
|
||||
(float pitch_sin, float pitch_cos) = MathF.SinCos(pitch_rad);
|
||||
|
||||
return new(yaw_sin * pitch_cos, -pitch_sin, yaw_cos * pitch_cos);
|
||||
}
|
||||
|
||||
public static double Lerp(double delta, double start, double end)
|
||||
{
|
||||
return start + delta * (end - start);
|
||||
}
|
||||
|
||||
public static long Lfloor(double value)
|
||||
{
|
||||
long l = (long)value;
|
||||
return value < (double)l ? l - 1L : l;
|
||||
}
|
||||
|
||||
public static double FractionalPart(double value)
|
||||
{
|
||||
return value - Lfloor(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -144,7 +144,7 @@ namespace MinecraftClient.Mapping
|
|||
if (chunk != null)
|
||||
return chunk.GetBlock(location);
|
||||
}
|
||||
return new Block(0); //Air
|
||||
return Block.Air;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -218,36 +218,5 @@ namespace MinecraftClient.Mapping
|
|||
chunkCnt = 0;
|
||||
chunkLoadNotCompleted = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the location of block of the entity is looking
|
||||
/// </summary>
|
||||
/// <param name="location">Location of the entity</param>
|
||||
/// <param name="yaw">Yaw of the entity</param>
|
||||
/// <param name="pitch">Pitch of the entity</param>
|
||||
/// <returns>Location of the block or empty Location if no block was found</returns>
|
||||
public Location GetLookingBlockLocation(Location location, double yaw, double pitch)
|
||||
{
|
||||
double rotX = (Math.PI / 180) * yaw;
|
||||
double rotY = (Math.PI / 180) * pitch;
|
||||
double x = -Math.Cos(rotY) * Math.Sin(rotX);
|
||||
double y = -Math.Sin(rotY);
|
||||
double z = Math.Cos(rotY) * Math.Cos(rotX);
|
||||
Location vector = new Location(x, y, z);
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Location newVector = vector * i;
|
||||
Location blockLocation = location.EyesLocation() + new Location(newVector.X, newVector.Y, newVector.Z);
|
||||
blockLocation.X = Math.Floor(blockLocation.X);
|
||||
blockLocation.Y = Math.Floor(blockLocation.Y);
|
||||
blockLocation.Z = Math.Floor(blockLocation.Z);
|
||||
Block b = GetBlock(blockLocation);
|
||||
if (b.Type != Material.Air)
|
||||
{
|
||||
return blockLocation;
|
||||
}
|
||||
}
|
||||
return new Location();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue