From 1b04386b01dee65d672d4d1c8861d875903c02d6 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 17 Oct 2021 13:53:55 +0200 Subject: [PATCH 1/7] Allow saving unnamed waypoints by position --- src/main/java/baritone/command/defaults/WaypointsCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index 5d964da4..c0757518 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -129,7 +129,7 @@ public class WaypointsCommand extends Command { if (tag == null) { throw new CommandInvalidStateException(String.format("'%s' is not a tag ", args.consumedString())); } - String name = args.hasAny() ? args.getString() : ""; + String name = (args.hasExactlyOne() || args.hasExactly(4)) ? args.getString() : ""; BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, ctx.playerFeet()) : ctx.playerFeet(); @@ -292,6 +292,7 @@ public class WaypointsCommand extends Command { "Usage:", "> wp [l/list] - List all waypoints.", "> wp - Save your current position as an unnamed waypoint with the specified tag.", + "> wp - Save an unnamed waypoint with the specified tag and position.", "> wp - Save the waypoint with the specified name.", "> wp - Save the waypoint with the specified name and position.", "> wp - Show info on a waypoint by tag.", From 3e69281d61e9920ef5e11c6651412dde21afe903 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 17 Oct 2021 14:06:07 +0200 Subject: [PATCH 2/7] Update usage of #waypoint It now properly reports when either a tag or name can be specified and includes the clear subcommand --- .../baritone/command/defaults/WaypointsCommand.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index c0757518..c484a5ec 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -291,14 +291,16 @@ public class WaypointsCommand extends Command { "", "Usage:", "> wp [l/list] - List all waypoints.", + "> wp - List all waypoints by tag.", "> wp - Save your current position as an unnamed waypoint with the specified tag.", "> wp - Save an unnamed waypoint with the specified tag and position.", "> wp - Save the waypoint with the specified name.", "> wp - Save the waypoint with the specified name and position.", - "> wp - Show info on a waypoint by tag.", - "> wp - Delete a waypoint by tag.", - "> wp - Set a goal to a waypoint by tag.", - "> wp - Set a goal to a waypoint by tag and start pathing." + "> wp - Show info on a waypoint by tag or name.", + "> wp - Delete a waypoint by tag or name.", + "> wp - Delete all waypoints with the specified tag.", + "> wp - Set a goal to a waypoint by tag or name.", + "> wp - Set a goal to a waypoint by tag or name and start pathing." ); } From 3b480dabdb628fdd025406bdf30fee44ef6c0df0 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 17 Oct 2021 14:47:03 +0200 Subject: [PATCH 3/7] Make the tag argument optional, defaulting to USER Listing all possible combinations in the usage as done before would have beed 8 lines just for the save command so I made it one special case, one combined line and a line explaining the defaults in the general waypoint help. Also tab completion does not work when omitting either tag or name, because it starting to tab complete a position right from the first argument would probably only cause confusion and would be harder to implement because of the variable start position (names can even be numbers so it's impossible to do it 100% correctly) --- .../command/defaults/WaypointsCommand.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index c484a5ec..a90828ba 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -125,9 +125,11 @@ public class WaypointsCommand extends Command { ); } } else if (action == Action.SAVE) { - IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString()); + IWaypoint.Tag tag = args.hasAny() ? IWaypoint.Tag.getByName(args.peekString()) : null; if (tag == null) { - throw new CommandInvalidStateException(String.format("'%s' is not a tag ", args.consumedString())); + tag = IWaypoint.Tag.USER; + } else { + args.get(); } String name = (args.hasExactlyOne() || args.hasExactly(4)) ? args.getString() : ""; BetterBlockPos pos = args.hasAny() @@ -289,13 +291,13 @@ public class WaypointsCommand extends Command { "", "Note that the info, delete, and goal commands let you specify a waypoint by tag. If there is more than one waypoint with a certain tag, then they will let you select which waypoint you mean.", "", + "Missing arguments for the save command use the USER tag, creating an unnamed waypoint and your current position as defaults.", + "", "Usage:", "> wp [l/list] - List all waypoints.", "> wp - List all waypoints by tag.", - "> wp - Save your current position as an unnamed waypoint with the specified tag.", - "> wp - Save an unnamed waypoint with the specified tag and position.", - "> wp - Save the waypoint with the specified name.", - "> wp - Save the waypoint with the specified name and position.", + "> wp - Save an unnamed USER waypoint at your current position", + "> wp [tag] [name] [pos] - Save a waypoint with the specified tag, name and position.", "> wp - Show info on a waypoint by tag or name.", "> wp - Delete a waypoint by tag or name.", "> wp - Delete all waypoints with the specified tag.", From 6669d49636ee29903f52f36af047bb0dca0f91d2 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 17 Oct 2021 15:03:27 +0200 Subject: [PATCH 4/7] Add a way to get the creation command for a waypoint --- .../command/defaults/WaypointsCommand.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index a90828ba..e3cd9fcc 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.cache.IWaypoint; import baritone.api.cache.Waypoint; @@ -218,6 +219,20 @@ public class WaypointsCommand extends Command { waypoint.getCreationTimestamp() ) )); + ITextComponent recreateComponent = new TextComponentString("Click to show a command to recreate this waypoint"); + recreateComponent.getStyle().setClickEvent(new ClickEvent( + ClickEvent.Action.SUGGEST_COMMAND, + String.format( + "%s%s save %s %s %s %s %s", + Baritone.settings().prefix.value, // This uses the normal prefix because it is run by the user. + label, + waypoint.getTag().getName(), + waypoint.getName(), + waypoint.getLocation().x, + waypoint.getLocation().y, + waypoint.getLocation().z + ) + )); ITextComponent backComponent = new TextComponentString("Click to return to the waypoints list"); backComponent.getStyle().setClickEvent(new ClickEvent( ClickEvent.Action.RUN_COMMAND, @@ -229,6 +244,7 @@ public class WaypointsCommand extends Command { )); logDirect(deleteComponent); logDirect(goalComponent); + logDirect(recreateComponent); logDirect(backComponent); } else if (action == Action.DELETE) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); From c8966d22baaadcd1e380bef2bc6eb0a5231bf481 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sun, 17 Oct 2021 23:44:21 +0200 Subject: [PATCH 5/7] Don't create a new waypoint every time a bed is clicked. Just the first time and always for the head part. --- .../java/baritone/behavior/MemoryBehavior.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/behavior/MemoryBehavior.java b/src/main/java/baritone/behavior/MemoryBehavior.java index b7d31223..ee8bf0e4 100644 --- a/src/main/java/baritone/behavior/MemoryBehavior.java +++ b/src/main/java/baritone/behavior/MemoryBehavior.java @@ -18,6 +18,7 @@ package baritone.behavior; import baritone.Baritone; +import baritone.api.cache.IWaypoint; import baritone.api.cache.Waypoint; import baritone.api.event.events.BlockInteractEvent; import baritone.api.event.events.PacketEvent; @@ -30,6 +31,7 @@ import baritone.cache.ContainerMemory; import baritone.utils.BlockStateInterface; import net.minecraft.block.Block; import net.minecraft.block.BlockBed; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.network.Packet; @@ -167,8 +169,19 @@ public final class MemoryBehavior extends Behavior { @Override public void onBlockInteract(BlockInteractEvent event) { - if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) { - baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, BetterBlockPos.from(event.getPos()))); + if (event.getType() == BlockInteractEvent.Type.USE) { + BetterBlockPos pos = BetterBlockPos.from(event.getPos()); + IBlockState state = BlockStateInterface.get(ctx, pos); + if (state.getBlock() instanceof BlockBed) { + if (state.getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT) { + pos = pos.offset(state.getValue(BlockBed.FACING)); + } + Set waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(IWaypoint.Tag.BED); + boolean exists = waypoints.stream().map(IWaypoint::getLocation).filter(pos::equals).findFirst().isPresent(); + if (!exists) { + baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, pos)); + } + } } } From 3244b102ad4476b50274226c2df0d3709ed7d7ce Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Mon, 18 Oct 2021 02:42:58 +0200 Subject: [PATCH 6/7] Add a way to restore deleted waypoints Makes using the clickable text less dangerous when there are others writing in chat. --- .../command/defaults/WaypointsCommand.java | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index e3cd9fcc..727d24af 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -42,12 +42,15 @@ import net.minecraft.util.text.event.HoverEvent; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; public class WaypointsCommand extends Command { + private List deletedWaypoints = new ArrayList<>(); + public WaypointsCommand(IBaritone baritone) { super(baritone, "waypoints", "waypoint", "wp"); } @@ -150,7 +153,41 @@ public class WaypointsCommand extends Command { for (IWaypoint waypoint : waypoints) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); } - logDirect(String.format("Cleared %d waypoints", waypoints.length)); + deletedWaypoints.addAll(Arrays.asList(waypoints)); + ITextComponent textComponent = new TextComponentString(String.format("Cleared %d waypoints, click to restore them", waypoints.length)); + textComponent.getStyle().setClickEvent(new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + String.format( + "%s%s restore @ %s", + FORCE_COMMAND_PREFIX, + label, + Stream.of(waypoints).map(wp -> Long.toString(wp.getCreationTimestamp())).collect(Collectors.joining(" ")) + ) + )); + logDirect(textComponent); + } else if (action == Action.RESTORE) { + List waypoints = new ArrayList<>(); + if (args.peekString().equals("@")) { + args.get(); + // no args.requireMin(1) because if the user clears an empty tag there is nothing to restore + while (args.hasAny()) { + long timestamp = args.getAs(Long.class); + for (IWaypoint waypoint : deletedWaypoints) { + if (waypoint.getCreationTimestamp() == timestamp) { + waypoints.add(waypoint); + break; + } + } + } + } else { + args.requireExactly(1); + int size = deletedWaypoints.size(); + int amount = Math.min(size, args.getAs(Integer.class)); + waypoints = new ArrayList<>(deletedWaypoints.subList(size - amount, size)); + } + waypoints.forEach(ForWaypoints.waypoints(this.baritone)::addWaypoint); + deletedWaypoints.removeIf(waypoints::contains); + logDirect(String.format("Restored %d waypoints", waypoints.size())); } else { IWaypoint[] waypoints = args.getDatatypeFor(ForWaypoints.INSTANCE); IWaypoint waypoint = null; @@ -248,7 +285,18 @@ public class WaypointsCommand extends Command { logDirect(backComponent); } else if (action == Action.DELETE) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); - logDirect("That waypoint has successfully been deleted"); + deletedWaypoints.add(waypoint); + ITextComponent textComponent = new TextComponentString("That waypoint has successfully been deleted, click to restore it"); + textComponent.getStyle().setClickEvent(new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + String.format( + "%s%s restore @ %s", + FORCE_COMMAND_PREFIX, + label, + waypoint.getCreationTimestamp() + ) + )); + logDirect(textComponent); } else if (action == Action.GOAL) { Goal goal = new GoalBlock(waypoint.getLocation()); baritone.getCustomGoalProcess().setGoal(goal); @@ -280,6 +328,8 @@ public class WaypointsCommand extends Command { .sortAlphabetically() .filterPrefix(args.getString()) .stream(); + } else if (action == Action.RESTORE) { + return Stream.empty(); } else { return args.tabCompleteDatatype(ForWaypoints.INSTANCE); } @@ -316,6 +366,7 @@ public class WaypointsCommand extends Command { "> wp [tag] [name] [pos] - Save a waypoint with the specified tag, name and position.", "> wp - Show info on a waypoint by tag or name.", "> wp - Delete a waypoint by tag or name.", + "> wp - Restore the last n deleted waypoints.", "> wp - Delete all waypoints with the specified tag.", "> wp - Set a goal to a waypoint by tag or name.", "> wp - Set a goal to a waypoint by tag or name and start pathing." @@ -328,6 +379,7 @@ public class WaypointsCommand extends Command { SAVE("save", "s"), INFO("info", "show", "i"), DELETE("delete", "d"), + RESTORE("restore"), GOAL("goal", "g"), GOTO("goto"); private final String[] names; From 724162f37f1489bbdfd8b6220facd8e83b4c1b2f Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 19 Oct 2021 01:17:23 +0200 Subject: [PATCH 7/7] Store deleted waypoints per world Different dimensions are actually different worlds and the user might expect the wapoints to be restorable until they leave the server, so discrading them when the world changes would be too early. --- .../java/baritone/command/defaults/WaypointsCommand.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index 727d24af..5a45686a 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.cache.IWaypoint; import baritone.api.cache.Waypoint; +import baritone.api.cache.IWorldData; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.datatypes.ForWaypoints; @@ -49,7 +50,7 @@ import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; public class WaypointsCommand extends Command { - private List deletedWaypoints = new ArrayList<>(); + private Map> deletedWaypoints = new HashMap<>(); public WaypointsCommand(IBaritone baritone) { super(baritone, "waypoints", "waypoint", "wp"); @@ -153,7 +154,7 @@ public class WaypointsCommand extends Command { for (IWaypoint waypoint : waypoints) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); } - deletedWaypoints.addAll(Arrays.asList(waypoints)); + deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).addAll(Arrays.asList(waypoints)); ITextComponent textComponent = new TextComponentString(String.format("Cleared %d waypoints, click to restore them", waypoints.length)); textComponent.getStyle().setClickEvent(new ClickEvent( ClickEvent.Action.RUN_COMMAND, @@ -167,6 +168,7 @@ public class WaypointsCommand extends Command { logDirect(textComponent); } else if (action == Action.RESTORE) { List waypoints = new ArrayList<>(); + List deletedWaypoints = this.deletedWaypoints.getOrDefault(baritone.getWorldProvider().getCurrentWorld(), Collections.emptyList()); if (args.peekString().equals("@")) { args.get(); // no args.requireMin(1) because if the user clears an empty tag there is nothing to restore @@ -285,7 +287,7 @@ public class WaypointsCommand extends Command { logDirect(backComponent); } else if (action == Action.DELETE) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); - deletedWaypoints.add(waypoint); + deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).add(waypoint); ITextComponent textComponent = new TextComponentString("That waypoint has successfully been deleted, click to restore it"); textComponent.getStyle().setClickEvent(new ClickEvent( ClickEvent.Action.RUN_COMMAND,