Minecraft-Console-Client/MinecraftClient/Commands/Useblock.cs

80 lines
3.3 KiB
C#

using System;
using Brigadier.NET;
using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler;
using MinecraftClient.Inventory;
using MinecraftClient.Mapping;
using static MinecraftClient.CommandHandler.CmdResult;
namespace MinecraftClient.Commands
{
class Useblock : Command
{
public override string CmdName { get { return "useblock"; } }
public override string CmdUsage { get { return "useblock <x> <y> <z> [mainhand|offhand]"; } }
public override string CmdDesc { get { return Translations.cmd_useblock_desc; } }
public override void RegisterCommand(CommandDispatcher<CmdResult> dispatcher)
{
dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CmdName)
.Executes(r => GetUsage(r.Source, string.Empty))
)
);
dispatcher.Register(l => l.Literal(CmdName)
.Then(l => l.Argument("Location", MccArguments.Location())
.Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"), Hand.MainHand))
.Then(l => l.Literal("mainhand")
.Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"), Hand.MainHand)))
.Then(l => l.Literal("offhand")
.Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"), Hand.OffHand))))
.Then(l => l.Literal("_help")
.Executes(r => GetUsage(r.Source, string.Empty))
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
);
}
private int GetUsage(CmdResult r, string? cmd)
{
return r.SetAndReturn(cmd switch
{
#pragma warning disable format // @formatter:off
_ => GetCmdDescTranslated(),
#pragma warning restore format // @formatter:on
});
}
private int UseBlockAtLocation(CmdResult r, Location block, Hand hand)
{
McClient handler = CmdResult.currentHandler!;
if (!handler.GetTerrainEnabled())
return r.SetAndReturn(Status.FailNeedTerrain);
Location current = handler.GetCurrentLocation();
block = block.ToAbsolute(current).ToFloor();
Location blockCenter = block.ToCenter();
bool res = handler.PlaceBlock(block, GetFaceNearestPlayer(current, blockCenter), hand, lookAtBlock: true);
return r.SetAndReturn(string.Format(Translations.cmd_useblock_use, blockCenter.X, blockCenter.Y, blockCenter.Z, res ? "succeeded" : "failed"), res);
}
private static Direction GetFaceNearestPlayer(Location playerLocation, Location blockCenter)
{
double dx = playerLocation.X - blockCenter.X;
double dy = playerLocation.Y - blockCenter.Y;
double dz = playerLocation.Z - blockCenter.Z;
double absX = Math.Abs(dx);
double absY = Math.Abs(dy);
double absZ = Math.Abs(dz);
if (absX >= absY && absX >= absZ)
return dx >= 0 ? Direction.East : Direction.West;
if (absY >= absZ)
return dy >= 0 ? Direction.Up : Direction.Down;
return dz >= 0 ? Direction.South : Direction.North;
}
}
}