diff --git a/MinecraftClient/Commands/UseItem.cs b/MinecraftClient/Commands/UseItem.cs index 4a0fe1f6..40993c7a 100644 --- a/MinecraftClient/Commands/UseItem.cs +++ b/MinecraftClient/Commands/UseItem.cs @@ -1,6 +1,8 @@ using Brigadier.NET; using Brigadier.NET.Builder; using MinecraftClient.CommandHandler; +using MinecraftClient.Inventory; +using MinecraftClient.Mapping; using static MinecraftClient.CommandHandler.CmdResult; namespace MinecraftClient.Commands @@ -8,7 +10,7 @@ namespace MinecraftClient.Commands class UseItem : Command { public override string CmdName { get { return "useitem"; } } - public override string CmdUsage { get { return "useitem"; } } + public override string CmdUsage { get { return "useitem [x] [y] [z]"; } } public override string CmdDesc { get { return Translations.cmd_useitem_desc; } } public override void RegisterCommand(CommandDispatcher dispatcher) @@ -21,6 +23,8 @@ namespace MinecraftClient.Commands dispatcher.Register(l => l.Literal(CmdName) .Executes(r => DoUseItem(r.Source)) + .Then(l => l.Argument("Location", MccArguments.Location()) + .Executes(r => DoUseItemAtLocation(r.Source, MccArguments.GetLocation(r, "Location")))) .Then(l => l.Literal("_help") .Executes(r => GetUsage(r.Source, string.Empty)) .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName))) @@ -43,8 +47,34 @@ namespace MinecraftClient.Commands if (!handler.GetInventoryEnabled()) return r.SetAndReturn(Status.FailNeedInventory); + if (handler.GetTerrainEnabled()) + { + const double maxDistance = 4.5; + var raycast = RaycastHelper.RaycastBlock(handler, maxDistance, false); + if (raycast.Item1 && raycast.Item3.Type != Material.Air) + { + handler.PlaceBlock(raycast.Item2, Direction.Up, lookAtBlock: true); + handler.DoAnimation((int)Hand.MainHand); + return r.SetAndReturn(Status.Done, Translations.cmd_useitem_use); + } + } + handler.UseItemOnHand(); return r.SetAndReturn(Status.Done, Translations.cmd_useitem_use); } + + private int DoUseItemAtLocation(CmdResult r, Location block) + { + McClient handler = CmdResult.currentHandler!; + if (!handler.GetTerrainEnabled()) + return r.SetAndReturn(Status.FailNeedTerrain); + + Location current = handler.GetCurrentLocation(); + block = block.ToAbsolute(current).ToFloor(); + handler.PlaceBlock(block, Direction.Up, lookAtBlock: true); + handler.DoAnimation((int)Hand.MainHand); + return r.SetAndReturn(Status.Done, Translations.cmd_useitem_use); + } + } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index be0914bc..48568f0f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -4563,6 +4563,7 @@ namespace MinecraftClient.Protocol.Handlers try { var packet = new List(); + var (cursorX, cursorY, cursorZ) = GetFaceHitCursor(face); switch (protocolVersion) { @@ -4598,9 +4599,9 @@ namespace MinecraftClient.Protocol.Handlers break; } - packet.AddRange(dataTypes.GetFloat(0.5f)); // cursorX - packet.AddRange(dataTypes.GetFloat(0.5f)); // cursorY - packet.AddRange(dataTypes.GetFloat(0.5f)); // cursorZ + packet.AddRange(dataTypes.GetFloat(cursorX)); // cursorX + packet.AddRange(dataTypes.GetFloat(cursorY)); // cursorY + packet.AddRange(dataTypes.GetFloat(cursorZ)); // cursorZ if(protocolVersion >= MC_1_14_Version) packet.Add(0); // insideBlock = false @@ -4628,6 +4629,17 @@ namespace MinecraftClient.Protocol.Handlers } } + private static (float x, float y, float z) GetFaceHitCursor(Direction face) => face switch + { + Direction.Up => (0.5f, 1.0f, 0.5f), + Direction.Down => (0.5f, 0.0f, 0.5f), + Direction.North => (0.5f, 0.5f, 0.0f), + Direction.South => (0.5f, 0.5f, 1.0f), + Direction.West => (0.0f, 0.5f, 0.5f), + Direction.East => (1.0f, 0.5f, 0.5f), + _ => (0.5f, 0.5f, 0.5f), + }; + public bool SendHeldItemChange(short slot) { try diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index d76a3bed..cce4eda2 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -4481,7 +4481,7 @@ namespace MinecraftClient { } /// - /// Looks up a localized string similar to Use (left click) an item on the hand. + /// Looks up a localized string similar to Use the item in your hand, optionally on a specific block. /// internal static string cmd_useitem_desc { get { diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 10b2ef3a..45662bd5 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -1518,7 +1518,7 @@ You can use "/chunk status {0:0.0} {1:0.0} {2:0.0}" to check the chunk loading s Useblock at ({0:0.0}, {1:0.0}, {2:0.0}) {3}. - Use (left click) an item on the hand + Use the item in your hand, optionally on a specific block Used an item @@ -2347,4 +2347,4 @@ see item details. {0} {1} - + \ No newline at end of file diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 6d167257..833d5dd3 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -837,7 +837,7 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q - **Description:** - Use item in the hand, this can be used to do a right click on items which open menus on servers. + Use the item in your hand, including use-on-block actions like shovel flattening.

Note

@@ -857,6 +857,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /useitem ``` + Use the item on a specific block: + + ``` + /useitem + ``` +