From 20b03d00049dc3f4a75c8d8e9aa83eca1bd7ac55 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 18 Jan 2019 13:43:19 -0600 Subject: [PATCH] No more setSprinting --- .../api/event/events/SprintStateEvent.java | 42 +++++++++++++++++++ .../listener/AbstractGameEventListener.java | 3 ++ .../event/listener/IGameEventListener.java | 8 ++++ .../launch/mixins/MixinEntityPlayerSP.java | 16 +++++++ .../baritone/behavior/PathingBehavior.java | 12 ++++-- .../java/baritone/event/GameEventHandler.java | 5 +++ .../baritone/pathing/path/PathExecutor.java | 38 +++++++---------- 7 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 src/api/java/baritone/api/event/events/SprintStateEvent.java diff --git a/src/api/java/baritone/api/event/events/SprintStateEvent.java b/src/api/java/baritone/api/event/events/SprintStateEvent.java new file mode 100644 index 00000000..e7b8d193 --- /dev/null +++ b/src/api/java/baritone/api/event/events/SprintStateEvent.java @@ -0,0 +1,42 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.event.events; + +import baritone.api.event.events.type.ManagedPlayerEvent; +import net.minecraft.client.entity.EntityPlayerSP; + +/** + * @author Brady + * @since 1/18/2019 + */ +public class SprintStateEvent extends ManagedPlayerEvent { + + private Boolean state; + + public SprintStateEvent(EntityPlayerSP player) { + super(player); + } + + public final void setState(boolean state) { + this.state = state; + } + + public final Boolean getState() { + return this.state; + } +} diff --git a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java index 135c29a7..71045768 100644 --- a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java @@ -57,6 +57,9 @@ public interface AbstractGameEventListener extends IGameEventListener { @Override default void onPlayerRotationMove(RotationMoveEvent event) {} + @Override + default void onPlayerSprintState(SprintStateEvent event) {} + @Override default void onBlockInteract(BlockInteractEvent event) {} diff --git a/src/api/java/baritone/api/event/listener/IGameEventListener.java b/src/api/java/baritone/api/event/listener/IGameEventListener.java index 0572cbe9..dc471e5f 100644 --- a/src/api/java/baritone/api/event/listener/IGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/IGameEventListener.java @@ -109,6 +109,14 @@ public interface IGameEventListener { */ void onPlayerRotationMove(RotationMoveEvent event); + /** + * Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate} + * + * @param event The event + * @see EntityPlayerSP#onLivingUpdate() + */ + void onPlayerSprintState(SprintStateEvent event); + /** * Called when the local player interacts with a block, whether it is breaking or opening/placing. * diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 9c9509f0..2f87b72d 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -21,8 +21,10 @@ import baritone.api.BaritoneAPI; import baritone.api.behavior.IPathingBehavior; import baritone.api.event.events.ChatEvent; import baritone.api.event.events.PlayerUpdateEvent; +import baritone.api.event.events.SprintStateEvent; import baritone.api.event.events.type.EventState; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.player.PlayerCapabilities; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -87,4 +89,18 @@ public class MixinEntityPlayerSP { IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior(); return !pathingBehavior.isPathing() && capabilities.allowFlying; } + + @Redirect( + method = "onLivingUpdate", + at = @At( + value = "INVOKE", + target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z" + ) + ) + private boolean isKeyDown(KeyBinding keyBinding) { + EntityPlayerSP self = (EntityPlayerSP) (Object) this; + SprintStateEvent event = new SprintStateEvent(self); + BaritoneAPI.getProvider().getBaritoneForPlayer(self).getGameEventHandler().onPlayerSprintState(event); + return event.getState() == null ? keyBinding.isKeyDown() : event.getState(); + } } diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 8c5fb8a4..92eb242e 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -19,10 +19,7 @@ package baritone.behavior; import baritone.Baritone; import baritone.api.behavior.IPathingBehavior; -import baritone.api.event.events.PathEvent; -import baritone.api.event.events.PlayerUpdateEvent; -import baritone.api.event.events.RenderEvent; -import baritone.api.event.events.TickEvent; +import baritone.api.event.events.*; import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalXZ; @@ -98,6 +95,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, dispatchEvents(); } + @Override + public void onPlayerSprintState(SprintStateEvent event) { + if (current != null) { + event.setState(current.isSprinting()); + } + } + private void tickPath() { if (pauseRequestedLastTick && safeToCancel) { pauseRequestedLastTick = false; diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index e85c46de..3b327002 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -121,6 +121,11 @@ public final class GameEventHandler implements IEventBus, Helper { listeners.forEach(l -> l.onPlayerRotationMove(event)); } + @Override + public void onPlayerSprintState(SprintStateEvent event) { + listeners.forEach(l -> l.onPlayerSprintState(event)); + } + @Override public void onBlockInteract(BlockInteractEvent event) { listeners.forEach(l -> l.onBlockInteract(event)); diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index cad144aa..ef856f42 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -79,6 +79,8 @@ public class PathExecutor implements IPathExecutor, Helper { private PathingBehavior behavior; private IPlayerContext ctx; + private boolean sprintNextTick; + public PathExecutor(PathingBehavior behavior, IPath path) { this.behavior = behavior; this.ctx = behavior.ctx; @@ -269,7 +271,7 @@ public class PathExecutor implements IPathExecutor, Helper { onTick(); return true; } else { - sprintIfRequested(); + sprintNextTick = shouldSprintNextTick(); ticksOnCurrent++; if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.get()) { // only cancel if the total time has exceeded the initial estimate @@ -371,21 +373,17 @@ public class PathExecutor implements IPathExecutor, Helper { return true; } - private void sprintIfRequested() { + private boolean shouldSprintNextTick() { // first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint if (!new CalculationContext(behavior.baritone).canSprint) { behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); - ctx.player().setSprinting(false); - return; + return false; } // if the movement requested sprinting, then we're done if (behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT)) { behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); - if (!ctx.player().isSprinting()) { - ctx.player().setSprinting(true); - } - return; + return true; } // we'll take it from here, no need for minecraft to see we're holding down control and sprint for us @@ -397,30 +395,23 @@ public class PathExecutor implements IPathExecutor, Helper { if (((MovementDescend) current).safeMode()) { logDebug("Sprinting would be unsafe"); - ctx.player().setSprinting(false); - return; + return false; } IMovement next = path.movements().get(pathPosition + 1); if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) { // a descend then an ascend in the same direction - if (!ctx.player().isSprinting()) { - ctx.player().setSprinting(true); - } pathPosition++; // okay to skip clearKeys and / or onChangeInPathPosition here since this isn't possible to repeat, since it's asymmetric logDebug("Skipping descend to straight ascend"); - return; + return true; } if (canSprintInto(ctx, current, next)) { if (ctx.playerFeet().equals(current.getDest())) { pathPosition++; onChangeInPathPosition(); } - if (!ctx.player().isSprinting()) { - ctx.player().setSprinting(true); - } - return; + return true; } //logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection())); } @@ -430,14 +421,11 @@ public class PathExecutor implements IPathExecutor, Helper { BlockPos center = current.getSrc().up(); if (ctx.player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false); - if (!ctx.player().isSprinting()) { - ctx.player().setSprinting(true); - } - return; + return true; } } } - ctx.player().setSprinting(false); + return false; } private static boolean canSprintInto(IPlayerContext ctx, IMovement current, IMovement next) { @@ -532,4 +520,8 @@ public class PathExecutor implements IPathExecutor, Helper { public Set toWalkInto() { return Collections.unmodifiableSet(toWalkInto); } + + public boolean isSprinting() { + return sprintNextTick; + } }