mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
137 lines
5.5 KiB
C#
137 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using MinecraftClient.Mapping;
|
|
using MinecraftClient.Pathing.Core;
|
|
|
|
namespace MinecraftClient.Pathing.Execution
|
|
{
|
|
public static class PathSegmentBuilder
|
|
{
|
|
public static List<PathSegment> FromPath(IReadOnlyList<PathNode> nodes)
|
|
{
|
|
var segments = new List<PathSegment>(Math.Max(0, nodes.Count - 1));
|
|
for (int i = 1; i < nodes.Count; i++)
|
|
{
|
|
PathSegment current = CreatePreview(nodes[i - 1], nodes[i]);
|
|
PathSegment? next = i + 1 < nodes.Count ? CreatePreview(nodes[i], nodes[i + 1]) : null;
|
|
PathSegment? nextNext = i + 2 < nodes.Count ? CreatePreview(nodes[i + 1], nodes[i + 2]) : null;
|
|
|
|
PathTransitionType exitTransition = Classify(current, next);
|
|
segments.Add(new PathSegment
|
|
{
|
|
Start = current.Start,
|
|
End = current.End,
|
|
MoveType = current.MoveType,
|
|
ParkourProfile = current.ParkourProfile,
|
|
ExitTransition = exitTransition,
|
|
ExitHints = BuildHints(current, next, nextNext, exitTransition),
|
|
PreserveSprint = exitTransition is PathTransitionType.ContinueStraight or PathTransitionType.PrepareJump
|
|
});
|
|
}
|
|
return segments;
|
|
}
|
|
|
|
private static PathTransitionType Classify(PathSegment current, PathSegment? next)
|
|
{
|
|
if (next is null)
|
|
return PathTransitionType.FinalStop;
|
|
|
|
if (next.MoveType is MoveType.Parkour or MoveType.Ascend)
|
|
return PathTransitionType.PrepareJump;
|
|
|
|
if (current.MoveType is MoveType.Parkour or MoveType.Descend or MoveType.Fall)
|
|
return PathTransitionType.LandingRecovery;
|
|
|
|
if (current.HeadingX == next.HeadingX && current.HeadingZ == next.HeadingZ)
|
|
return PathTransitionType.ContinueStraight;
|
|
|
|
return PathTransitionType.Turn;
|
|
}
|
|
|
|
private static PathSegment CreatePreview(PathNode start, PathNode end)
|
|
{
|
|
return new PathSegment
|
|
{
|
|
Start = new Location(start.X + 0.5, start.Y, start.Z + 0.5),
|
|
End = new Location(end.X + 0.5, end.Y, end.Z + 0.5),
|
|
MoveType = end.MoveUsed,
|
|
ParkourProfile = end.ParkourProfile
|
|
};
|
|
}
|
|
|
|
private static PathTransitionHints BuildHints(PathSegment current, PathSegment? next, PathSegment? nextNext,
|
|
PathTransitionType exitTransition)
|
|
{
|
|
if (next is null)
|
|
{
|
|
return new PathTransitionHints(
|
|
DesiredHeadingX: current.HeadingX,
|
|
DesiredHeadingZ: current.HeadingZ,
|
|
MinExitSpeed: 0.0,
|
|
MaxExitSpeed: 0.02,
|
|
RequireStableFooting: true,
|
|
RequireGrounded: true,
|
|
RequireJumpReady: false,
|
|
AllowAirBrake: false,
|
|
HorizonTicks: 12);
|
|
}
|
|
|
|
if (next.MoveType is MoveType.Parkour or MoveType.Ascend)
|
|
{
|
|
return new PathTransitionHints(
|
|
DesiredHeadingX: next.HeadingX,
|
|
DesiredHeadingZ: next.HeadingZ,
|
|
MinExitSpeed: next.MoveType == MoveType.Parkour ? 0.10 : 0.0,
|
|
MaxExitSpeed: double.PositiveInfinity,
|
|
RequireStableFooting: false,
|
|
RequireGrounded: true,
|
|
RequireJumpReady: true,
|
|
AllowAirBrake: false,
|
|
HorizonTicks: 10);
|
|
}
|
|
|
|
bool turning = current.HeadingX != next.HeadingX || current.HeadingZ != next.HeadingZ;
|
|
bool nextImmediatelyJumps = nextNext is not null
|
|
&& nextNext.MoveType is (MoveType.Parkour or MoveType.Ascend);
|
|
|
|
if (turning)
|
|
{
|
|
return new PathTransitionHints(
|
|
DesiredHeadingX: next.HeadingX,
|
|
DesiredHeadingZ: next.HeadingZ,
|
|
MinExitSpeed: nextImmediatelyJumps ? 0.05 : 0.0,
|
|
MaxExitSpeed: nextImmediatelyJumps ? 0.16 : 0.05,
|
|
RequireStableFooting: !nextImmediatelyJumps,
|
|
RequireGrounded: true,
|
|
RequireJumpReady: nextImmediatelyJumps,
|
|
AllowAirBrake: true,
|
|
HorizonTicks: 12);
|
|
}
|
|
|
|
if (exitTransition == PathTransitionType.LandingRecovery)
|
|
{
|
|
return new PathTransitionHints(
|
|
DesiredHeadingX: next.HeadingX,
|
|
DesiredHeadingZ: next.HeadingZ,
|
|
MinExitSpeed: 0.03,
|
|
MaxExitSpeed: double.PositiveInfinity,
|
|
RequireStableFooting: false,
|
|
RequireGrounded: true,
|
|
RequireJumpReady: false,
|
|
AllowAirBrake: true,
|
|
HorizonTicks: 12);
|
|
}
|
|
|
|
return new PathTransitionHints(
|
|
DesiredHeadingX: next.HeadingX,
|
|
DesiredHeadingZ: next.HeadingZ,
|
|
MinExitSpeed: 0.06,
|
|
MaxExitSpeed: double.PositiveInfinity,
|
|
RequireStableFooting: false,
|
|
RequireGrounded: false,
|
|
RequireJumpReady: false,
|
|
AllowAirBrake: false,
|
|
HorizonTicks: 8);
|
|
}
|
|
}
|
|
}
|