diff --git a/src/api/java/baritone/api/IBaritone.java b/src/api/java/baritone/api/IBaritone.java index 0cc73b0d1..0913a8c43 100644 --- a/src/api/java/baritone/api/IBaritone.java +++ b/src/api/java/baritone/api/IBaritone.java @@ -17,6 +17,7 @@ package baritone.api; +import baritone.api.behavior.IElytraBehavior; import baritone.api.behavior.ILookBehavior; import baritone.api.behavior.IPathingBehavior; import baritone.api.cache.IWorldProvider; @@ -40,6 +41,12 @@ public interface IBaritone { */ IPathingBehavior getPathingBehavior(); + /** + * @return The {@link IElytraBehavior} instance + * @see IElytraBehavior + */ + IElytraBehavior getElytraBehavior(); + /** * @return The {@link ILookBehavior} instance * @see ILookBehavior diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 9180c6ad7..116df04e0 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -50,6 +50,14 @@ public final class Settings { public final Setting elytraSimulationTicks = new Setting<>(20); public final Setting elytraPitchRange = new Setting<>(25); + /** + * Allow users to control firework usage instead of Baritone. e.g. with their own client modules. + */ + public final Setting elytraUseFireworks = new Setting<>(true); + /** + * Allow Baritone to manage fireworks in the inventory and hotbar + */ + public final Setting elytraInventory = new Setting<>(true); public final Setting elytraFireworkSpeed = new Setting<>(0.6); public final Setting conserveFireworks = new Setting<>(true); public final Setting renderRaytraces = new Setting<>(false); diff --git a/src/api/java/baritone/api/behavior/IElytraBehavior.java b/src/api/java/baritone/api/behavior/IElytraBehavior.java new file mode 100644 index 000000000..dc44eacda --- /dev/null +++ b/src/api/java/baritone/api/behavior/IElytraBehavior.java @@ -0,0 +1,35 @@ +/* + * 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.behavior; + +public interface IElytraBehavior extends IBehavior { + /** + * Pause the current {@link IElytraBehavior} if it is pathing. + */ + void pause(); + + /** + * Resume the current {@link IElytraBehavior} if it is paused. + */ + void resume(); + + /** + * Returns true if the current {@link IElytraBehavior} is actively pathing and not paused. + */ + boolean isActive(); +} diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java new file mode 100644 index 000000000..274e979a0 --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinEntityFireworkRocket.java @@ -0,0 +1,35 @@ +/* + * 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.launch.mixins; + +import baritone.utils.accessor.IEntityFireworkRocket; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityFireworkRocket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(EntityFireworkRocket.class) +public abstract class MixinEntityFireworkRocket implements IEntityFireworkRocket { + @Shadow + private EntityLivingBase boostedEntity; + + @Override + public EntityLivingBase getBoostedEntity() { + return boostedEntity; + } +} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index 982736635..5c221de58 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -16,6 +16,7 @@ "MixinChunkProviderServer", "MixinChunkRenderContainer", "MixinChunkRenderWorker", + "MixinEntityFireworkRocket", "MixinEntityLivingBase", "MixinEntityPlayerSP", "MixinEntityRenderer", @@ -34,4 +35,4 @@ "MixinVboRenderList", "MixinWorldClient" ] -} \ No newline at end of file +} diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 457b49a45..05e1992c9 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -232,6 +232,7 @@ public class Baritone implements IBaritone { return this.commandManager; } + @Override public ElytraBehavior getElytraBehavior() { return this.elytraBehavior; } diff --git a/src/main/java/baritone/behavior/ElytraBehavior.java b/src/main/java/baritone/behavior/ElytraBehavior.java index fa15e1678..3da503066 100644 --- a/src/main/java/baritone/behavior/ElytraBehavior.java +++ b/src/main/java/baritone/behavior/ElytraBehavior.java @@ -18,6 +18,7 @@ package baritone.behavior; import baritone.Baritone; +import baritone.api.behavior.IElytraBehavior; import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.TickEvent; import baritone.api.event.events.type.EventState; @@ -25,11 +26,19 @@ import baritone.api.utils.*; import baritone.behavior.elytra.NetherPathfinderContext; import baritone.behavior.elytra.UnpackedSegment; import baritone.utils.BlockStateInterface; +import baritone.utils.accessor.IEntityFireworkRocket; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.*; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -37,7 +46,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.UnaryOperator; -public final class ElytraBehavior extends Behavior implements Helper { +public final class ElytraBehavior extends Behavior implements IElytraBehavior, Helper { /** * 2b2t seed @@ -53,6 +62,7 @@ public final class ElytraBehavior extends Behavior implements Helper { private final NetherPathfinderContext context; private final PathManager pathManager; private int sinceFirework; + private boolean pawsed = false; public ElytraBehavior(Baritone baritone) { super(baritone); @@ -297,6 +307,7 @@ public final class ElytraBehavior extends Behavior implements Helper { } public void path(BlockPos destination) { + pawsed = false; this.pathManager.pathToDestination(destination); } @@ -305,6 +316,23 @@ public final class ElytraBehavior extends Behavior implements Helper { this.pathManager.clear(); this.aimPos = null; this.sinceFirework = 0; + pawsed = false; + } + + public boolean isActive() { + return !this.pathManager.getPath().isEmpty() && !isPaused(); + } + + public void pause() { + this.pawsed = true; + } + + public void resume() { + this.pawsed = false; + } + + public boolean isPaused() { + return this.pawsed; } @Override @@ -312,6 +340,7 @@ public final class ElytraBehavior extends Behavior implements Helper { if (event.getType() == TickEvent.Type.OUT) { return; } + if (isPaused()) return; this.lines.clear(); final List path = this.pathManager.getPath(); @@ -410,20 +439,69 @@ public final class ElytraBehavior extends Behavior implements Helper { if (forceUseFirework || (!firework && sinceFirework > 10 + && Baritone.settings().elytraUseFireworks.value && useOnDescend && (ctx.player().posY < goingTo.y - 5 || start.distanceTo(new Vec3d(goingTo.x + 0.5, ctx.player().posY, goingTo.z + 0.5)) > 5) // UGH!!!!!!! && currentSpeed < Baritone.settings().elytraFireworkSpeed.value) ) { + if (Baritone.settings().elytraInventory.value) { + final int firstFireworksInHotbar = firstFireworksInHotbar(); + if (firstFireworksInHotbar == -1) { + if (!swapToFireworksInInventory()) { + logDirect("no fireworks"); + return; + } + } else { + ctx.player().inventory.currentItem = firstFireworksInHotbar; + } + } logDirect("firework" + (forceUseFirework ? " takeoff" : "")); ctx.playerController().processRightClick(ctx.player(), ctx.world(), EnumHand.MAIN_HAND); sinceFirework = 0; } } + private boolean swapToFireworksInInventory() { + final int i = firstFireworksInInventory(); + if (i != -1) { + baritone.getInventoryBehavior().attemptToPutOnHotbar(i, (slot) -> slot != 7); + ctx.player().inventory.currentItem = 7; + return true; + } + return false; + } + + private int firstFireworksInInventory() { + final NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < invy.size(); i++) { + if (isBoostingFireworks(invy.get(i))) { + return i; + } + } + return -1; + } + + private int firstFireworksInHotbar() { + final NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < 9; i++) { + if (isBoostingFireworks(invy.get(i))) { + return i; + } + } + return -1; + } + + private boolean isBoostingFireworks(final ItemStack itemStack) { + final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); + return itemStack.getItem() == Items.FIREWORKS + && subCompound != null + && subCompound.hasKey("Flight"); + } + private boolean isFireworkActive() { - // TODO: Validate that the EntityFireworkRocket is attached to ctx.player() return ctx.world().loadedEntityList.stream() - .anyMatch(x -> (x instanceof EntityFireworkRocket) && ((EntityFireworkRocket) x).isAttachedToEntity()); + .filter(x -> x instanceof EntityFireworkRocket) + .anyMatch(x -> Objects.equals(((IEntityFireworkRocket) x).getBoostedEntity(), ctx.player())); } private boolean isClear(final Vec3d start, final Vec3d dest, final Double growAmount) { @@ -688,4 +766,5 @@ public final class ElytraBehavior extends Behavior implements Helper { } return world.getChunk(chunkX, chunkZ); } -} \ No newline at end of file +} + diff --git a/src/main/java/baritone/behavior/InventoryBehavior.java b/src/main/java/baritone/behavior/InventoryBehavior.java index 93dc200cc..5c351adce 100644 --- a/src/main/java/baritone/behavior/InventoryBehavior.java +++ b/src/main/java/baritone/behavior/InventoryBehavior.java @@ -25,8 +25,10 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.inventory.ClickType; import net.minecraft.item.*; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; @@ -150,6 +152,20 @@ public final class InventoryBehavior extends Behavior implements Helper { return bestInd; } + private int firstFireworks() { + final NonNullList invy = ctx.player().inventory.mainInventory; + for (int i = 0; i < invy.size(); i++) { + final ItemStack itemStack = invy.get(i); + final NBTTagCompound subCompound = itemStack.getSubCompound("Fireworks"); + if (itemStack.getItem() == Items.FIREWORKS + && subCompound != null + && subCompound.hasKey("Flight")) { + return i; + } + } + return -1; + } + public boolean hasGenericThrowaway() { for (Item item : Baritone.settings().acceptableThrowawayItems.value) { if (throwaway(false, stack -> item.equals(stack.getItem()))) { diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 1c9ee7882..7c101fd3b 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -81,4 +81,4 @@ public class ElytraCommand extends Command { public List getLongDesc() { return Arrays.asList(); } -} \ No newline at end of file +} diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index ef566bb8d..6ca324ad7 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -89,6 +89,7 @@ public class ExecutionControlCommands { throw new CommandInvalidStateException("Already paused"); } paused[0] = true; + baritone.getElytraBehavior().pause(); logDirect("Paused"); } @@ -123,6 +124,7 @@ public class ExecutionControlCommands { throw new CommandInvalidStateException("Not paused"); } paused[0] = false; + baritone.getElytraBehavior().resume(); logDirect("Resumed"); } diff --git a/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java b/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java new file mode 100644 index 000000000..86c96acd9 --- /dev/null +++ b/src/main/java/baritone/utils/accessor/IEntityFireworkRocket.java @@ -0,0 +1,24 @@ +/* + * 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.utils.accessor; + +import net.minecraft.entity.EntityLivingBase; + +public interface IEntityFireworkRocket { + EntityLivingBase getBoostedEntity(); +}