From e14afe54e3c8f187f127c879ee9dd61d85665de6 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 May 2023 10:12:12 -0500 Subject: [PATCH 01/39] Create CraftCommand.java --- src/main/java/baritone/command/defaults/CraftCommand.java | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/java/baritone/command/defaults/CraftCommand.java diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -0,0 +1 @@ + From aa18fdf9df79420cb7b2b3c238aa6b056fd42281 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 May 2023 10:28:33 -0500 Subject: [PATCH 02/39] Update CraftCommand.java --- .../command/defaults/CraftCommand.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index 8b1378917..433824de7 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -1 +1,62 @@ +/* + * 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.command.defaults; + +import baritone.api.IBaritone; +import baritone.api.command.Command; +import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.datatypes.BlockById; +import baritone.api.command.datatypes.ForBlockOptionalMeta; +import baritone.api.command.datatypes.RelativeCoordinate; +import baritone.api.command.datatypes.RelativeGoal; +import baritone.api.command.exception.CommandException; +import baritone.api.pathing.goals.Goal; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.BlockOptionalMeta; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +public class CraftCommand extends Command { + + protected CraftCommand(IBaritone baritone) { + super(baritone, "craft"); + } + + @Override + public void execute(String label, IArgConsumer args) throws CommandException { + destination = minecraft:crafting_table + baritone.getGetToBlockProcess().getToBlock(destination); + } + + @Override + public String getShortDesc() { + return "Go to a crafting table"; + } + + @Override + public List getLongDesc() { + return Arrays.asList( + "The craft command tells Baritone to head towards the closest crafting table, then begin crafting", + "", + "Usage:", + "> craft - Go to a crafting table, wherever it is in the world", + ); + } +} From 5c0fe9ca7aaebdc4a9414e4f8a1224805611c694 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 May 2023 10:47:18 -0500 Subject: [PATCH 03/39] Update Settings.java --- src/api/java/baritone/api/Settings.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 38661d8be..5ee76cf1d 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -68,6 +68,11 @@ public final class Settings { * Allow Baritone to move items in your inventory to your hotbar */ public final Setting allowInventory = new Setting<>(false); + + /** + * Allow Baritone to auto craft items with "craft command is called. + */ + public final Setting allowAutoCraft = new Setting<>(false); /** * Wait this many ticks between InventoryBehavior moving inventory items From 15efa2b1df01126073fe768e7284a5ad42a60893 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 May 2023 10:48:28 -0500 Subject: [PATCH 04/39] More info in description --- src/main/java/baritone/command/defaults/CraftCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index 433824de7..50fc29aa5 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -53,7 +53,8 @@ public String getShortDesc() { @Override public List getLongDesc() { return Arrays.asList( - "The craft command tells Baritone to head towards the closest crafting table, then begin crafting", + "The craft command tells Baritone to head towards the closest crafting table, then begin crafting. ", + "Requires allowInventory to be true", "", "Usage:", "> craft - Go to a crafting table, wherever it is in the world", From 4c5a5dad3c00199fce71a0f3bb7d509eef369f93 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 May 2023 10:53:23 -0500 Subject: [PATCH 05/39] Update DefaultCommands.java --- src/main/java/baritone/command/defaults/DefaultCommands.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java index 901fda713..061ba8330 100644 --- a/src/main/java/baritone/command/defaults/DefaultCommands.java +++ b/src/main/java/baritone/command/defaults/DefaultCommands.java @@ -34,6 +34,7 @@ public static List createAll(IBaritone baritone) { new SetCommand(baritone), new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"), new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"), + new CraftCommand(baritone), new GoalCommand(baritone), new GotoCommand(baritone), new PathCommand(baritone), From 31976c13a1f23916b129b1fc9a9e01eedf1e396e Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 May 2023 14:28:45 -0500 Subject: [PATCH 06/39] Add chat notifier --- src/main/java/baritone/command/defaults/CraftCommand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index 50fc29aa5..ea7a57719 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -41,8 +41,9 @@ protected CraftCommand(IBaritone baritone) { @Override public void execute(String label, IArgConsumer args) throws CommandException { - destination = minecraft:crafting_table - baritone.getGetToBlockProcess().getToBlock(destination); + logDirect("Crafting"); + table = minecraft:crafting_table + baritone.getGetToBlockProcess().getToBlock(table); } @Override From 1547431c1cfc402305e3cbbf53e7cbeece976d06 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 25 May 2023 15:26:05 +0200 Subject: [PATCH 07/39] prototype --- src/api/java/baritone/api/IBaritone.java | 6 + .../api/process/ICraftingProcess.java | 69 ++++ src/main/java/baritone/Baritone.java | 7 + .../command/defaults/CraftCommand.java | 43 ++- .../baritone/process/CraftingProcess.java | 329 ++++++++++++++++++ 5 files changed, 439 insertions(+), 15 deletions(-) create mode 100644 src/api/java/baritone/api/process/ICraftingProcess.java create mode 100644 src/main/java/baritone/process/CraftingProcess.java diff --git a/src/api/java/baritone/api/IBaritone.java b/src/api/java/baritone/api/IBaritone.java index 0cc73b0d1..8430d606d 100644 --- a/src/api/java/baritone/api/IBaritone.java +++ b/src/api/java/baritone/api/IBaritone.java @@ -88,6 +88,12 @@ public interface IBaritone { */ IGetToBlockProcess getGetToBlockProcess(); + /** + * @return The {@link IGetToBlockProcess} instance + * @see IGetToBlockProcess + */ + ICraftingProcess getCraftingProcess(); + /** * @return The {@link IWorldProvider} instance * @see IWorldProvider diff --git a/src/api/java/baritone/api/process/ICraftingProcess.java b/src/api/java/baritone/api/process/ICraftingProcess.java new file mode 100644 index 000000000..293388cc5 --- /dev/null +++ b/src/api/java/baritone/api/process/ICraftingProcess.java @@ -0,0 +1,69 @@ +/* + * 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.process; + +import baritone.api.utils.BlockOptionalMeta; +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.crafting.IRecipe; + +import java.util.ArrayList; + +/** + * but it rescans the world every once in a while so it doesn't get fooled by its cache + */ +public interface ICraftingProcess extends IBaritoneProcess { + + //todo this is a copy paste of the IgetToBlockProcess and hasnt been cleand up + + + void getToBlock(BlockOptionalMeta block); + + default void getToBlock(Block block) { + getToBlock(new BlockOptionalMeta(block)); + } + + boolean blacklistClosest(); + + /** + * @param item that should be crafted + * @return Can the item be crafted in a crafting table? + */ + boolean hasCraftingRecipe(Item item); + + /** + * @param item that should be crafted + * @return List of all recipies that result in the provided Item. + */ + ArrayList getCraftingRecipes(Item item); + + /** + * Checks if the requested item can be crafted the requested amount of times. + * @param item that should be crafted + * @param amount how much of that item is wanted. + * @return + */ + boolean canCraft(Item item, int amount); + + /** + * Executes the crafting of the requested item the requested amount of times. + * @param item that should be crafted + * @param amount how much of that item is wanted. + */ + void craft(Item item, int amount); +} diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 61db54211..47e6976d7 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -80,6 +80,7 @@ public class Baritone implements IBaritone { private ExploreProcess exploreProcess; private BackfillProcess backfillProcess; private FarmProcess farmProcess; + private CraftingProcess craftingProcess; private InventoryPauserProcess inventoryPauserProcess; private PathingControlManager pathingControlManager; @@ -116,6 +117,7 @@ public class Baritone implements IBaritone { this.pathingControlManager.registerProcess(exploreProcess = new ExploreProcess(this)); this.pathingControlManager.registerProcess(backfillProcess = new BackfillProcess(this)); this.pathingControlManager.registerProcess(farmProcess = new FarmProcess(this)); + this.pathingControlManager.registerProcess(craftingProcess = new CraftingProcess(this)); this.pathingControlManager.registerProcess(inventoryPauserProcess = new InventoryPauserProcess(this)); } @@ -148,6 +150,11 @@ public GetToBlockProcess getGetToBlockProcess() { return this.getToBlockProcess; } + @Override + public CraftingProcess getCraftingProcess() { + return this.craftingProcess; + } + @Override public IPlayerContext getPlayerContext() { return this.playerContext; diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index ea7a57719..f96c63d52 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -20,14 +20,8 @@ import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; -import baritone.api.command.datatypes.BlockById; -import baritone.api.command.datatypes.ForBlockOptionalMeta; -import baritone.api.command.datatypes.RelativeCoordinate; -import baritone.api.command.datatypes.RelativeGoal; import baritone.api.command.exception.CommandException; -import baritone.api.pathing.goals.Goal; -import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.BlockOptionalMeta; +import net.minecraft.item.Item; import java.util.Arrays; import java.util.List; @@ -41,24 +35,43 @@ protected CraftCommand(IBaritone baritone) { @Override public void execute(String label, IArgConsumer args) throws CommandException { - logDirect("Crafting"); - table = minecraft:crafting_table - baritone.getGetToBlockProcess().getToBlock(table); + //todo works for simple items like "stick" but items like "granite" aren't parsed because they are stone:1 + Item item = Item.getByNameOrId(args.getString()); + + int amount = args.hasAny() ? args.getAs(Integer.class) : 1; + + if (item == null) { + logDirect("invalid Item"); + } else if (!baritone.getCraftingProcess().hasCraftingRecipe(item)) { + logDirect("no crafting recipe for "+item.getTranslationKey()+" found."); + /*todo missing feature check if we can craft before we walk to a crafting table + } else if (BaritoneAPI.getSettings().allowAutoCraft.value && !baritone.getCraftingProcess().canCraft(item, amount)) { + logDirect("trying to craft "+ item.getTranslationKey()); + logDirect("not enough resources in inventory"); + /**/ + } else { + baritone.getCraftingProcess().craft(item, amount); + } + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) throws CommandException { + //todo add autocomplete for items + return null; } @Override public String getShortDesc() { - return "Go to a crafting table"; + return "Craft a item."; } @Override public List getLongDesc() { return Arrays.asList( - "The craft command tells Baritone to head towards the closest crafting table, then begin crafting. ", - "Requires allowInventory to be true", + "Go to a crafting table and craft a item.", "", "Usage:", - "> craft - Go to a crafting table, wherever it is in the world", + "> craft - Go to a crafting table, and craft a item." ); } -} +} \ No newline at end of file diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java new file mode 100644 index 000000000..9ea3028e6 --- /dev/null +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -0,0 +1,329 @@ +/* + * 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.process; + +import baritone.Baritone; +import baritone.api.BaritoneAPI; +import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalBlock; +import baritone.api.pathing.goals.GoalGetToBlock; +import baritone.api.pathing.goals.GoalTwoBlocks; +import baritone.api.process.ICraftingProcess; +import baritone.api.process.PathingCommand; +import baritone.api.process.PathingCommandType; +import baritone.api.utils.BlockOptionalMeta; +import baritone.api.utils.BlockOptionalMetaLookup; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; +import baritone.api.utils.input.Input; +import baritone.pathing.movement.CalculationContext; +import baritone.utils.BaritoneProcessHelper; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiCrafting; +import net.minecraft.client.util.RecipeItemHelper; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ClickType; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.ContainerWorkbench; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.stats.RecipeBook; +import net.minecraft.util.math.BlockPos; + +import java.util.*; + +public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { + + //todo this is a copy paste of the getToBlockProcess and hasnt been cleand up + + private BlockOptionalMeta gettingTo; + private List knownLocations; + private List blacklist; // locations we failed to calc to + private BlockPos start; + + private int tickCount = 0; + private int arrivalTickCount = 0; + private RecipeBook book; + private Item item; + private int amount; + + public CraftingProcess(Baritone baritone) { + super(baritone); + } + + @Override + public void getToBlock(BlockOptionalMeta block) { + onLostControl(); + gettingTo = block; + start = ctx.playerFeet(); + blacklist = new ArrayList<>(); + arrivalTickCount = 0; + rescan(new ArrayList<>(), new GetToBlockCalculationContext(false)); + } + + @Override + public boolean isActive() { + return item != null && amount >= 1; + } + + @Override + public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (baritone.getGetToBlockProcess().isActive()) { + return new PathingCommand(null, PathingCommandType.DEFER); + } else { + //logDirect("we no longer pathing so its time to craft"); + try { + int outputCount = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftResult.getStackInSlot(420).getCount(); + int inputCount = 0; + for (int i = 0; i < 9; i++) { + ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + inputCount = itemStack.getCount(); + break; + } + } + if (outputCount * inputCount >= amount || inputCount == 64) { + int a = ctx.player().openContainer.windowId; + int b = 0; //slot id. for crafting table output it is 0 + int c = 0; //idk isnt used + Minecraft.getMinecraft().playerController.windowClick(a, b, c, ClickType.QUICK_MOVE, ctx.player()); + logDirect("we finished crafting"); + onLostControl(); + } + if (mc.currentScreen instanceof GuiCrafting) { + moveItemsToCraftingGrid(); + } + } catch (Exception e) { + //you probably closed the crafting window. + onLostControl(); + } + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } + } + + private void moveItemsToCraftingGrid() { + int a = baritone.getPlayerContext().player().openContainer.windowId; + IRecipe recipe = getCraftingRecipes(item).get(0); + boolean b = GuiScreen.isShiftKeyDown(); + //create a package to move a recipe into the crafting grid. + //CPacketPlaceRecipe placeRecipe = new CPacketPlaceRecipe(a, recipe, b); + + for (int i = 0; i*recipe.getRecipeOutput().getCount() < amount; i++) { + mc.playerController.func_194338_a(a,recipe, b, ctx.player()); + } + + //send package + //baritone.getPlayerContext().player().connection.sendPacket(placeRecipe); + } + + // blacklist the closest block and its adjacent blocks + public synchronized boolean blacklistClosest() { + List newBlacklist = new ArrayList<>(); + knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add); + outer: + while (true) { + for (BlockPos known : knownLocations) { + for (BlockPos blacklist : newBlacklist) { + if (areAdjacent(known, blacklist)) { // directly adjacent + newBlacklist.add(known); + knownLocations.remove(known); + continue outer; + } + } + } + // i can't do break; (codacy gets mad), and i can't do if(true){break}; (codacy gets mad) + // so i will do this + switch (newBlacklist.size()) { + default: + break outer; + } + } + logDebug("Blacklisting unreachable locations " + newBlacklist); + blacklist.addAll(newBlacklist); + return !newBlacklist.isEmpty(); + } + + @Override + public boolean hasCraftingRecipe(Item item) { + ArrayList recipes = getCraftingRecipes(item); + return !recipes.isEmpty(); + } + + @Override + public ArrayList getCraftingRecipes(Item item) { + ArrayList recipes = new ArrayList<>(); + for (IRecipe recipe : CraftingManager.REGISTRY) { + if (recipe.getRecipeOutput().getItem().equals(item)) { + recipes.add(recipe); + } + } + return recipes; + } + + @Override + public boolean canCraft(Item item, int amount) { + RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); + IRecipe recipe = getCraftingRecipes(item).get(0); + boolean canDo = recipeItemHelper.canCraft(recipe, null, amount); + return canDo; + + /*EntityPlayerSP player = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player(); + RecipeBook book = player.getRecipeBook(); + ArrayList invSlots = new ArrayList<>(); + invSlots.addAll(player.inventory.mainInventory); + invSlots.addAll(player.inventory.offHandInventory); + ArrayList recipes = getCraftingRecipes(item); + for (IRecipe recipe : recipes) { + logDirect(recipe.getRecipeOutput().getTranslationKey()); + } + IRecipe recipeInUse = recipes.get(0); + int timesToCraft = (amount / recipeInUse.getRecipeOutput().getCount()) + (amount % recipeInUse.getRecipeOutput().getCount() == 0 ? 0 : 1); + ArrayList ingredients = new ArrayList<>(); + ingredients.addAll(recipeInUse.getIngredients()); + for (Ingredient ingredient : ingredients) { + ingredient.getMatchingStacks()[0].getCount()*timesToCraft; + } + //idk lets just assume we can + return true;/**/ + } + + @Override + public void craft(Item item, int amount) { + //active = true; + book = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player().getRecipeBook(); + this.item = item; + this.amount = amount; + //todo check for crafting tables that are close. if none are found place one. else gotoBlock. + baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); + //todo once we are at the crafting table start crafting + + //todo check if crafting gui is open + //book.setGuiOpen(true); + //book.setFilteringCraftable(true); + //RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); + logDirect("im totaly crafting right now"); + } + + // this is to signal to MineProcess that we don't care about the allowBreak setting + // it is NOT to be used to actually calculate a path + public class GetToBlockCalculationContext extends CalculationContext { + + public GetToBlockCalculationContext(boolean forUseOnAnotherThread) { + super(CraftingProcess.super.baritone, forUseOnAnotherThread); + } + + @Override + public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) { + return 1; + } + } + + // safer than direct double comparison from distanceSq + private boolean areAdjacent(BlockPos posA, BlockPos posB) { + int diffX = Math.abs(posA.getX() - posB.getX()); + int diffY = Math.abs(posA.getY() - posB.getY()); + int diffZ = Math.abs(posA.getZ() - posB.getZ()); + return (diffX + diffY + diffZ) == 1; + } + + @Override + public synchronized void onLostControl() { + amount = 0; + item = null; + + gettingTo = null; + knownLocations = null; + start = null; + blacklist = null; + baritone.getInputOverrideHandler().clearAllKeys(); + } + + @Override + public String displayName0() { + if (knownLocations.isEmpty()) { + return "Exploring randomly to find " + gettingTo + ", no known locations"; + } + return "Get To " + gettingTo + ", " + knownLocations.size() + " known locations"; + } + + private synchronized void rescan(List known, CalculationContext context) { + List positions = MineProcess.searchWorld(context, new BlockOptionalMetaLookup(gettingTo), 64, known, blacklist, Collections.emptyList()); + positions.removeIf(blacklist::contains); + knownLocations = positions; + } + + private Goal createGoal(BlockPos pos) { + if (walkIntoInsteadOfAdjacent(gettingTo.getBlock())) { + return new GoalTwoBlocks(pos); + } + if (blockOnTopMustBeRemoved(gettingTo.getBlock()) && baritone.bsi.get0(pos.up()).isBlockNormalCube()) { + return new GoalBlock(pos.up()); + } + return new GoalGetToBlock(pos); + } + + private boolean rightClick() { + for (BlockPos pos : knownLocations) { + Optional reachable = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); + if (reachable.isPresent()) { + baritone.getLookBehavior().updateTarget(reachable.get(), true); + if (knownLocations.contains(ctx.getSelectedBlock().orElse(null))) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); // TODO find some way to right click even if we're in an ESC menu + System.out.println(ctx.player().openContainer); + if (!(ctx.player().openContainer instanceof ContainerPlayer)) { + return true; + } + } + if (arrivalTickCount++ > 20) { + logDirect("Right click timed out"); + return true; + } + return false; // trying to right click, will do it next tick or so + } + } + logDirect("Arrived but failed to right click open"); + return true; + } + + private boolean walkIntoInsteadOfAdjacent(Block block) { + if (!Baritone.settings().enterPortal.value) { + return false; + } + return block == Blocks.PORTAL; + } + + private boolean rightClickOnArrival(Block block) { + if (!Baritone.settings().rightClickContainerOnArrival.value) { + return false; + } + return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.LIT_FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST; + } + + private boolean blockOnTopMustBeRemoved(Block block) { + if (!rightClickOnArrival(block)) { // only if we plan to actually open it on arrival + return false; + } + // only these chests; you can open a crafting table or furnace even with a block on top + return block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST; + } +} From a443dcc0bc9c1210680ff90bb501c0fdde8f69fd Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Fri, 26 May 2023 01:04:12 +0200 Subject: [PATCH 08/39] not sure if this goes in the right direction --- .../api/process/ICraftingProcess.java | 13 - .../launch/mixins/MixinGuiRecipeBook.java | 45 ++++ .../launch/mixins/MixinRecipeBookPage.java | 36 +++ src/launch/resources/mixins.baritone.json | 2 + .../baritone/process/CraftingProcess.java | 248 ++++-------------- 5 files changed, 127 insertions(+), 217 deletions(-) create mode 100644 src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java create mode 100644 src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java diff --git a/src/api/java/baritone/api/process/ICraftingProcess.java b/src/api/java/baritone/api/process/ICraftingProcess.java index 293388cc5..1105e621a 100644 --- a/src/api/java/baritone/api/process/ICraftingProcess.java +++ b/src/api/java/baritone/api/process/ICraftingProcess.java @@ -17,8 +17,6 @@ package baritone.api.process; -import baritone.api.utils.BlockOptionalMeta; -import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.crafting.IRecipe; @@ -29,17 +27,6 @@ */ public interface ICraftingProcess extends IBaritoneProcess { - //todo this is a copy paste of the IgetToBlockProcess and hasnt been cleand up - - - void getToBlock(BlockOptionalMeta block); - - default void getToBlock(Block block) { - getToBlock(new BlockOptionalMeta(block)); - } - - boolean blacklistClosest(); - /** * @param item that should be crafted * @return Can the item be crafted in a crafting table? diff --git a/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java b/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java new file mode 100644 index 000000000..a39a75f0d --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java @@ -0,0 +1,45 @@ +/* + * 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.IMixinGuiRecipeBook; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.gui.recipebook.GuiRecipeBook; +import net.minecraft.client.gui.recipebook.RecipeBookPage; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(GuiRecipeBook.class) +public class MixinGuiRecipeBook implements IMixinGuiRecipeBook { + + @Shadow + private GuiTextField searchBar; + + @Shadow + private RecipeBookPage recipeBookPage; + + @Override + public GuiTextField getSearchBar() { + return searchBar; + } + + @Override + public RecipeBookPage getRecipeBookPage() { + return recipeBookPage; + } +} diff --git a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java new file mode 100644 index 000000000..2d702b8c2 --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java @@ -0,0 +1,36 @@ +/* + * 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 net.minecraft.client.gui.recipebook.RecipeBookPage; +import net.minecraft.client.gui.recipebook.RecipeList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; + +@Mixin(RecipeBookPage.class) +public class MixinRecipeBookPage { + + @Shadow + private List recipeLists; + + public List getRecipeLists() { + return recipeLists; + } +} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index 982736635..93953e8e0 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -19,6 +19,7 @@ "MixinEntityLivingBase", "MixinEntityPlayerSP", "MixinEntityRenderer", + "MixinGuiRecipeBook", "MixinGuiScreen", "MixinItemStack", "MixinItemTool", @@ -27,6 +28,7 @@ "MixinNetHandlerPlayClient", "MixinNetworkManager", "MixinPlayerControllerMP", + "MixinRecipeBookPage", "MixinRenderChunk", "MixinRenderList", "MixinStateImplementation", diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 9ea3028e6..8d0fa0b05 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -18,37 +18,21 @@ package baritone.process; import baritone.Baritone; -import baritone.api.BaritoneAPI; -import baritone.api.pathing.goals.Goal; -import baritone.api.pathing.goals.GoalBlock; -import baritone.api.pathing.goals.GoalGetToBlock; -import baritone.api.pathing.goals.GoalTwoBlocks; import baritone.api.process.ICraftingProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; -import baritone.api.utils.BlockOptionalMeta; -import baritone.api.utils.BlockOptionalMetaLookup; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; -import baritone.api.utils.input.Input; -import baritone.pathing.movement.CalculationContext; import baritone.utils.BaritoneProcessHelper; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiCrafting; +import net.minecraft.client.gui.recipebook.RecipeList; import net.minecraft.client.util.RecipeItemHelper; import net.minecraft.init.Blocks; import net.minecraft.inventory.ClickType; -import net.minecraft.inventory.ContainerPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.stats.RecipeBook; -import net.minecraft.util.math.BlockPos; import java.util.*; @@ -56,14 +40,6 @@ public final class CraftingProcess extends BaritoneProcessHelper implements ICra //todo this is a copy paste of the getToBlockProcess and hasnt been cleand up - private BlockOptionalMeta gettingTo; - private List knownLocations; - private List blacklist; // locations we failed to calc to - private BlockPos start; - - private int tickCount = 0; - private int arrivalTickCount = 0; - private RecipeBook book; private Item item; private int amount; @@ -71,15 +47,6 @@ public CraftingProcess(Baritone baritone) { super(baritone); } - @Override - public void getToBlock(BlockOptionalMeta block) { - onLostControl(); - gettingTo = block; - start = ctx.playerFeet(); - blacklist = new ArrayList<>(); - arrivalTickCount = 0; - rescan(new ArrayList<>(), new GetToBlockCalculationContext(false)); - } @Override public boolean isActive() { @@ -89,12 +56,15 @@ public boolean isActive() { @Override public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (baritone.getGetToBlockProcess().isActive()) { + //we are pathing to a table and therefor have to wait. return new PathingCommand(null, PathingCommandType.DEFER); } else { - //logDirect("we no longer pathing so its time to craft"); + //we no longer pathing so it's time to craft try { - int outputCount = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftResult.getStackInSlot(420).getCount(); + //todo if we cant craft more because of stack limit or lack of resources grab result and either throw low resource exception or continue crafting + int outputCount = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftResult.getStackInSlot(420).getCount(); //items per crafting cycle int inputCount = 0; + //todo this should, in order to consider low or non stackable items, search for the lowest non zero stack count for (int i = 0; i < 9; i++) { ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { @@ -102,19 +72,33 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa break; } } + + //if we have enought or reached stack limit on a input stack grab the result and subtract it from the target amount. + // todo dynamicly check input stack limit based on lowest stackable item if (outputCount * inputCount >= amount || inputCount == 64) { - int a = ctx.player().openContainer.windowId; - int b = 0; //slot id. for crafting table output it is 0 - int c = 0; //idk isnt used - Minecraft.getMinecraft().playerController.windowClick(a, b, c, ClickType.QUICK_MOVE, ctx.player()); - logDirect("we finished crafting"); - onLostControl(); + int windowId = ctx.player().openContainer.windowId; + int slotID = 0; //slot id. for crafting table output it is 0 + int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used + mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); + amount = amount - (outputCount * inputCount); + + if (amount <= 0) { + //we finished crafting + ctx.player().closeScreen(); + onLostControl(); + } } if (mc.currentScreen instanceof GuiCrafting) { - moveItemsToCraftingGrid(); + if (canCraft(item, amount)) { + moveItemsToCraftingGrid(); + } else { + logDirect("we cant craft"); //this should be a more meaning full message also if we check craftability beforehand we should never run out of resources mid crafting + mc.player.closeScreen(); + onLostControl(); + } } } catch (Exception e) { - //you probably closed the crafting window. + //you probably closed the crafting window while crafting process was still running. onLostControl(); } return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); @@ -122,95 +106,43 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } private void moveItemsToCraftingGrid() { - int a = baritone.getPlayerContext().player().openContainer.windowId; - IRecipe recipe = getCraftingRecipes(item).get(0); - boolean b = GuiScreen.isShiftKeyDown(); - //create a package to move a recipe into the crafting grid. - //CPacketPlaceRecipe placeRecipe = new CPacketPlaceRecipe(a, recipe, b); + int windowId = baritone.getPlayerContext().player().openContainer.windowId; + IRecipe recipe = getCraftingRecipes(item).get(0); //todo better way to get a recipe + //try to put the recipe the required amount of times in to the crafting grid. for (int i = 0; i*recipe.getRecipeOutput().getCount() < amount; i++) { - mc.playerController.func_194338_a(a,recipe, b, ctx.player()); + mc.playerController.func_194338_a(windowId,recipe, GuiScreen.isShiftKeyDown(), ctx.player()); } - - //send package - //baritone.getPlayerContext().player().connection.sendPacket(placeRecipe); - } - - // blacklist the closest block and its adjacent blocks - public synchronized boolean blacklistClosest() { - List newBlacklist = new ArrayList<>(); - knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add); - outer: - while (true) { - for (BlockPos known : knownLocations) { - for (BlockPos blacklist : newBlacklist) { - if (areAdjacent(known, blacklist)) { // directly adjacent - newBlacklist.add(known); - knownLocations.remove(known); - continue outer; - } - } - } - // i can't do break; (codacy gets mad), and i can't do if(true){break}; (codacy gets mad) - // so i will do this - switch (newBlacklist.size()) { - default: - break outer; - } - } - logDebug("Blacklisting unreachable locations " + newBlacklist); - blacklist.addAll(newBlacklist); - return !newBlacklist.isEmpty(); } @Override public boolean hasCraftingRecipe(Item item) { - ArrayList recipes = getCraftingRecipes(item); - return !recipes.isEmpty(); - } - - @Override - public ArrayList getCraftingRecipes(Item item) { ArrayList recipes = new ArrayList<>(); for (IRecipe recipe : CraftingManager.REGISTRY) { if (recipe.getRecipeOutput().getItem().equals(item)) { recipes.add(recipe); } } - return recipes; + return !recipes.isEmpty(); + } + + @Override + public ArrayList getCraftingRecipes(Item item) { + ((GuiCrafting)mc.currentScreen).func_194310_f().getSearchBar().setText("itemname"); + List recipeLists = ((GuiCrafting)mc.currentScreen).func_194310_f().getRecipeBookPage().getRecipeLists(); + return (ArrayList) recipeLists.get(0).getRecipes(); } @Override public boolean canCraft(Item item, int amount) { RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); - IRecipe recipe = getCraftingRecipes(item).get(0); - boolean canDo = recipeItemHelper.canCraft(recipe, null, amount); - return canDo; - - /*EntityPlayerSP player = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player(); - RecipeBook book = player.getRecipeBook(); - ArrayList invSlots = new ArrayList<>(); - invSlots.addAll(player.inventory.mainInventory); - invSlots.addAll(player.inventory.offHandInventory); - ArrayList recipes = getCraftingRecipes(item); - for (IRecipe recipe : recipes) { - logDirect(recipe.getRecipeOutput().getTranslationKey()); - } - IRecipe recipeInUse = recipes.get(0); - int timesToCraft = (amount / recipeInUse.getRecipeOutput().getCount()) + (amount % recipeInUse.getRecipeOutput().getCount() == 0 ? 0 : 1); - ArrayList ingredients = new ArrayList<>(); - ingredients.addAll(recipeInUse.getIngredients()); - for (Ingredient ingredient : ingredients) { - ingredient.getMatchingStacks()[0].getCount()*timesToCraft; - } - //idk lets just assume we can - return true;/**/ + IRecipe recipe = getCraftingRecipes(item).stream().findAny().get(); + return recipeItemHelper.canCraft(recipe, null, amount); } @Override public void craft(Item item, int amount) { - //active = true; - book = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player().getRecipeBook(); + //book = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player().getRecipeBook(); this.item = item; this.amount = amount; //todo check for crafting tables that are close. if none are found place one. else gotoBlock. @@ -224,106 +156,14 @@ public void craft(Item item, int amount) { logDirect("im totaly crafting right now"); } - // this is to signal to MineProcess that we don't care about the allowBreak setting - // it is NOT to be used to actually calculate a path - public class GetToBlockCalculationContext extends CalculationContext { - - public GetToBlockCalculationContext(boolean forUseOnAnotherThread) { - super(CraftingProcess.super.baritone, forUseOnAnotherThread); - } - - @Override - public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) { - return 1; - } - } - - // safer than direct double comparison from distanceSq - private boolean areAdjacent(BlockPos posA, BlockPos posB) { - int diffX = Math.abs(posA.getX() - posB.getX()); - int diffY = Math.abs(posA.getY() - posB.getY()); - int diffZ = Math.abs(posA.getZ() - posB.getZ()); - return (diffX + diffY + diffZ) == 1; - } - @Override public synchronized void onLostControl() { amount = 0; item = null; - - gettingTo = null; - knownLocations = null; - start = null; - blacklist = null; - baritone.getInputOverrideHandler().clearAllKeys(); } @Override public String displayName0() { - if (knownLocations.isEmpty()) { - return "Exploring randomly to find " + gettingTo + ", no known locations"; - } - return "Get To " + gettingTo + ", " + knownLocations.size() + " known locations"; - } - - private synchronized void rescan(List known, CalculationContext context) { - List positions = MineProcess.searchWorld(context, new BlockOptionalMetaLookup(gettingTo), 64, known, blacklist, Collections.emptyList()); - positions.removeIf(blacklist::contains); - knownLocations = positions; - } - - private Goal createGoal(BlockPos pos) { - if (walkIntoInsteadOfAdjacent(gettingTo.getBlock())) { - return new GoalTwoBlocks(pos); - } - if (blockOnTopMustBeRemoved(gettingTo.getBlock()) && baritone.bsi.get0(pos.up()).isBlockNormalCube()) { - return new GoalBlock(pos.up()); - } - return new GoalGetToBlock(pos); - } - - private boolean rightClick() { - for (BlockPos pos : knownLocations) { - Optional reachable = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance()); - if (reachable.isPresent()) { - baritone.getLookBehavior().updateTarget(reachable.get(), true); - if (knownLocations.contains(ctx.getSelectedBlock().orElse(null))) { - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); // TODO find some way to right click even if we're in an ESC menu - System.out.println(ctx.player().openContainer); - if (!(ctx.player().openContainer instanceof ContainerPlayer)) { - return true; - } - } - if (arrivalTickCount++ > 20) { - logDirect("Right click timed out"); - return true; - } - return false; // trying to right click, will do it next tick or so - } - } - logDirect("Arrived but failed to right click open"); - return true; - } - - private boolean walkIntoInsteadOfAdjacent(Block block) { - if (!Baritone.settings().enterPortal.value) { - return false; - } - return block == Blocks.PORTAL; - } - - private boolean rightClickOnArrival(Block block) { - if (!Baritone.settings().rightClickContainerOnArrival.value) { - return false; - } - return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.LIT_FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST; - } - - private boolean blockOnTopMustBeRemoved(Block block) { - if (!rightClickOnArrival(block)) { // only if we plan to actually open it on arrival - return false; - } - // only these chests; you can open a crafting table or furnace even with a block on top - return block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST; + return "Crafting "+amount+"x "+item.getTranslationKey(); } } From e7a36ec025ea4edb88404490ee440d03aa2004e9 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Fri, 26 May 2023 10:49:49 +0200 Subject: [PATCH 09/39] resolving some mixin problems --- .../api/process/ICraftingProcess.java | 4 +-- .../launch/mixins/MixinGuiRecipeBook.java | 22 ++++---------- .../launch/mixins/MixinRecipeBookPage.java | 12 +++----- .../baritone/process/CraftingProcess.java | 13 +++++---- .../utils/accessor/IMixinGuiRecipeBook.java | 27 +++++++++++++++++ .../utils/accessor/IMixinRecipeBookPage.java | 29 +++++++++++++++++++ 6 files changed, 76 insertions(+), 31 deletions(-) create mode 100644 src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java create mode 100644 src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java diff --git a/src/api/java/baritone/api/process/ICraftingProcess.java b/src/api/java/baritone/api/process/ICraftingProcess.java index 1105e621a..a7b522468 100644 --- a/src/api/java/baritone/api/process/ICraftingProcess.java +++ b/src/api/java/baritone/api/process/ICraftingProcess.java @@ -20,7 +20,7 @@ import net.minecraft.item.Item; import net.minecraft.item.crafting.IRecipe; -import java.util.ArrayList; +import java.util.List; /** * but it rescans the world every once in a while so it doesn't get fooled by its cache @@ -37,7 +37,7 @@ public interface ICraftingProcess extends IBaritoneProcess { * @param item that should be crafted * @return List of all recipies that result in the provided Item. */ - ArrayList getCraftingRecipes(Item item); + List getCraftingRecipes(Item item); /** * Checks if the requested item can be crafted the requested amount of times. diff --git a/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java b/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java index a39a75f0d..f0d90b867 100644 --- a/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java +++ b/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java @@ -22,24 +22,14 @@ import net.minecraft.client.gui.recipebook.GuiRecipeBook; import net.minecraft.client.gui.recipebook.RecipeBookPage; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(GuiRecipeBook.class) -public class MixinGuiRecipeBook implements IMixinGuiRecipeBook { +public abstract class MixinGuiRecipeBook implements IMixinGuiRecipeBook{ - @Shadow - private GuiTextField searchBar; + @Accessor("searchBar") + public abstract GuiTextField getSearchBar(); - @Shadow - private RecipeBookPage recipeBookPage; - - @Override - public GuiTextField getSearchBar() { - return searchBar; - } - - @Override - public RecipeBookPage getRecipeBookPage() { - return recipeBookPage; - } + @Accessor("recipeBookPage") + public abstract RecipeBookPage getRecipeBookPage(); } diff --git a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java index 2d702b8c2..2a56497b7 100644 --- a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java +++ b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java @@ -20,17 +20,13 @@ import net.minecraft.client.gui.recipebook.RecipeBookPage; import net.minecraft.client.gui.recipebook.RecipeList; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Accessor; import java.util.List; @Mixin(RecipeBookPage.class) -public class MixinRecipeBookPage { +public abstract class MixinRecipeBookPage { - @Shadow - private List recipeLists; - - public List getRecipeLists() { - return recipeLists; - } + @Accessor("recipeLists") + public abstract List getRecipeLists(); } diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 8d0fa0b05..8e3554ee5 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -22,6 +22,8 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.utils.BaritoneProcessHelper; +import baritone.utils.accessor.IMixinGuiRecipeBook; +import baritone.utils.accessor.IMixinRecipeBookPage; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiCrafting; import net.minecraft.client.gui.recipebook.RecipeList; @@ -34,7 +36,8 @@ import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; -import java.util.*; +import java.util.ArrayList; +import java.util.List; public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { @@ -127,10 +130,10 @@ public boolean hasCraftingRecipe(Item item) { } @Override - public ArrayList getCraftingRecipes(Item item) { - ((GuiCrafting)mc.currentScreen).func_194310_f().getSearchBar().setText("itemname"); - List recipeLists = ((GuiCrafting)mc.currentScreen).func_194310_f().getRecipeBookPage().getRecipeLists(); - return (ArrayList) recipeLists.get(0).getRecipes(); + public List getCraftingRecipes(Item item) { + ((IMixinGuiRecipeBook)((GuiCrafting)mc.currentScreen).func_194310_f()).getSearchBar().setText("itemname"); + List recipeLists = ((IMixinRecipeBookPage)((IMixinGuiRecipeBook)((GuiCrafting)mc.currentScreen).func_194310_f()).getRecipeBookPage()).getRecipeLists(); + return recipeLists.get(0).getRecipes(); } @Override diff --git a/src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java b/src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java new file mode 100644 index 000000000..1265289b0 --- /dev/null +++ b/src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java @@ -0,0 +1,27 @@ +/* + * 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.client.gui.GuiTextField; +import net.minecraft.client.gui.recipebook.RecipeBookPage; + +public interface IMixinGuiRecipeBook { + + GuiTextField getSearchBar(); + RecipeBookPage getRecipeBookPage(); +} diff --git a/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java b/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java new file mode 100644 index 000000000..bb3280803 --- /dev/null +++ b/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java @@ -0,0 +1,29 @@ +/* + * 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.client.gui.GuiTextField; +import net.minecraft.client.gui.recipebook.RecipeBookPage; +import net.minecraft.client.gui.recipebook.RecipeList; + +import java.util.List; + +public interface IMixinRecipeBookPage { + + List getRecipeLists(); +} From 98c1d649fadf02e2392db050dcdd678a5e566211 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Mon, 29 May 2023 01:05:02 +0200 Subject: [PATCH 10/39] revert some changes as they didnt worked out. --- .../launch/mixins/MixinRecipeBookPage.java | 3 +- .../baritone/process/CraftingProcess.java | 41 ++++++++----------- .../baritone/process/GetToBlockProcess.java | 4 ++ .../utils/accessor/IMixinRecipeBookPage.java | 2 - 4 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java index 2a56497b7..a703cc5d7 100644 --- a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java +++ b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java @@ -17,6 +17,7 @@ package baritone.launch.mixins; +import baritone.utils.accessor.IMixinRecipeBookPage; import net.minecraft.client.gui.recipebook.RecipeBookPage; import net.minecraft.client.gui.recipebook.RecipeList; import org.spongepowered.asm.mixin.Mixin; @@ -25,7 +26,7 @@ import java.util.List; @Mixin(RecipeBookPage.class) -public abstract class MixinRecipeBookPage { +public abstract class MixinRecipeBookPage implements IMixinRecipeBookPage { @Accessor("recipeLists") public abstract List getRecipeLists(); diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 8e3554ee5..af1a5e6be 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -22,11 +22,8 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.utils.BaritoneProcessHelper; -import baritone.utils.accessor.IMixinGuiRecipeBook; -import baritone.utils.accessor.IMixinRecipeBookPage; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiCrafting; -import net.minecraft.client.gui.recipebook.RecipeList; import net.minecraft.client.util.RecipeItemHelper; import net.minecraft.init.Blocks; import net.minecraft.inventory.ClickType; @@ -37,7 +34,6 @@ import net.minecraft.item.crafting.IRecipe; import java.util.ArrayList; -import java.util.List; public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { @@ -86,22 +82,24 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa amount = amount - (outputCount * inputCount); if (amount <= 0) { + logDirect("done"); //we finished crafting ctx.player().closeScreen(); onLostControl(); } } if (mc.currentScreen instanceof GuiCrafting) { - if (canCraft(item, amount)) { + //if (canCraft(item, amount)) { moveItemsToCraftingGrid(); - } else { + /*} else { logDirect("we cant craft"); //this should be a more meaning full message also if we check craftability beforehand we should never run out of resources mid crafting mc.player.closeScreen(); onLostControl(); - } + }/**/ } } catch (Exception e) { //you probably closed the crafting window while crafting process was still running. + logDirect("error"); onLostControl(); } return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); @@ -120,43 +118,36 @@ private void moveItemsToCraftingGrid() { @Override public boolean hasCraftingRecipe(Item item) { + ArrayList recipes = getCraftingRecipes(item); + return !recipes.isEmpty(); + } + + @Override + public ArrayList getCraftingRecipes(Item item) { ArrayList recipes = new ArrayList<>(); for (IRecipe recipe : CraftingManager.REGISTRY) { if (recipe.getRecipeOutput().getItem().equals(item)) { recipes.add(recipe); } } - return !recipes.isEmpty(); - } - - @Override - public List getCraftingRecipes(Item item) { - ((IMixinGuiRecipeBook)((GuiCrafting)mc.currentScreen).func_194310_f()).getSearchBar().setText("itemname"); - List recipeLists = ((IMixinRecipeBookPage)((IMixinGuiRecipeBook)((GuiCrafting)mc.currentScreen).func_194310_f()).getRecipeBookPage()).getRecipeLists(); - return recipeLists.get(0).getRecipes(); + return recipes; } @Override public boolean canCraft(Item item, int amount) { RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); - IRecipe recipe = getCraftingRecipes(item).stream().findAny().get(); - return recipeItemHelper.canCraft(recipe, null, amount); + IRecipe recipe = getCraftingRecipes(item).get(0); + boolean canDo = recipeItemHelper.canCraft(recipe, null, amount); + return canDo; } @Override public void craft(Item item, int amount) { - //book = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player().getRecipeBook(); this.item = item; this.amount = amount; //todo check for crafting tables that are close. if none are found place one. else gotoBlock. baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); - //todo once we are at the crafting table start crafting - - //todo check if crafting gui is open - //book.setGuiOpen(true); - //book.setFilteringCraftable(true); - //RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); - logDirect("im totaly crafting right now"); + logDirect("im totally crafting right now"); } @Override diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 16fc3dda5..e0b79920e 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -175,6 +175,10 @@ private boolean areAdjacent(BlockPos posA, BlockPos posB) { return (diffX + diffY + diffZ) == 1; } + public boolean isTemporary() { + return baritone.getCraftingProcess().isActive(); + } + @Override public synchronized void onLostControl() { gettingTo = null; diff --git a/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java b/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java index bb3280803..736643fb5 100644 --- a/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java +++ b/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java @@ -17,8 +17,6 @@ package baritone.utils.accessor; -import net.minecraft.client.gui.GuiTextField; -import net.minecraft.client.gui.recipebook.RecipeBookPage; import net.minecraft.client.gui.recipebook.RecipeList; import java.util.List; From 645dbc487f753e0d4f9d539ae895847c6a6c69db Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 2 Jun 2023 09:00:29 -0500 Subject: [PATCH 11/39] Update CraftingProcess.java --- src/main/java/baritone/process/CraftingProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index af1a5e6be..61d45674c 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -99,7 +99,7 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } } catch (Exception e) { //you probably closed the crafting window while crafting process was still running. - logDirect("error"); + logDirect("Error! Did you close the crafting window while crafting process was still running?"); onLostControl(); } return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); From b009df207261ab6c9f298b2330b4ce46c4a0adcd Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Wed, 7 Jun 2023 14:37:24 +0200 Subject: [PATCH 12/39] craft-ability check --- .../api/process/ICraftingProcess.java | 21 +++++- .../command/defaults/CraftCommand.java | 2 +- .../baritone/process/CraftingProcess.java | 68 +++++++++++++------ 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/api/java/baritone/api/process/ICraftingProcess.java b/src/api/java/baritone/api/process/ICraftingProcess.java index a7b522468..928e0c62d 100644 --- a/src/api/java/baritone/api/process/ICraftingProcess.java +++ b/src/api/java/baritone/api/process/ICraftingProcess.java @@ -40,9 +40,17 @@ public interface ICraftingProcess extends IBaritoneProcess { List getCraftingRecipes(Item item); /** - * Checks if the requested item can be crafted the requested amount of times. + * Checks if the recipe can craft the requested amount of output. + * @param recipe that should be crafted + * @param amount how much output is wanted + * @return + */ + boolean canCraft(IRecipe recipe, int amount); + + /** + * Checks if the item can be crafted the requested amount of times. * @param item that should be crafted - * @param amount how much of that item is wanted. + * @param amount how much of this item should be crafted * @return */ boolean canCraft(Item item, int amount); @@ -52,5 +60,12 @@ public interface ICraftingProcess extends IBaritoneProcess { * @param item that should be crafted * @param amount how much of that item is wanted. */ - void craft(Item item, int amount); + void craftItem(Item item, int amount); + + /** + * Executes the crafting of the requested recipe the requested amount of times. + * @param recipe recipe that should be used. + * @param amount how many result items are wanted. + */ + void craftRecipe(IRecipe recipe, int amount); } diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index f96c63d52..aed6a2c33 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -50,7 +50,7 @@ public void execute(String label, IArgConsumer args) throws CommandException { logDirect("not enough resources in inventory"); /**/ } else { - baritone.getCraftingProcess().craft(item, amount); + baritone.getCraftingProcess().craftItem(item, amount); } } diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 61d45674c..ff6b482a2 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -34,13 +34,11 @@ import net.minecraft.item.crafting.IRecipe; import java.util.ArrayList; +import java.util.List; public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { - - //todo this is a copy paste of the getToBlockProcess and hasnt been cleand up - - private Item item; private int amount; + private IRecipe recipe; public CraftingProcess(Baritone baritone) { super(baritone); @@ -49,7 +47,7 @@ public CraftingProcess(Baritone baritone) { @Override public boolean isActive() { - return item != null && amount >= 1; + return recipe != null && amount >= 1; } @Override @@ -89,9 +87,9 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } } if (mc.currentScreen instanceof GuiCrafting) { - //if (canCraft(item, amount)) { + if (canCraft(recipe, amount)) { moveItemsToCraftingGrid(); - /*} else { + } else { logDirect("we cant craft"); //this should be a more meaning full message also if we check craftability beforehand we should never run out of resources mid crafting mc.player.closeScreen(); onLostControl(); @@ -108,8 +106,6 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa private void moveItemsToCraftingGrid() { int windowId = baritone.getPlayerContext().player().openContainer.windowId; - IRecipe recipe = getCraftingRecipes(item).get(0); //todo better way to get a recipe - //try to put the recipe the required amount of times in to the crafting grid. for (int i = 0; i*recipe.getRecipeOutput().getCount() < amount; i++) { mc.playerController.func_194338_a(windowId,recipe, GuiScreen.isShiftKeyDown(), ctx.player()); @@ -134,30 +130,60 @@ public ArrayList getCraftingRecipes(Item item) { } @Override - public boolean canCraft(Item item, int amount) { + public boolean canCraft(IRecipe recipe, int amount) { RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); - IRecipe recipe = getCraftingRecipes(item).get(0); - boolean canDo = recipeItemHelper.canCraft(recipe, null, amount); - return canDo; + for (ItemStack stack : ctx.player().inventory.mainInventory) { + recipeItemHelper.accountStack(stack); + } + return recipeItemHelper.canCraft(recipe, null, amount); + } + + @Override + public boolean canCraft(Item item, int amount) { + List recipeList = getCraftingRecipes(item); + for (IRecipe recipe : recipeList) { + if(canCraft(recipe, amount)) { + this.recipe = recipe; + return true; + } + } + return false; + //we maybe still be able to craft but need to mix ingredients. + //example we have 1 oak plank and 1 spruce plank and want to make sticks. this statement could be wrong. } @Override - public void craft(Item item, int amount) { - this.item = item; - this.amount = amount; - //todo check for crafting tables that are close. if none are found place one. else gotoBlock. - baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); - logDirect("im totally crafting right now"); + public void craftItem(Item item, int amount) { + if(canCraft(item, amount)) { + this.amount = amount; + //todo check for crafting tables that are close. if none are found place one. else gotoBlock. + baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); + logDirect("im totally crafting right now"); + } else { + logDirect("unable to find a craftable recipe. do you have the necessary resources?"); + } + } + + @Override + //this is intended for use over the api + public void craftRecipe(IRecipe recipe, int amount) { + if(canCraft(recipe,amount)) { + this.recipe = recipe; + this.amount = amount; + baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); + } else { + logDirect("this recipe is not craftable with the available resources."); + } } @Override public synchronized void onLostControl() { amount = 0; - item = null; + recipe = null; } @Override public String displayName0() { - return "Crafting "+amount+"x "+item.getTranslationKey(); + return "Crafting "+amount+"x "+recipe.getRecipeOutput().getDisplayName(); } } From 13c31c1d364af0255cf36fec58ed309d08d08c1c Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Wed, 7 Jun 2023 15:27:50 +0200 Subject: [PATCH 13/39] refactoring --- .../baritone/process/CraftingProcess.java | 87 +++++++++++-------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index ff6b482a2..fdd4bce0c 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -58,45 +58,15 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } else { //we no longer pathing so it's time to craft try { - //todo if we cant craft more because of stack limit or lack of resources grab result and either throw low resource exception or continue crafting - int outputCount = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftResult.getStackInSlot(420).getCount(); //items per crafting cycle - int inputCount = 0; - //todo this should, in order to consider low or non stackable items, search for the lowest non zero stack count - for (int i = 0; i < 9; i++) { - ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); - if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { - inputCount = itemStack.getCount(); - break; - } - } + int outputCount = getOutputCount(); //items per crafting cycle + int inputCount = getInputCount(); + boolean inputStackLimitReached = inputCount >= getLowestMaxStackSize(); - //if we have enought or reached stack limit on a input stack grab the result and subtract it from the target amount. - // todo dynamicly check input stack limit based on lowest stackable item - if (outputCount * inputCount >= amount || inputCount == 64) { - int windowId = ctx.player().openContainer.windowId; - int slotID = 0; //slot id. for crafting table output it is 0 - int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used - mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); - amount = amount - (outputCount * inputCount); - - if (amount <= 0) { - logDirect("done"); - //we finished crafting - ctx.player().closeScreen(); - onLostControl(); - } - } + takeResultFromOutput(outputCount, inputCount, inputStackLimitReached); if (mc.currentScreen instanceof GuiCrafting) { - if (canCraft(recipe, amount)) { - moveItemsToCraftingGrid(); - } else { - logDirect("we cant craft"); //this should be a more meaning full message also if we check craftability beforehand we should never run out of resources mid crafting - mc.player.closeScreen(); - onLostControl(); - }/**/ + moveItemsToCraftingGrid(); } } catch (Exception e) { - //you probably closed the crafting window while crafting process was still running. logDirect("Error! Did you close the crafting window while crafting process was still running?"); onLostControl(); } @@ -104,6 +74,49 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } } + private void takeResultFromOutput(int outputCount, int inputCount, boolean inputStackLimitReached) { + if (outputCount * inputCount >= amount || inputStackLimitReached) { + int windowId = ctx.player().openContainer.windowId; + int slotID = 0; //slot id. for crafting table output it is 0 + int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used + mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); + amount = amount - (outputCount * inputCount); + + if (amount <= 0) { + logDirect("done"); + //we finished crafting + ctx.player().closeScreen(); + onLostControl(); + } + } + } + + private int getOutputCount() { + return ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftResult.getStackInSlot(420).getCount(); + } + + private int getInputCount() { + int stackSize = Integer.MAX_VALUE; + for (int i = 0; i < 9; i++) { + ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + stackSize = Math.min(itemStack.getCount(), stackSize); + } + } + return stackSize; + } + + private int getLowestMaxStackSize() { + int maxStackSize = Integer.MAX_VALUE; + for (int i = 0; i < 9; i++) { + ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + maxStackSize = Math.min(itemStack.getMaxStackSize(), maxStackSize); + } + } + return maxStackSize; + } + private void moveItemsToCraftingGrid() { int windowId = baritone.getPlayerContext().player().openContainer.windowId; //try to put the recipe the required amount of times in to the crafting grid. @@ -113,12 +126,14 @@ private void moveItemsToCraftingGrid() { } @Override + //should this be in a helper class? public boolean hasCraftingRecipe(Item item) { ArrayList recipes = getCraftingRecipes(item); return !recipes.isEmpty(); } @Override + //should this be in a helper class? public ArrayList getCraftingRecipes(Item item) { ArrayList recipes = new ArrayList<>(); for (IRecipe recipe : CraftingManager.REGISTRY) { @@ -130,6 +145,7 @@ public ArrayList getCraftingRecipes(Item item) { } @Override + //should this be in a helper class? public boolean canCraft(IRecipe recipe, int amount) { RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); for (ItemStack stack : ctx.player().inventory.mainInventory) { @@ -139,6 +155,7 @@ public boolean canCraft(IRecipe recipe, int amount) { } @Override + //should this be in a helper class? public boolean canCraft(Item item, int amount) { List recipeList = getCraftingRecipes(item); for (IRecipe recipe : recipeList) { From c34eb8979a74e05a2e9d2e84c72343505976242d Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 8 Jun 2023 20:07:09 +0200 Subject: [PATCH 14/39] small fix --- src/main/java/baritone/process/CraftingProcess.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index fdd4bce0c..400ce64fa 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -151,7 +151,10 @@ public boolean canCraft(IRecipe recipe, int amount) { for (ItemStack stack : ctx.player().inventory.mainInventory) { recipeItemHelper.accountStack(stack); } - return recipeItemHelper.canCraft(recipe, null, amount); + //could be inlined but i think that would be not very readable + int outputCount = recipe.getRecipeOutput().getCount(); + int times = amount % outputCount == 0 ? amount / outputCount : (amount / outputCount) + 1; + return recipeItemHelper.canCraft(recipe, null, times); } @Override From 49a33d097a8f256ac958a57c7d80cbdb764189d1 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 8 Jun 2023 20:11:48 +0200 Subject: [PATCH 15/39] remove autocraft setting because unused --- src/api/java/baritone/api/Settings.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 5ee76cf1d..a59aa9000 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -68,11 +68,7 @@ public final class Settings { * Allow Baritone to move items in your inventory to your hotbar */ public final Setting allowInventory = new Setting<>(false); - - /** - * Allow Baritone to auto craft items with "craft command is called. - */ - public final Setting allowAutoCraft = new Setting<>(false); + /** * Wait this many ticks between InventoryBehavior moving inventory items From 79e417e17def7eb62e6fcbc58421534229a0dc20 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:10:44 +0200 Subject: [PATCH 16/39] refactoring CraftingProcess --- .../api/process/ICraftingProcess.java | 50 ++++--- .../baritone/process/CraftingProcess.java | 137 ++++++++---------- 2 files changed, 87 insertions(+), 100 deletions(-) diff --git a/src/api/java/baritone/api/process/ICraftingProcess.java b/src/api/java/baritone/api/process/ICraftingProcess.java index 928e0c62d..1bf7b3a2f 100644 --- a/src/api/java/baritone/api/process/ICraftingProcess.java +++ b/src/api/java/baritone/api/process/ICraftingProcess.java @@ -23,49 +23,53 @@ import java.util.List; /** - * but it rescans the world every once in a while so it doesn't get fooled by its cache + * Allows you to craft items. */ public interface ICraftingProcess extends IBaritoneProcess { /** + * Executes the crafting of the requested item such that we obtain the requested amount. * @param item that should be crafted - * @return Can the item be crafted in a crafting table? + * @param amount how much of that item is wanted. */ - boolean hasCraftingRecipe(Item item); + void craftItem(Item item, int amount); /** - * @param item that should be crafted - * @return List of all recipies that result in the provided Item. + * Executes the crafting of the requested recipe such that we obtain the requested amount of output. + * @param recipe recipe that should be used. + * @param amount how many result items are wanted. */ - List getCraftingRecipes(Item item); + void craftRecipe(IRecipe recipe, int amount); /** - * Checks if the recipe can craft the requested amount of output. - * @param recipe that should be crafted - * @param amount how much output is wanted - * @return + * @param item that should be crafted. + * @return Can the item be crafted in a crafting table? */ - boolean canCraft(IRecipe recipe, int amount); + boolean hasCraftingRecipe(Item item); /** - * Checks if the item can be crafted the requested amount of times. - * @param item that should be crafted - * @param amount how much of this item should be crafted - * @return + * @param item that should be crafted. + * @return List of all recipes that result in the provided Item. + */ + List getCraftingRecipes(Item item); + + /** + * @param item that should be crafted. + * @param amount how much of this item should be crafted. + * @return Can we craft this item the requested amount of times? */ boolean canCraft(Item item, int amount); /** - * Executes the crafting of the requested item the requested amount of times. - * @param item that should be crafted - * @param amount how much of that item is wanted. + * @param recipe that should be crafted. + * @param amount how much output is wanted. + * @return Can we craft this recipe to get the requested amount of output? */ - void craftItem(Item item, int amount); + boolean canCraft(IRecipe recipe, int amount); /** - * Executes the crafting of the requested recipe the requested amount of times. - * @param recipe recipe that should be used. - * @param amount how many result items are wanted. + * @param recipe the recipe we want to craft. + * @return Do we need a crafting table or can we craft it in our inventory? */ - void craftRecipe(IRecipe recipe, int amount); + boolean canCraftInInventory(IRecipe recipe); } diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 400ce64fa..06333f828 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -23,7 +23,6 @@ import baritone.api.process.PathingCommandType; import baritone.utils.BaritoneProcessHelper; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.inventory.GuiCrafting; import net.minecraft.client.util.RecipeItemHelper; import net.minecraft.init.Blocks; import net.minecraft.inventory.ClickType; @@ -44,7 +43,6 @@ public CraftingProcess(Baritone baritone) { super(baritone); } - @Override public boolean isActive() { return recipe != null && amount >= 1; @@ -58,14 +56,8 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } else { //we no longer pathing so it's time to craft try { - int outputCount = getOutputCount(); //items per crafting cycle - int inputCount = getInputCount(); - boolean inputStackLimitReached = inputCount >= getLowestMaxStackSize(); - - takeResultFromOutput(outputCount, inputCount, inputStackLimitReached); - if (mc.currentScreen instanceof GuiCrafting) { - moveItemsToCraftingGrid(); - } + moveItemsToCraftingGrid(); + takeResultFromOutput(); } catch (Exception e) { logDirect("Error! Did you close the crafting window while crafting process was still running?"); onLostControl(); @@ -74,25 +66,38 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } } - private void takeResultFromOutput(int outputCount, int inputCount, boolean inputStackLimitReached) { - if (outputCount * inputCount >= amount || inputStackLimitReached) { - int windowId = ctx.player().openContainer.windowId; - int slotID = 0; //slot id. for crafting table output it is 0 - int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used - mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); - amount = amount - (outputCount * inputCount); + @Override + public synchronized void onLostControl() { + amount = 0; + recipe = null; + } - if (amount <= 0) { - logDirect("done"); - //we finished crafting - ctx.player().closeScreen(); - onLostControl(); - } + @Override + public String displayName0() { + return "Crafting " + amount + "x " + recipe.getRecipeOutput().getDisplayName(); + } + + @Override + public void craftItem(Item item, int amount) { + if (canCraft(item, amount)) { + this.amount = amount; + //todo check for crafting tables that are close. if none are found place one. else gotoBlock. + baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); + logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); + } else { + logDirect("Insufficient resources."); } } - private int getOutputCount() { - return ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftResult.getStackInSlot(420).getCount(); + @Override + public void craftRecipe(IRecipe recipe, int amount) { + if (canCraft(recipe, amount)) { + this.recipe = recipe; + this.amount = amount; + baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); + } else { + logDirect("this recipe is not craftable with the available resources."); + } } private int getInputCount() { @@ -103,25 +108,32 @@ private int getInputCount() { stackSize = Math.min(itemStack.getCount(), stackSize); } } - return stackSize; + return stackSize == Integer.MAX_VALUE ? 0 : stackSize; } - private int getLowestMaxStackSize() { - int maxStackSize = Integer.MAX_VALUE; - for (int i = 0; i < 9; i++) { - ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); - if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { - maxStackSize = Math.min(itemStack.getMaxStackSize(), maxStackSize); - } + private void takeResultFromOutput() { + int inputCount = getInputCount(); + if (inputCount > 0) { + int windowId = ctx.player().openContainer.windowId; + int slotID = 0; //slot id. for crafting table output it is 0 + int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used + mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); + amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); + } + + if (amount <= 0) { + logDirect("Done"); + //we finished crafting + ctx.player().closeScreen(); + onLostControl(); } - return maxStackSize; } private void moveItemsToCraftingGrid() { int windowId = baritone.getPlayerContext().player().openContainer.windowId; //try to put the recipe the required amount of times in to the crafting grid. - for (int i = 0; i*recipe.getRecipeOutput().getCount() < amount; i++) { - mc.playerController.func_194338_a(windowId,recipe, GuiScreen.isShiftKeyDown(), ctx.player()); + for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { + mc.playerController.func_194338_a(windowId, recipe, GuiScreen.isShiftKeyDown(), ctx.player()); } } @@ -144,25 +156,12 @@ public ArrayList getCraftingRecipes(Item item) { return recipes; } - @Override - //should this be in a helper class? - public boolean canCraft(IRecipe recipe, int amount) { - RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); - for (ItemStack stack : ctx.player().inventory.mainInventory) { - recipeItemHelper.accountStack(stack); - } - //could be inlined but i think that would be not very readable - int outputCount = recipe.getRecipeOutput().getCount(); - int times = amount % outputCount == 0 ? amount / outputCount : (amount / outputCount) + 1; - return recipeItemHelper.canCraft(recipe, null, times); - } - @Override //should this be in a helper class? public boolean canCraft(Item item, int amount) { List recipeList = getCraftingRecipes(item); for (IRecipe recipe : recipeList) { - if(canCraft(recipe, amount)) { + if (canCraft(recipe, amount)) { this.recipe = recipe; return true; } @@ -173,37 +172,21 @@ public boolean canCraft(Item item, int amount) { } @Override - public void craftItem(Item item, int amount) { - if(canCraft(item, amount)) { - this.amount = amount; - //todo check for crafting tables that are close. if none are found place one. else gotoBlock. - baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); - logDirect("im totally crafting right now"); - } else { - logDirect("unable to find a craftable recipe. do you have the necessary resources?"); - } - } - - @Override - //this is intended for use over the api - public void craftRecipe(IRecipe recipe, int amount) { - if(canCraft(recipe,amount)) { - this.recipe = recipe; - this.amount = amount; - baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); - } else { - logDirect("this recipe is not craftable with the available resources."); + //should this be in a helper class? + public boolean canCraft(IRecipe recipe, int amount) { + RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); + for (ItemStack stack : ctx.player().inventory.mainInventory) { + recipeItemHelper.accountStack(stack); } + //could be inlined but i think that would be not very readable + int outputCount = recipe.getRecipeOutput().getCount(); + int times = amount % outputCount == 0 ? amount / outputCount : (amount / outputCount) + 1; + return recipeItemHelper.canCraft(recipe, null, times); } - @Override - public synchronized void onLostControl() { - amount = 0; - recipe = null; - } @Override - public String displayName0() { - return "Crafting "+amount+"x "+recipe.getRecipeOutput().getDisplayName(); + public boolean canCraftInInventory(IRecipe recipe) { + return recipe.canFit(2,2); } } From 8d1b2c7ebe8ec86fe0e4d961ed330e8c77ee4713 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:14:27 +0200 Subject: [PATCH 17/39] delete mixins because unused --- .../launch/mixins/MixinGuiRecipeBook.java | 35 ------------------- .../launch/mixins/MixinRecipeBookPage.java | 33 ----------------- src/launch/resources/mixins.baritone.json | 2 -- 3 files changed, 70 deletions(-) delete mode 100644 src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java delete mode 100644 src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java diff --git a/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java b/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java deleted file mode 100644 index f0d90b867..000000000 --- a/src/launch/java/baritone/launch/mixins/MixinGuiRecipeBook.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.IMixinGuiRecipeBook; -import net.minecraft.client.gui.GuiTextField; -import net.minecraft.client.gui.recipebook.GuiRecipeBook; -import net.minecraft.client.gui.recipebook.RecipeBookPage; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(GuiRecipeBook.class) -public abstract class MixinGuiRecipeBook implements IMixinGuiRecipeBook{ - - @Accessor("searchBar") - public abstract GuiTextField getSearchBar(); - - @Accessor("recipeBookPage") - public abstract RecipeBookPage getRecipeBookPage(); -} diff --git a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java b/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java deleted file mode 100644 index a703cc5d7..000000000 --- a/src/launch/java/baritone/launch/mixins/MixinRecipeBookPage.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.IMixinRecipeBookPage; -import net.minecraft.client.gui.recipebook.RecipeBookPage; -import net.minecraft.client.gui.recipebook.RecipeList; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -@Mixin(RecipeBookPage.class) -public abstract class MixinRecipeBookPage implements IMixinRecipeBookPage { - - @Accessor("recipeLists") - public abstract List getRecipeLists(); -} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index 93953e8e0..982736635 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -19,7 +19,6 @@ "MixinEntityLivingBase", "MixinEntityPlayerSP", "MixinEntityRenderer", - "MixinGuiRecipeBook", "MixinGuiScreen", "MixinItemStack", "MixinItemTool", @@ -28,7 +27,6 @@ "MixinNetHandlerPlayClient", "MixinNetworkManager", "MixinPlayerControllerMP", - "MixinRecipeBookPage", "MixinRenderChunk", "MixinRenderList", "MixinStateImplementation", From 1cb53c7977bebdf366e798c46c8a748510be6bb3 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:17:22 +0200 Subject: [PATCH 18/39] delete mixins because unused --- .../utils/accessor/IMixinGuiRecipeBook.java | 27 ------------------- .../utils/accessor/IMixinRecipeBookPage.java | 27 ------------------- 2 files changed, 54 deletions(-) delete mode 100644 src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java delete mode 100644 src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java diff --git a/src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java b/src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java deleted file mode 100644 index 1265289b0..000000000 --- a/src/main/java/baritone/utils/accessor/IMixinGuiRecipeBook.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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.client.gui.GuiTextField; -import net.minecraft.client.gui.recipebook.RecipeBookPage; - -public interface IMixinGuiRecipeBook { - - GuiTextField getSearchBar(); - RecipeBookPage getRecipeBookPage(); -} diff --git a/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java b/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java deleted file mode 100644 index 736643fb5..000000000 --- a/src/main/java/baritone/utils/accessor/IMixinRecipeBookPage.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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.client.gui.recipebook.RecipeList; - -import java.util.List; - -public interface IMixinRecipeBookPage { - - List getRecipeLists(); -} From c1f2d0c45a29f5ff43484beef3ce2747c68bdbe6 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:18:32 +0200 Subject: [PATCH 19/39] revert changes on GetToBlockProcess --- src/main/java/baritone/process/GetToBlockProcess.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index e0b79920e..16fc3dda5 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -175,10 +175,6 @@ private boolean areAdjacent(BlockPos posA, BlockPos posB) { return (diffX + diffY + diffZ) == 1; } - public boolean isTemporary() { - return baritone.getCraftingProcess().isActive(); - } - @Override public synchronized void onLostControl() { gettingTo = null; From 6d34c506e3718c0c512a6481c7e500046263d7bc Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Fri, 9 Jun 2023 00:00:39 +0200 Subject: [PATCH 20/39] im hard at my limit here --- .../baritone/process/CraftingProcess.java | 132 ++++++++++++------ 1 file changed, 88 insertions(+), 44 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 06333f828..5cd3bb254 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -18,9 +18,12 @@ package baritone.process; import baritone.Baritone; +import baritone.api.pathing.goals.*; import baritone.api.process.ICraftingProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; +import baritone.api.utils.BlockOptionalMetaLookup; +import baritone.pathing.movement.CalculationContext; import baritone.utils.BaritoneProcessHelper; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.util.RecipeItemHelper; @@ -31,13 +34,17 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.math.BlockPos; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { private int amount; private IRecipe recipe; + private Goal goal; + private BlockPos placeAt; public CraftingProcess(Baritone baritone) { super(baritone); @@ -50,9 +57,16 @@ public boolean isActive() { @Override public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - if (baritone.getGetToBlockProcess().isActive()) { + if (calcFailed) { + logDirect("path calculation failed"); + onLostControl(); + } + if (goal != null) { //we are pathing to a table and therefor have to wait. - return new PathingCommand(null, PathingCommandType.DEFER); + return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); + } else if (placeAt != null) { + + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } else { //we no longer pathing so it's time to craft try { @@ -70,6 +84,8 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa public synchronized void onLostControl() { amount = 0; recipe = null; + goal = null; + placeAt = null; } @Override @@ -81,9 +97,8 @@ public String displayName0() { public void craftItem(Item item, int amount) { if (canCraft(item, amount)) { this.amount = amount; - //todo check for crafting tables that are close. if none are found place one. else gotoBlock. - baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); + getACraftingTable(); } else { logDirect("Insufficient resources."); } @@ -94,46 +109,9 @@ public void craftRecipe(IRecipe recipe, int amount) { if (canCraft(recipe, amount)) { this.recipe = recipe; this.amount = amount; - baritone.getGetToBlockProcess().getToBlock(Blocks.CRAFTING_TABLE); + getACraftingTable(); } else { - logDirect("this recipe is not craftable with the available resources."); - } - } - - private int getInputCount() { - int stackSize = Integer.MAX_VALUE; - for (int i = 0; i < 9; i++) { - ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); - if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { - stackSize = Math.min(itemStack.getCount(), stackSize); - } - } - return stackSize == Integer.MAX_VALUE ? 0 : stackSize; - } - - private void takeResultFromOutput() { - int inputCount = getInputCount(); - if (inputCount > 0) { - int windowId = ctx.player().openContainer.windowId; - int slotID = 0; //slot id. for crafting table output it is 0 - int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used - mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); - amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); - } - - if (amount <= 0) { - logDirect("Done"); - //we finished crafting - ctx.player().closeScreen(); - onLostControl(); - } - } - - private void moveItemsToCraftingGrid() { - int windowId = baritone.getPlayerContext().player().openContainer.windowId; - //try to put the recipe the required amount of times in to the crafting grid. - for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { - mc.playerController.func_194338_a(windowId, recipe, GuiScreen.isShiftKeyDown(), ctx.player()); + logDirect("Insufficient resources."); } } @@ -184,9 +162,75 @@ public boolean canCraft(IRecipe recipe, int amount) { return recipeItemHelper.canCraft(recipe, null, times); } - @Override public boolean canCraftInInventory(IRecipe recipe) { return recipe.canFit(2,2); } + + private int getInputCount() { + int stackSize = Integer.MAX_VALUE; + for (int i = 0; i < 9; i++) { + ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + stackSize = Math.min(itemStack.getCount(), stackSize); + } + } + return stackSize == Integer.MAX_VALUE ? 0 : stackSize; + } + + private void takeResultFromOutput() { + int inputCount = getInputCount(); + if (inputCount > 0) { + int windowId = ctx.player().openContainer.windowId; + int slotID = 0; //slot id. for crafting table output it is 0 + int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used + mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); + amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); + } + + if (amount <= 0) { + logDirect("Done"); + //we finished crafting + ctx.player().closeScreen(); + onLostControl(); + } + } + + private void moveItemsToCraftingGrid() { + int windowId = ctx.player().openContainer.windowId; + //try to put the recipe the required amount of times in to the crafting grid. + for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { + mc.playerController.func_194338_a(windowId, recipe, GuiScreen.isShiftKeyDown(), ctx.player()); + } + } + + private void getACraftingTable() { + List knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 1, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + if (knownLocations.isEmpty()) { + logDirect("no crafting table found"); + if (hasCraftingTable()) { + logDirect("but player has one in inventory"); + placeAt = ctx.playerFeet().north(); + } else { + logDirect("No CraftingTable."); + onLostControl(); + } + } else { + logDirect("crafting table found"); + goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new)); + } + } + + private boolean hasCraftingTable() { + for (ItemStack itemstack : ctx.player().inventory.mainInventory) { + if (itemstack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { + return true; + } + } + return false; + } + + private Goal createGoal(BlockPos pos) { + return new GoalGetToBlock(pos); + } } From f5c50df28a9d01b6e008d3f3b4f451066e24ef5f Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Fri, 9 Jun 2023 00:54:39 +0200 Subject: [PATCH 21/39] i need help --- src/main/java/baritone/process/CraftingProcess.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 5cd3bb254..10b948ba1 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -62,6 +62,10 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa onLostControl(); } if (goal != null) { + if (goal.isInGoal(ctx.playerFeet())) { + //rightClick(); + goal = null; + } //we are pathing to a table and therefor have to wait. return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else if (placeAt != null) { @@ -86,6 +90,7 @@ public synchronized void onLostControl() { recipe = null; goal = null; placeAt = null; + baritone.getInputOverrideHandler().clearAllKeys(); } @Override From f79077f3603773ad2735f302c2429c621097767c Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sat, 10 Jun 2023 01:25:57 +0200 Subject: [PATCH 22/39] its amazing that it works sometimes --- .../baritone/process/CraftingProcess.java | 104 ++++++++++++++---- 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 10b948ba1..f3117ef5e 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -23,12 +23,16 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.utils.BlockOptionalMetaLookup; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; +import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.utils.BaritoneProcessHelper; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.util.RecipeItemHelper; import net.minecraft.init.Blocks; import net.minecraft.inventory.ClickType; +import net.minecraft.inventory.ContainerPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -39,12 +43,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { private int amount; private IRecipe recipe; private Goal goal; private BlockPos placeAt; + private boolean clearToPush = true; public CraftingProcess(Baritone baritone) { super(baritone); @@ -57,24 +63,27 @@ public boolean isActive() { @Override public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - if (calcFailed) { + if (calcFailed) { //is this correct? logDirect("path calculation failed"); onLostControl(); } if (goal != null) { if (goal.isInGoal(ctx.playerFeet())) { - //rightClick(); - goal = null; + if (rightClick()) { + goal = null; + } } //we are pathing to a table and therefor have to wait. return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else if (placeAt != null) { - - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + placeCraftingtableNearby(); + return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else { //we no longer pathing so it's time to craft try { - moveItemsToCraftingGrid(); + if (clearToPush) { + moveItemsToCraftingGrid(); + } takeResultFromOutput(); } catch (Exception e) { logDirect("Error! Did you close the crafting window while crafting process was still running?"); @@ -172,15 +181,13 @@ public boolean canCraftInInventory(IRecipe recipe) { return recipe.canFit(2,2); } - private int getInputCount() { - int stackSize = Integer.MAX_VALUE; - for (int i = 0; i < 9; i++) { - ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); - if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { - stackSize = Math.min(itemStack.getCount(), stackSize); - } + private void moveItemsToCraftingGrid() { + clearToPush = false; + int windowId = ctx.player().openContainer.windowId; + //try to put the recipe the required amount of times in to the crafting grid. + for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { + mc.playerController.func_194338_a(windowId, recipe, GuiScreen.isShiftKeyDown(), ctx.player()); } - return stackSize == Integer.MAX_VALUE ? 0 : stackSize; } private void takeResultFromOutput() { @@ -191,6 +198,7 @@ private void takeResultFromOutput() { int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); + clearToPush = true; } if (amount <= 0) { @@ -201,27 +209,30 @@ private void takeResultFromOutput() { } } - private void moveItemsToCraftingGrid() { - int windowId = ctx.player().openContainer.windowId; - //try to put the recipe the required amount of times in to the crafting grid. - for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { - mc.playerController.func_194338_a(windowId, recipe, GuiScreen.isShiftKeyDown(), ctx.player()); + private int getInputCount() { + int stackSize = Integer.MAX_VALUE; + for (int i = 0; i < 9; i++) { + ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + stackSize = Math.min(itemStack.getCount(), stackSize); + } } + return stackSize == Integer.MAX_VALUE ? 0 : stackSize; } private void getACraftingTable() { - List knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 1, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + List knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); if (knownLocations.isEmpty()) { - logDirect("no crafting table found"); + //logDirect("There are no crafting tables nearby,"); if (hasCraftingTable()) { - logDirect("but player has one in inventory"); + //logDirect("but player has crafting table in inventory."); placeAt = ctx.playerFeet().north(); } else { - logDirect("No CraftingTable."); + //logDirect("cant do shit."); onLostControl(); } } else { - logDirect("crafting table found"); + //logDirect("Pathing now to crafting table"); goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new)); } } @@ -238,4 +249,49 @@ private boolean hasCraftingTable() { private Goal createGoal(BlockPos pos) { return new GoalGetToBlock(pos); } + + private boolean rightClick() { //shamelessly copied from go to block process + BlockPos bp = null; + if (goal instanceof GoalComposite) { + Goal[] goals = ((GoalComposite)goal).goals(); + for (Goal goal : goals) { + if (goal.isInGoal(ctx.playerFeet()) && goal instanceof GoalGetToBlock) { + bp = ((GoalGetToBlock)goal).getGoalPos(); + break; + } + logDirect("error rightclick was called without being next to goal. will throw nullpointer & crash mc"); + } + } else { + bp = ((GoalGetToBlock)goal).getGoalPos(); + } + Optional reachable = RotationUtils.reachable(ctx.player(), bp, ctx.playerController().getBlockReachDistance()); + if (reachable.isPresent()) { + baritone.getLookBehavior().updateTarget(reachable.get(), true); + if (bp.equals(ctx.getSelectedBlock().orElse(null))) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + System.out.println(ctx.player().openContainer); + if (!(ctx.player().openContainer instanceof ContainerPlayer)) { + baritone.getInputOverrideHandler().clearAllKeys(); + return true; + } + } + return false; + } + return true; + } + + private void placeCraftingtableNearby() { //this code is so buggy im amazed that there are special cases where it works + for (int i = 0; i < 9; i++) { + ItemStack stack = ctx.player().inventory.mainInventory.get(i); + if (stack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { + ctx.player().inventory.currentItem = i; + break; + } + } + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + //do placing + + placeAt = null; + getACraftingTable(); + } } From eae2dc34f7dc576007026da5255daed330234667 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 11 Jun 2023 15:21:37 +0200 Subject: [PATCH 23/39] delete extra line --- src/api/java/baritone/api/Settings.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index a59aa9000..38661d8be 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -69,7 +69,6 @@ public final class Settings { */ public final Setting allowInventory = new Setting<>(false); - /** * Wait this many ticks between InventoryBehavior moving inventory items */ From ecfbc4974131b19d3f143e11528d9b3a33796053 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 11 Jun 2023 16:41:11 +0200 Subject: [PATCH 24/39] craft command --- .../api/command/datatypes/ItemById.java | 51 +++++++++++++++++++ .../command/defaults/CraftCommand.java | 35 +++++++++---- 2 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 src/api/java/baritone/api/command/datatypes/ItemById.java diff --git a/src/api/java/baritone/api/command/datatypes/ItemById.java b/src/api/java/baritone/api/command/datatypes/ItemById.java new file mode 100644 index 000000000..205b93d03 --- /dev/null +++ b/src/api/java/baritone/api/command/datatypes/ItemById.java @@ -0,0 +1,51 @@ +/* + * 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.command.datatypes; + +import baritone.api.command.exception.CommandException; +import baritone.api.command.helpers.TabCompleteHelper; +import net.minecraft.item.Item; +import net.minecraft.util.ResourceLocation; + +import java.util.stream.Stream; + +/** + * @author ZacSharp + * written for a yet unmerged #pickUp command + */ +public enum ItemById implements IDatatypeFor { + INSTANCE; + + @Override + public Item get(IDatatypeContext ctx) throws CommandException { + Item item; + if ((item = Item.getByNameOrId(ctx.getConsumer().getString())) == null) { + throw new IllegalArgumentException("No item found by that id"); + } + return item; + } + + @Override + public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + return new TabCompleteHelper() + .append(Item.REGISTRY.getKeys().stream().map(ResourceLocation::toString)) + .filterPrefixNamespaced(ctx.getConsumer().getString()) + .sortAlphabetically() + .stream(); + } +} \ No newline at end of file diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index aed6a2c33..1611e389c 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -20,8 +20,11 @@ import baritone.api.IBaritone; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.datatypes.ItemById; import baritone.api.command.exception.CommandException; import net.minecraft.item.Item; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; import java.util.Arrays; import java.util.List; @@ -35,20 +38,22 @@ protected CraftCommand(IBaritone baritone) { @Override public void execute(String label, IArgConsumer args) throws CommandException { - //todo works for simple items like "stick" but items like "granite" aren't parsed because they are stone:1 - Item item = Item.getByNameOrId(args.getString()); + String itemName = args.getString(); + Item item = Item.getByNameOrId(itemName); int amount = args.hasAny() ? args.getAs(Integer.class) : 1; - if (item == null) { + if (item == null) {//this is hacky, but it gets the job done for now. also we arnt interested in non craft-able items anyway + itemName = itemName.replace("_", " "); + for (IRecipe recipe : CraftingManager.REGISTRY) { + if (recipe.getRecipeOutput().getDisplayName().equalsIgnoreCase(itemName)) { + baritone.getCraftingProcess().craftRecipe(recipe, amount); + return; + } + } logDirect("invalid Item"); } else if (!baritone.getCraftingProcess().hasCraftingRecipe(item)) { logDirect("no crafting recipe for "+item.getTranslationKey()+" found."); - /*todo missing feature check if we can craft before we walk to a crafting table - } else if (BaritoneAPI.getSettings().allowAutoCraft.value && !baritone.getCraftingProcess().canCraft(item, amount)) { - logDirect("trying to craft "+ item.getTranslationKey()); - logDirect("not enough resources in inventory"); - /**/ } else { baritone.getCraftingProcess().craftItem(item, amount); } @@ -56,8 +61,13 @@ public void execute(String label, IArgConsumer args) throws CommandException { @Override public Stream tabComplete(String label, IArgConsumer args) throws CommandException { - //todo add autocomplete for items - return null; + while (args.has(2)) { + if (args.peekDatatypeOrNull(ItemById.INSTANCE) == null) { + return Stream.empty(); + } + args.get(); + } + return args.tabCompleteDatatype(ItemById.INSTANCE); } @Override @@ -71,7 +81,10 @@ public List getLongDesc() { "Go to a crafting table and craft a item.", "", "Usage:", - "> craft - Go to a crafting table, and craft a item." + "> craft [item] - Go to a crafting table, and craft a item.", + "Examples:", + "> craft planks 17 -> will craft 20 planks of any logs you have.", + "> craft oak_wood_planks -> will craft 4 oak wood planks." ); } } \ No newline at end of file From 48dc6749230f2d912b644a24bc6b232cabc2b469 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 11 Jun 2023 17:52:19 +0200 Subject: [PATCH 25/39] getting closer to a finished product --- .../baritone/process/CraftingProcess.java | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index f3117ef5e..ea78bbd5a 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -18,7 +18,9 @@ package baritone.process; import baritone.Baritone; -import baritone.api.pathing.goals.*; +import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalComposite; +import baritone.api.pathing.goals.GoalGetToBlock; import baritone.api.process.ICraftingProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; @@ -112,7 +114,9 @@ public void craftItem(Item item, int amount) { if (canCraft(item, amount)) { this.amount = amount; logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); - getACraftingTable(); + if (!canCraftInInventory(recipe)) { + getACraftingTable(); + } } else { logDirect("Insufficient resources."); } @@ -123,7 +127,10 @@ public void craftRecipe(IRecipe recipe, int amount) { if (canCraft(recipe, amount)) { this.recipe = recipe; this.amount = amount; - getACraftingTable(); + logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); + if (!canCraftInInventory(recipe)) { + getACraftingTable(); + } } else { logDirect("Insufficient resources."); } @@ -159,8 +166,6 @@ public boolean canCraft(Item item, int amount) { } } return false; - //we maybe still be able to craft but need to mix ingredients. - //example we have 1 oak plank and 1 spruce plank and want to make sticks. this statement could be wrong. } @Override @@ -170,7 +175,6 @@ public boolean canCraft(IRecipe recipe, int amount) { for (ItemStack stack : ctx.player().inventory.mainInventory) { recipeItemHelper.accountStack(stack); } - //could be inlined but i think that would be not very readable int outputCount = recipe.getRecipeOutput().getCount(); int times = amount % outputCount == 0 ? amount / outputCount : (amount / outputCount) + 1; return recipeItemHelper.canCraft(recipe, null, times); @@ -178,7 +182,7 @@ public boolean canCraft(IRecipe recipe, int amount) { @Override public boolean canCraftInInventory(IRecipe recipe) { - return recipe.canFit(2,2); + return recipe.canFit(2,2) && !ctx.player().isCreative(); } private void moveItemsToCraftingGrid() { @@ -203,7 +207,6 @@ private void takeResultFromOutput() { if (amount <= 0) { logDirect("Done"); - //we finished crafting ctx.player().closeScreen(); onLostControl(); } @@ -211,11 +214,22 @@ private void takeResultFromOutput() { private int getInputCount() { int stackSize = Integer.MAX_VALUE; - for (int i = 0; i < 9; i++) { - ItemStack itemStack = ((ContainerWorkbench) baritone.getPlayerContext().player().openContainer).craftMatrix.getStackInSlot(i); - if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { - stackSize = Math.min(itemStack.getCount(), stackSize); + if (ctx.player().openContainer instanceof ContainerPlayer) { + for (int i = 0; i < 4; i++) { + ItemStack itemStack = ((ContainerPlayer) ctx.player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + stackSize = Math.min(itemStack.getCount(), stackSize); + } + } + } else if (ctx.player().openContainer instanceof ContainerWorkbench) { + for (int i = 0; i < 9; i++) { + ItemStack itemStack = ((ContainerWorkbench) ctx.player().openContainer).craftMatrix.getStackInSlot(i); + if (itemStack.getItem() != Item.getItemFromBlock(Blocks.AIR)) { + stackSize = Math.min(itemStack.getCount(), stackSize); + } } + } else { + throw new RuntimeException("Expected a crafting Inventory"); } return stackSize == Integer.MAX_VALUE ? 0 : stackSize; } @@ -223,16 +237,13 @@ private int getInputCount() { private void getACraftingTable() { List knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); if (knownLocations.isEmpty()) { - //logDirect("There are no crafting tables nearby,"); if (hasCraftingTable()) { - //logDirect("but player has crafting table in inventory."); placeAt = ctx.playerFeet().north(); } else { - //logDirect("cant do shit."); + logDirect("Recipe requires a crafting table."); onLostControl(); } } else { - //logDirect("Pathing now to crafting table"); goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new)); } } @@ -289,7 +300,6 @@ private void placeCraftingtableNearby() { //this code is so buggy im amazed that } } baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); - //do placing placeAt = null; getACraftingTable(); From 0a85399cb3236c56fc2256fea74df131476c5cc2 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 11 Jun 2023 18:06:37 +0200 Subject: [PATCH 26/39] todos --- src/main/java/baritone/process/CraftingProcess.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index ea78bbd5a..e220a7186 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -292,6 +292,8 @@ private boolean rightClick() { //shamelessly copied from go to block process } private void placeCraftingtableNearby() { //this code is so buggy im amazed that there are special cases where it works + //todo if crafting table isnt in hotbar move it to the hot bar. + //todo search and look at a position where the table can be placed for (int i = 0; i < 9; i++) { ItemStack stack = ctx.player().inventory.mainInventory.get(i); if (stack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { From 4e71b0486c42fe26ad6021e4aebcdeb645fd3ee5 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Tue, 13 Jun 2023 18:54:17 +0200 Subject: [PATCH 27/39] codacy and selecting crafting table --- .../baritone/process/CraftingProcess.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index e220a7186..a96a0dffc 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -71,7 +71,8 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } if (goal != null) { if (goal.isInGoal(ctx.playerFeet())) { - if (rightClick()) { + rightClick(); + if (ctx.player().openContainer instanceof ContainerWorkbench) { goal = null; } } @@ -228,8 +229,6 @@ private int getInputCount() { stackSize = Math.min(itemStack.getCount(), stackSize); } } - } else { - throw new RuntimeException("Expected a crafting Inventory"); } return stackSize == Integer.MAX_VALUE ? 0 : stackSize; } @@ -292,18 +291,27 @@ private boolean rightClick() { //shamelessly copied from go to block process } private void placeCraftingtableNearby() { //this code is so buggy im amazed that there are special cases where it works - //todo if crafting table isnt in hotbar move it to the hot bar. + selectCraftingTable(); //todo search and look at a position where the table can be placed - for (int i = 0; i < 9; i++) { - ItemStack stack = ctx.player().inventory.mainInventory.get(i); - if (stack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { - ctx.player().inventory.currentItem = i; - break; - } - } + baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); placeAt = null; getACraftingTable(); } + + private void selectCraftingTable() { + for (int i = 0; i < 36; i++) { + ItemStack stack = ctx.player().inventory.mainInventory.get(i); + if (stack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { + if (i < 9) { + ctx.player().inventory.currentItem = i; + return; + } else { + baritone.getInventoryBehavior().attemptToPutOnHotbar(i, null); + i=0; + } + } + } + } } From d8c8884bd1f86ab4c40a401fd5a9b459b6e764ab Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Tue, 13 Jun 2023 23:57:16 +0200 Subject: [PATCH 28/39] comments and edge cases --- .../command/defaults/CraftCommand.java | 19 ++++++++++--- .../baritone/process/CraftingProcess.java | 28 ++++++++++--------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index 1611e389c..4142344d2 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -45,17 +45,28 @@ public void execute(String label, IArgConsumer args) throws CommandException { if (item == null) {//this is hacky, but it gets the job done for now. also we arnt interested in non craft-able items anyway itemName = itemName.replace("_", " "); + boolean recipeExists = false; for (IRecipe recipe : CraftingManager.REGISTRY) { if (recipe.getRecipeOutput().getDisplayName().equalsIgnoreCase(itemName)) { - baritone.getCraftingProcess().craftRecipe(recipe, amount); - return; + if (baritone.getCraftingProcess().canCraft(recipe, amount)) { + baritone.getCraftingProcess().craftRecipe(recipe, amount); + return; + } else { //a recipe exists but we cant craft it + recipeExists = true; + } } } - logDirect("invalid Item"); + if (recipeExists) { + logDirect("Insufficient Resources"); + } else { + logDirect("Invalid Item"); + } } else if (!baritone.getCraftingProcess().hasCraftingRecipe(item)) { logDirect("no crafting recipe for "+item.getTranslationKey()+" found."); - } else { + } else if (baritone.getCraftingProcess().canCraft(item, amount)){ baritone.getCraftingProcess().craftItem(item, amount); + } else { + logDirect("Insufficient Resources"); } } diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index a96a0dffc..31102b2f4 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -70,13 +70,13 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa onLostControl(); } if (goal != null) { + //we are pathing to a table and therefor have to wait. if (goal.isInGoal(ctx.playerFeet())) { rightClick(); if (ctx.player().openContainer instanceof ContainerWorkbench) { goal = null; } } - //we are pathing to a table and therefor have to wait. return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else if (placeAt != null) { placeCraftingtableNearby(); @@ -269,25 +269,27 @@ private boolean rightClick() { //shamelessly copied from go to block process bp = ((GoalGetToBlock)goal).getGoalPos(); break; } - logDirect("error rightclick was called without being next to goal. will throw nullpointer & crash mc"); } } else { bp = ((GoalGetToBlock)goal).getGoalPos(); } - Optional reachable = RotationUtils.reachable(ctx.player(), bp, ctx.playerController().getBlockReachDistance()); - if (reachable.isPresent()) { - baritone.getLookBehavior().updateTarget(reachable.get(), true); - if (bp.equals(ctx.getSelectedBlock().orElse(null))) { - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); - System.out.println(ctx.player().openContainer); - if (!(ctx.player().openContainer instanceof ContainerPlayer)) { - baritone.getInputOverrideHandler().clearAllKeys(); - return true; + if (bp != null) { + Optional reachable = RotationUtils.reachable(ctx.player(), bp, ctx.playerController().getBlockReachDistance()); + if (reachable.isPresent()) { + baritone.getLookBehavior().updateTarget(reachable.get(), true); + if (bp.equals(ctx.getSelectedBlock().orElse(null))) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + System.out.println(ctx.player().openContainer); + if (!(ctx.player().openContainer instanceof ContainerPlayer)) { + baritone.getInputOverrideHandler().clearAllKeys(); + return true; + } } + return false; } - return false; + return true; } - return true; + return false; } private void placeCraftingtableNearby() { //this code is so buggy im amazed that there are special cases where it works From 857acd42cae790782bd5077fdde643a1e76dc2dc Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Wed, 14 Jun 2023 10:20:51 +0200 Subject: [PATCH 29/39] copying a good part of builder process --- .../baritone/process/CraftingProcess.java | 182 ++++++++++++++++-- 1 file changed, 165 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 31102b2f4..dd11af966 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -21,15 +21,19 @@ import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalComposite; import baritone.api.pathing.goals.GoalGetToBlock; +import baritone.api.pathing.goals.GoalRunAway; import baritone.api.process.ICraftingProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; -import baritone.api.utils.BlockOptionalMetaLookup; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; +import baritone.api.schematic.FillSchematic; +import baritone.api.schematic.ISchematic; +import baritone.api.utils.*; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; +import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; +import baritone.utils.BlockStateInterface; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.util.RecipeItemHelper; import net.minecraft.init.Blocks; @@ -37,21 +41,23 @@ import net.minecraft.inventory.ContainerPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { private int amount; private IRecipe recipe; private Goal goal; - private BlockPos placeAt; + private boolean placeCraftingTable = false; private boolean clearToPush = true; public CraftingProcess(Baritone baritone) { @@ -69,7 +75,7 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa logDirect("path calculation failed"); onLostControl(); } - if (goal != null) { + if (goal != null && !(goal instanceof GoalRunAway)) { //we are pathing to a table and therefor have to wait. if (goal.isInGoal(ctx.playerFeet())) { rightClick(); @@ -78,7 +84,7 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } } return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); - } else if (placeAt != null) { + } else if (placeCraftingTable) { placeCraftingtableNearby(); return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else { @@ -101,7 +107,7 @@ public synchronized void onLostControl() { amount = 0; recipe = null; goal = null; - placeAt = null; + placeCraftingTable = false; baritone.getInputOverrideHandler().clearAllKeys(); } @@ -237,7 +243,7 @@ private void getACraftingTable() { List knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); if (knownLocations.isEmpty()) { if (hasCraftingTable()) { - placeAt = ctx.playerFeet().north(); + placeCraftingTable = true; } else { logDirect("Recipe requires a crafting table."); onLostControl(); @@ -294,12 +300,25 @@ private boolean rightClick() { //shamelessly copied from go to block process private void placeCraftingtableNearby() { //this code is so buggy im amazed that there are special cases where it works selectCraftingTable(); - //todo search and look at a position where the table can be placed - baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); - placeAt = null; - getACraftingTable(); + ISchematic schematic = new FillSchematic(5, 4, 5, Blocks.CRAFTING_TABLE.getDefaultState()); + + List desirableOnHotbar = new ArrayList<>(); + Optional toPlace = searchForPlaceables(schematic, desirableOnHotbar); + + if (toPlace.isPresent()) { + Rotation rot = toPlace.get().rot; + baritone.getLookBehavior().updateTarget(rot, true); + ctx.player().inventory.currentItem = toPlace.get().hotbarSelection; + baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); + if ((ctx.isLookingAt(toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + placeCraftingTable = false; + getACraftingTable(); + } + } else { + goal = new GoalRunAway(5, ctx.playerFeet()); + } } private void selectCraftingTable() { @@ -316,4 +335,133 @@ private void selectCraftingTable() { } } } + + private Optional searchForPlaceables(ISchematic schematic, List desirableOnHotbar) { + BetterBlockPos center = ctx.playerFeet(); + for (int dx = -5; dx <= 5; dx++) { + for (int dy = -5; dy <= 1; dy++) { + for (int dz = -5; dz <= 5; dz++) { + int x = center.x + dx; + int y = center.y + dy; + int z = center.z + dz; + List approxPlacable = new ArrayList<>(); + approxPlacable.add(Blocks.CRAFTING_TABLE.getDefaultState()); + IBlockState desired = schematic.desiredState(x, y, z, baritone.bsi.get0(x, y, z), approxPlacable); + if (desired == null) { + continue; // irrelevant + } + IBlockState curr = baritone.bsi.get0(x, y, z); + if (MovementHelper.isReplaceable(x, y, z, curr, baritone.bsi) && !valid(curr, desired, false)) { + if (dy == 1 && baritone.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) { + continue; + } + desirableOnHotbar.add(desired); + Optional opt = possibleToPlace(desired, x, y, z, baritone.bsi); + if (opt.isPresent()) { + return opt; + } + } + } + } + } + return Optional.empty(); + } + + private boolean valid(IBlockState current, IBlockState desired, boolean itemVerify) { + if (desired == null) { + return true; + } + return current.equals(desired); + } + + private Optional possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) { + for (EnumFacing against : EnumFacing.values()) { + BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against); + IBlockState placeAgainstState = bsi.get0(placeAgainstPos); + if (MovementHelper.isReplaceable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) { + continue; + } + if (!ctx.world().mayPlace(toPlace.getBlock(), new BetterBlockPos(x, y, z), false, against, null)) { + continue; + } + AxisAlignedBB aabb = placeAgainstState.getBoundingBox(ctx.world(), placeAgainstPos); + for (Vec3d placementMultiplier : aabbSideMultipliers(against)) { + double placeX = placeAgainstPos.x + aabb.minX * placementMultiplier.x + aabb.maxX * (1 - placementMultiplier.x); + double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y); + double placeZ = placeAgainstPos.z + aabb.minZ * placementMultiplier.z + aabb.maxZ * (1 - placementMultiplier.z); + Rotation rot = RotationUtils.calcRotationFromVec3d(RayTraceUtils.inferSneakingEyePosition(ctx.player()), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations()); + RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance(), true); + if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) { + OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot); + if (hotbar.isPresent()) { + return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot)); + } + } + } + } + return Optional.empty(); + } + + private static Vec3d[] aabbSideMultipliers(EnumFacing side) { + switch (side) { + case UP: + return new Vec3d[]{new Vec3d(0.5, 1, 0.5), new Vec3d(0.1, 1, 0.5), new Vec3d(0.9, 1, 0.5), new Vec3d(0.5, 1, 0.1), new Vec3d(0.5, 1, 0.9)}; + case DOWN: + return new Vec3d[]{new Vec3d(0.5, 0, 0.5), new Vec3d(0.1, 0, 0.5), new Vec3d(0.9, 0, 0.5), new Vec3d(0.5, 0, 0.1), new Vec3d(0.5, 0, 0.9)}; + case NORTH: + case SOUTH: + case EAST: + case WEST: + double x = side.getXOffset() == 0 ? 0.5 : (1 + side.getXOffset()) / 2D; + double z = side.getZOffset() == 0 ? 0.5 : (1 + side.getZOffset()) / 2D; + return new Vec3d[]{new Vec3d(x, 0.25, z), new Vec3d(x, 0.75, z)}; + default: // null + throw new IllegalStateException(); + } + } + + private OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) { + for (int i = 0; i < 9; i++) { + ItemStack stack = ctx.player().inventory.mainInventory.get(i); + if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock)) { + continue; + } + float originalYaw = ctx.player().rotationYaw; + float originalPitch = ctx.player().rotationPitch; + // the state depends on the facing of the player sometimes + ctx.player().rotationYaw = rot.getYaw(); + ctx.player().rotationPitch = rot.getPitch(); + IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement( + ctx.world(), + result.getBlockPos().offset(result.sideHit), + result.sideHit, + (float) result.hitVec.x - result.getBlockPos().getX(), // as in PlayerControllerMP + (float) result.hitVec.y - result.getBlockPos().getY(), + (float) result.hitVec.z - result.getBlockPos().getZ(), + stack.getItem().getMetadata(stack.getMetadata()), + ctx.player() + ); + ctx.player().rotationYaw = originalYaw; + ctx.player().rotationPitch = originalPitch; + if (valid(wouldBePlaced, desired, true)) { + return OptionalInt.of(i); + } + } + return OptionalInt.empty(); + } + + public static class Placement { + + private final int hotbarSelection; + private final BlockPos placeAgainst; + private final EnumFacing side; + private final Rotation rot; + + public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) { + this.hotbarSelection = hotbarSelection; + this.placeAgainst = placeAgainst; + this.side = side; + this.rot = rot; + } + } } From 4285f539a7346e2d5bd7016cfc0dec92b3102955 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Wed, 14 Jun 2023 10:49:19 +0200 Subject: [PATCH 30/39] small tweaks --- src/main/java/baritone/process/CraftingProcess.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index dd11af966..1c06f65cb 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -71,13 +71,16 @@ public boolean isActive() { @Override public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - if (calcFailed) { //is this correct? + if (calcFailed) { logDirect("path calculation failed"); onLostControl(); - } - if (goal != null && !(goal instanceof GoalRunAway)) { + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + } else if (goal != null && !(goal instanceof GoalRunAway)) { //we are pathing to a table and therefor have to wait. if (goal.isInGoal(ctx.playerFeet())) { + if (baritone.getInputOverrideHandler().isInputForcedDown(Input.SNEAK)) { + baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, false); + } rightClick(); if (ctx.player().openContainer instanceof ContainerWorkbench) { goal = null; @@ -316,6 +319,7 @@ private void placeCraftingtableNearby() { //this code is so buggy im amazed that placeCraftingTable = false; getACraftingTable(); } + baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, false); } else { goal = new GoalRunAway(5, ctx.playerFeet()); } From 8c40be4ca12f6a6c096f7ba64e0e840b041be7b8 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Wed, 14 Jun 2023 11:14:12 +0200 Subject: [PATCH 31/39] i think its ready --- .../java/baritone/process/CraftingProcess.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 1c06f65cb..9c3e1220b 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -77,10 +77,13 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } else if (goal != null && !(goal instanceof GoalRunAway)) { //we are pathing to a table and therefor have to wait. + if (baritone.getInputOverrideHandler().isInputForcedDown(Input.SNEAK)) { + baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, false); + } + if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_RIGHT)) { + baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, false); + } if (goal.isInGoal(ctx.playerFeet())) { - if (baritone.getInputOverrideHandler().isInputForcedDown(Input.SNEAK)) { - baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, false); - } rightClick(); if (ctx.player().openContainer instanceof ContainerWorkbench) { goal = null; @@ -301,7 +304,7 @@ private boolean rightClick() { //shamelessly copied from go to block process return false; } - private void placeCraftingtableNearby() { //this code is so buggy im amazed that there are special cases where it works + private void placeCraftingtableNearby() { selectCraftingTable(); ISchematic schematic = new FillSchematic(5, 4, 5, Blocks.CRAFTING_TABLE.getDefaultState()); @@ -319,7 +322,6 @@ private void placeCraftingtableNearby() { //this code is so buggy im amazed that placeCraftingTable = false; getACraftingTable(); } - baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, false); } else { goal = new GoalRunAway(5, ctx.playerFeet()); } @@ -342,9 +344,9 @@ private void selectCraftingTable() { private Optional searchForPlaceables(ISchematic schematic, List desirableOnHotbar) { BetterBlockPos center = ctx.playerFeet(); - for (int dx = -5; dx <= 5; dx++) { - for (int dy = -5; dy <= 1; dy++) { - for (int dz = -5; dz <= 5; dz++) { + for (int dx = -2; dx <= 2; dx++) { + for (int dy = -2; dy <= 2; dy++) { + for (int dz = -2; dz <= 2; dz++) { int x = center.x + dx; int y = center.y + dy; int z = center.z + dz; From 32bd0b4d2ec392aa3bc98ced4926b557de9716d5 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Thu, 15 Jun 2023 21:10:57 +0200 Subject: [PATCH 32/39] changes on CraftCommand --- .../command/argparser/DefaultArgParsers.java | 35 ++++++++++++++++++- .../command/defaults/CraftCommand.java | 31 ++++++++-------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/main/java/baritone/command/argparser/DefaultArgParsers.java b/src/main/java/baritone/command/argparser/DefaultArgParsers.java index 77a14bf92..676fc7b9d 100644 --- a/src/main/java/baritone/command/argparser/DefaultArgParsers.java +++ b/src/main/java/baritone/command/argparser/DefaultArgParsers.java @@ -19,6 +19,7 @@ import baritone.api.command.argparser.IArgParser; import baritone.api.command.argument.ICommandArgument; +import net.minecraft.item.Item; import java.util.Arrays; import java.util.List; @@ -114,11 +115,43 @@ public Boolean parseArg(ICommandArgument arg) throws RuntimeException { } } + public static class ItemArgumentParser implements IArgParser.Stateless { + public static final ItemArgumentParser INSTANCE = new ItemArgumentParser(); + + @Override + public Class getTarget() { + return Item.class; + } + + @Override + public Item parseArg(ICommandArgument arg) throws Exception { + /* + String value = arg.getValue(); + Item item = Item.getByNameOrId(value); + if (item == null) { + for (IRecipe recipe : CraftingManager.REGISTRY) { + if (recipe.getRecipeOutput().getDisplayName().equalsIgnoreCase(value)) { + return recipe.getRecipeOutput().getItem(); + } + } + throw new IllegalArgumentException("invalid item"); + } else { + return item; + }/**/ + Item item = Item.getByNameOrId(arg.getValue()); + if (item == null) { + throw new IllegalArgumentException("invalid item"); + } + return item; + } + } + public static final List> ALL = Arrays.asList( IntArgumentParser.INSTANCE, LongArgumentParser.INSTANCE, FloatArgumentParser.INSTANCE, DoubleArgumentParser.INSTANCE, - BooleanArgumentParser.INSTANCE + BooleanArgumentParser.INSTANCE, + ItemArgumentParser.INSTANCE ); } diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index 4142344d2..b3379b0fa 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -38,35 +38,34 @@ protected CraftCommand(IBaritone baritone) { @Override public void execute(String label, IArgConsumer args) throws CommandException { - String itemName = args.getString(); - Item item = Item.getByNameOrId(itemName); + int amount = args.getAsOrDefault(Integer.class, 1); - int amount = args.hasAny() ? args.getAs(Integer.class) : 1; + Item item = args.getAsOrNull(Item.class); - if (item == null) {//this is hacky, but it gets the job done for now. also we arnt interested in non craft-able items anyway - itemName = itemName.replace("_", " "); - boolean recipeExists = false; + if (item == null) { + String itemName = args.rawRest(); + //boolean recipeExists = false; for (IRecipe recipe : CraftingManager.REGISTRY) { if (recipe.getRecipeOutput().getDisplayName().equalsIgnoreCase(itemName)) { if (baritone.getCraftingProcess().canCraft(recipe, amount)) { baritone.getCraftingProcess().craftRecipe(recipe, amount); return; - } else { //a recipe exists but we cant craft it + } /*else { //a recipe exists but we cant craft it recipeExists = true; - } + }/**/ } - } + }/* if (recipeExists) { logDirect("Insufficient Resources"); } else { logDirect("Invalid Item"); - } + }/**/ } else if (!baritone.getCraftingProcess().hasCraftingRecipe(item)) { logDirect("no crafting recipe for "+item.getTranslationKey()+" found."); - } else if (baritone.getCraftingProcess().canCraft(item, amount)){ - baritone.getCraftingProcess().craftItem(item, amount); - } else { + } else if (!baritone.getCraftingProcess().canCraft(item, amount)){ logDirect("Insufficient Resources"); + } else { + baritone.getCraftingProcess().craftItem(item, amount); } } @@ -92,10 +91,10 @@ public List getLongDesc() { "Go to a crafting table and craft a item.", "", "Usage:", - "> craft [item] - Go to a crafting table, and craft a item.", + "> craft [quantity] - Go to a crafting table, and craft a item.", "Examples:", - "> craft planks 17 -> will craft 20 planks of any logs you have.", - "> craft oak_wood_planks -> will craft 4 oak wood planks." + "> craft 17 planks -> will craft 20 planks out of any logs you have.", + "> craft oak wood planks -> will craft 4 oak wood planks." ); } } \ No newline at end of file From 15a4cc311336127fadc8e579f62916877cc27e8e Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Fri, 16 Jun 2023 01:14:06 +0200 Subject: [PATCH 33/39] changes on CraftingProcess --- .../baritone/process/CraftingProcess.java | 76 +++++++++---------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 9c3e1220b..542298ee3 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -45,6 +45,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; +import net.minecraft.network.play.client.CPacketPlaceRecipe; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -58,7 +59,9 @@ public final class CraftingProcess extends BaritoneProcessHelper implements ICra private IRecipe recipe; private Goal goal; private boolean placeCraftingTable = false; - private boolean clearToPush = true; + private boolean clearToPush; + List knownLocations; + private int tickCount; public CraftingProcess(Baritone baritone) { super(baritone); @@ -77,12 +80,7 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } else if (goal != null && !(goal instanceof GoalRunAway)) { //we are pathing to a table and therefor have to wait. - if (baritone.getInputOverrideHandler().isInputForcedDown(Input.SNEAK)) { - baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, false); - } - if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_RIGHT)) { - baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, false); - } + baritone.getInputOverrideHandler().clearAllKeys(); if (goal.isInGoal(ctx.playerFeet())) { rightClick(); if (ctx.player().openContainer instanceof ContainerWorkbench) { @@ -114,6 +112,7 @@ public synchronized void onLostControl() { recipe = null; goal = null; placeCraftingTable = false; + knownLocations = null; baritone.getInputOverrideHandler().clearAllKeys(); } @@ -125,9 +124,12 @@ public String displayName0() { @Override public void craftItem(Item item, int amount) { if (canCraft(item, amount)) { + this.recipe = getCraftingRecipeForItem(item, amount); this.amount = amount; + clearToPush = true; logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); if (!canCraftInInventory(recipe)) { + knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); getACraftingTable(); } } else { @@ -140,8 +142,10 @@ public void craftRecipe(IRecipe recipe, int amount) { if (canCraft(recipe, amount)) { this.recipe = recipe; this.amount = amount; + clearToPush = true; logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); if (!canCraftInInventory(recipe)) { + knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); getACraftingTable(); } } else { @@ -174,7 +178,6 @@ public boolean canCraft(Item item, int amount) { List recipeList = getCraftingRecipes(item); for (IRecipe recipe : recipeList) { if (canCraft(recipe, amount)) { - this.recipe = recipe; return true; } } @@ -195,7 +198,17 @@ public boolean canCraft(IRecipe recipe, int amount) { @Override public boolean canCraftInInventory(IRecipe recipe) { - return recipe.canFit(2,2) && !ctx.player().isCreative(); + return recipe.canFit(2, 2) && !ctx.player().isCreative(); + } + + private IRecipe getCraftingRecipeForItem(Item item, int amount) { + List recipeList = getCraftingRecipes(item); + for (IRecipe recipe : recipeList) { + if (canCraft(recipe, amount)) { + return recipe; + } + } + return null; } private void moveItemsToCraftingGrid() { @@ -203,7 +216,7 @@ private void moveItemsToCraftingGrid() { int windowId = ctx.player().openContainer.windowId; //try to put the recipe the required amount of times in to the crafting grid. for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { - mc.playerController.func_194338_a(windowId, recipe, GuiScreen.isShiftKeyDown(), ctx.player()); + ctx.player().connection.sendPacket(new CPacketPlaceRecipe(windowId, recipe, GuiScreen.isShiftKeyDown())); } } @@ -212,8 +225,8 @@ private void takeResultFromOutput() { if (inputCount > 0) { int windowId = ctx.player().openContainer.windowId; int slotID = 0; //slot id. for crafting table output it is 0 - int randomIntWeDontNeedButHaveToProvide = 0; //idk isnt used - mc.playerController.windowClick(windowId, slotID, randomIntWeDontNeedButHaveToProvide, ClickType.QUICK_MOVE, ctx.player()); + int mouseButton = 0; //idk isnt used + ctx.playerController().windowClick(windowId, slotID, mouseButton, ClickType.QUICK_MOVE, ctx.player()); amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); clearToPush = true; } @@ -246,9 +259,12 @@ private int getInputCount() { } private void getACraftingTable() { - List knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value; + if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { + knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + } if (knownLocations.isEmpty()) { - if (hasCraftingTable()) { + if (baritone.getInventoryBehavior().throwaway(false, this::isCraftingTable)) { placeCraftingTable = true; } else { logDirect("Recipe requires a crafting table."); @@ -259,13 +275,8 @@ private void getACraftingTable() { } } - private boolean hasCraftingTable() { - for (ItemStack itemstack : ctx.player().inventory.mainInventory) { - if (itemstack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { - return true; - } - } - return false; + private boolean isCraftingTable(ItemStack itemStack) { + return itemStack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE); } private Goal createGoal(BlockPos pos) { @@ -275,15 +286,15 @@ private Goal createGoal(BlockPos pos) { private boolean rightClick() { //shamelessly copied from go to block process BlockPos bp = null; if (goal instanceof GoalComposite) { - Goal[] goals = ((GoalComposite)goal).goals(); + Goal[] goals = ((GoalComposite) goal).goals(); for (Goal goal : goals) { if (goal.isInGoal(ctx.playerFeet()) && goal instanceof GoalGetToBlock) { - bp = ((GoalGetToBlock)goal).getGoalPos(); + bp = ((GoalGetToBlock) goal).getGoalPos(); break; } } } else { - bp = ((GoalGetToBlock)goal).getGoalPos(); + bp = ((GoalGetToBlock) goal).getGoalPos(); } if (bp != null) { Optional reachable = RotationUtils.reachable(ctx.player(), bp, ctx.playerController().getBlockReachDistance()); @@ -305,7 +316,7 @@ private boolean rightClick() { //shamelessly copied from go to block process } private void placeCraftingtableNearby() { - selectCraftingTable(); + baritone.getInventoryBehavior().throwaway(true, this::isCraftingTable); ISchematic schematic = new FillSchematic(5, 4, 5, Blocks.CRAFTING_TABLE.getDefaultState()); @@ -327,21 +338,6 @@ private void placeCraftingtableNearby() { } } - private void selectCraftingTable() { - for (int i = 0; i < 36; i++) { - ItemStack stack = ctx.player().inventory.mainInventory.get(i); - if (stack.getItem() == Item.getItemFromBlock(Blocks.CRAFTING_TABLE)) { - if (i < 9) { - ctx.player().inventory.currentItem = i; - return; - } else { - baritone.getInventoryBehavior().attemptToPutOnHotbar(i, null); - i=0; - } - } - } - } - private Optional searchForPlaceables(ISchematic schematic, List desirableOnHotbar) { BetterBlockPos center = ctx.playerFeet(); for (int dx = -2; dx <= 2; dx++) { From df3f7a3b5e0e2eb5499c05c2704cf8a0d386d305 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sat, 17 Jun 2023 23:37:21 +0200 Subject: [PATCH 34/39] changes on CraftingProcess II --- .../baritone/process/CraftingProcess.java | 145 ++++++------------ 1 file changed, 48 insertions(+), 97 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 542298ee3..51f05d01f 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -25,8 +25,6 @@ import baritone.api.process.ICraftingProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; -import baritone.api.schematic.FillSchematic; -import baritone.api.schematic.ISchematic; import baritone.api.utils.*; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; @@ -41,7 +39,6 @@ import net.minecraft.inventory.ContainerPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; @@ -60,8 +57,7 @@ public final class CraftingProcess extends BaritoneProcessHelper implements ICra private Goal goal; private boolean placeCraftingTable = false; private boolean clearToPush; - List knownLocations; - private int tickCount; + private List knownLocations; public CraftingProcess(Baritone baritone) { super(baritone); @@ -89,7 +85,7 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else if (placeCraftingTable) { - placeCraftingtableNearby(); + placeCraftingTable(); return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } else { //we no longer pathing so it's time to craft @@ -129,8 +125,7 @@ public void craftItem(Item item, int amount) { clearToPush = true; logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); if (!canCraftInInventory(recipe)) { - knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - getACraftingTable(); + pathToACraftingTable(); } } else { logDirect("Insufficient resources."); @@ -145,8 +140,7 @@ public void craftRecipe(IRecipe recipe, int amount) { clearToPush = true; logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); if (!canCraftInInventory(recipe)) { - knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - getACraftingTable(); + pathToACraftingTable(); } } else { logDirect("Insufficient resources."); @@ -224,8 +218,8 @@ private void takeResultFromOutput() { int inputCount = getInputCount(); if (inputCount > 0) { int windowId = ctx.player().openContainer.windowId; - int slotID = 0; //slot id. for crafting table output it is 0 - int mouseButton = 0; //idk isnt used + int slotID = 0; //see cheat sheet https://wiki.vg/Inventory + int mouseButton = 0; ctx.playerController().windowClick(windowId, slotID, mouseButton, ClickType.QUICK_MOVE, ctx.player()); amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); clearToPush = true; @@ -258,11 +252,8 @@ private int getInputCount() { return stackSize == Integer.MAX_VALUE ? 0 : stackSize; } - private void getACraftingTable() { - int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value; - if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { - knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - } + private void pathToACraftingTable() { + knownLocations = MineProcess.searchWorld(new CalculationContext(baritone, false), new BlockOptionalMetaLookup(Blocks.CRAFTING_TABLE), 64, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); if (knownLocations.isEmpty()) { if (baritone.getInventoryBehavior().throwaway(false, this::isCraftingTable)) { placeCraftingTable = true; @@ -283,7 +274,7 @@ private Goal createGoal(BlockPos pos) { return new GoalGetToBlock(pos); } - private boolean rightClick() { //shamelessly copied from go to block process + private void rightClick() { BlockPos bp = null; if (goal instanceof GoalComposite) { Goal[] goals = ((GoalComposite) goal).goals(); @@ -293,52 +284,62 @@ private boolean rightClick() { //shamelessly copied from go to block process break; } } - } else { + } else if (goal instanceof GoalGetToBlock) { bp = ((GoalGetToBlock) goal).getGoalPos(); } + if (bp != null) { - Optional reachable = RotationUtils.reachable(ctx.player(), bp, ctx.playerController().getBlockReachDistance()); + Optional reachable = RotationUtils.reachable(ctx, bp, ctx.playerController().getBlockReachDistance()); if (reachable.isPresent()) { baritone.getLookBehavior().updateTarget(reachable.get(), true); if (bp.equals(ctx.getSelectedBlock().orElse(null))) { baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); - System.out.println(ctx.player().openContainer); if (!(ctx.player().openContainer instanceof ContainerPlayer)) { baritone.getInputOverrideHandler().clearAllKeys(); - return true; } } - return false; } - return true; } - return false; } - private void placeCraftingtableNearby() { - baritone.getInventoryBehavior().throwaway(true, this::isCraftingTable); - - ISchematic schematic = new FillSchematic(5, 4, 5, Blocks.CRAFTING_TABLE.getDefaultState()); - - List desirableOnHotbar = new ArrayList<>(); - Optional toPlace = searchForPlaceables(schematic, desirableOnHotbar); + private void placeCraftingTable() { + Optional toPlace = searchPlacement(); if (toPlace.isPresent()) { Rotation rot = toPlace.get().rot; baritone.getLookBehavior().updateTarget(rot, true); - ctx.player().inventory.currentItem = toPlace.get().hotbarSelection; + baritone.getInventoryBehavior().throwaway(true, this::isCraftingTable); baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true); if ((ctx.isLookingAt(toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) { baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); + //now that the table is placed path to it placeCraftingTable = false; - getACraftingTable(); + goal = new GoalGetToBlock(toPlace.get().placeAgainst.offset(toPlace.get().side)); } } else { goal = new GoalRunAway(5, ctx.playerFeet()); } } - private Optional searchForPlaceables(ISchematic schematic, List desirableOnHotbar) { + private Optional searchPlacement() { + for (BetterBlockPos bbp : blockPosListSortedByDistanceFromCenter()) { + if (MovementHelper.isReplaceable(bbp.x, bbp.y, bbp.z, baritone.bsi.get0(bbp.x, bbp.y, bbp.z), baritone.bsi)) { + if (bbp.y == ctx.playerHead().y && baritone.bsi.get0(bbp.x, bbp.y + 1, bbp.z).getBlock() == Blocks.AIR) { + continue; + } + Optional opt = possibleToPlace(Blocks.CRAFTING_TABLE.getDefaultState(), bbp.x, bbp.y, bbp.z, baritone.bsi); + if (opt.isPresent()) { + return opt; + } + } + } + return Optional.empty(); + } + + private List blockPosListSortedByDistanceFromCenter() { + //this is so stupid idk why im doing this + Map map = new HashMap<>(); + List usedIndexes = new ArrayList<>(); BetterBlockPos center = ctx.playerFeet(); for (int dx = -2; dx <= 2; dx++) { for (int dy = -2; dy <= 2; dy++) { @@ -346,34 +347,20 @@ private Optional searchForPlaceables(ISchematic schematic, List approxPlacable = new ArrayList<>(); - approxPlacable.add(Blocks.CRAFTING_TABLE.getDefaultState()); - IBlockState desired = schematic.desiredState(x, y, z, baritone.bsi.get0(x, y, z), approxPlacable); - if (desired == null) { - continue; // irrelevant - } - IBlockState curr = baritone.bsi.get0(x, y, z); - if (MovementHelper.isReplaceable(x, y, z, curr, baritone.bsi) && !valid(curr, desired, false)) { - if (dy == 1 && baritone.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) { - continue; - } - desirableOnHotbar.add(desired); - Optional opt = possibleToPlace(desired, x, y, z, baritone.bsi); - if (opt.isPresent()) { - return opt; - } + + BetterBlockPos bbp = new BetterBlockPos(x, y, z); + int approxPosInList = (int) bbp.distanceSq(center) * 1000; + while (usedIndexes.contains(approxPosInList)) { + approxPosInList++; } + map.put(approxPosInList, bbp); + usedIndexes.add(approxPosInList); } } } - return Optional.empty(); - } - - private boolean valid(IBlockState current, IBlockState desired, boolean itemVerify) { - if (desired == null) { - return true; - } - return current.equals(desired); + List sortedlist = new ArrayList<>(); + map.keySet().stream().sorted().forEach(key -> sortedlist.add(map.get(key))); + return sortedlist; } private Optional possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) { @@ -394,10 +381,7 @@ private Optional possibleToPlace(IBlockState toPlace, int x, int y, i Rotation rot = RotationUtils.calcRotationFromVec3d(RayTraceUtils.inferSneakingEyePosition(ctx.player()), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations()); RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance(), true); if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) { - OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot); - if (hotbar.isPresent()) { - return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot)); - } + return Optional.of(new Placement(placeAgainstPos, against.getOpposite(), rot)); } } } @@ -422,45 +406,12 @@ private static Vec3d[] aabbSideMultipliers(EnumFacing side) { } } - private OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) { - for (int i = 0; i < 9; i++) { - ItemStack stack = ctx.player().inventory.mainInventory.get(i); - if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock)) { - continue; - } - float originalYaw = ctx.player().rotationYaw; - float originalPitch = ctx.player().rotationPitch; - // the state depends on the facing of the player sometimes - ctx.player().rotationYaw = rot.getYaw(); - ctx.player().rotationPitch = rot.getPitch(); - IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement( - ctx.world(), - result.getBlockPos().offset(result.sideHit), - result.sideHit, - (float) result.hitVec.x - result.getBlockPos().getX(), // as in PlayerControllerMP - (float) result.hitVec.y - result.getBlockPos().getY(), - (float) result.hitVec.z - result.getBlockPos().getZ(), - stack.getItem().getMetadata(stack.getMetadata()), - ctx.player() - ); - ctx.player().rotationYaw = originalYaw; - ctx.player().rotationPitch = originalPitch; - if (valid(wouldBePlaced, desired, true)) { - return OptionalInt.of(i); - } - } - return OptionalInt.empty(); - } - public static class Placement { - - private final int hotbarSelection; private final BlockPos placeAgainst; private final EnumFacing side; private final Rotation rot; - public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) { - this.hotbarSelection = hotbarSelection; + public Placement(BlockPos placeAgainst, EnumFacing side, Rotation rot) { this.placeAgainst = placeAgainst; this.side = side; this.rot = rot; From 29d1df4f68f45b544d54f4cdb38257b151aa0689 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 18 Jun 2023 00:04:14 +0200 Subject: [PATCH 35/39] add recipe switching for item crafting --- .../baritone/process/CraftingProcess.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 51f05d01f..9cb7e994e 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -120,10 +120,10 @@ public String displayName0() { @Override public void craftItem(Item item, int amount) { if (canCraft(item, amount)) { - this.recipe = getCraftingRecipeForItem(item, amount); + this.recipe = getCraftingRecipeForItem(item); this.amount = amount; clearToPush = true; - logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); + logDirect("Crafting now " + amount + "x [" + item.getTranslationKey() + "]"); if (!canCraftInInventory(recipe)) { pathToACraftingTable(); } @@ -170,12 +170,17 @@ public ArrayList getCraftingRecipes(Item item) { //should this be in a helper class? public boolean canCraft(Item item, int amount) { List recipeList = getCraftingRecipes(item); + RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); + for (ItemStack stack : ctx.player().inventory.mainInventory) { + recipeItemHelper.accountStack(stack); + } + int totalPossibleToCraft = 0; for (IRecipe recipe : recipeList) { - if (canCraft(recipe, amount)) { - return true; + if (canCraft(recipe, 1)) { + totalPossibleToCraft = totalPossibleToCraft + (recipeItemHelper.getBiggestCraftableStack(recipe,null) * recipe.getRecipeOutput().getCount()); } } - return false; + return totalPossibleToCraft >= amount; } @Override @@ -195,10 +200,10 @@ public boolean canCraftInInventory(IRecipe recipe) { return recipe.canFit(2, 2) && !ctx.player().isCreative(); } - private IRecipe getCraftingRecipeForItem(Item item, int amount) { + private IRecipe getCraftingRecipeForItem(Item item) { List recipeList = getCraftingRecipes(item); for (IRecipe recipe : recipeList) { - if (canCraft(recipe, amount)) { + if (canCraft(recipe, 1)) { return recipe; } } @@ -208,6 +213,9 @@ private IRecipe getCraftingRecipeForItem(Item item, int amount) { private void moveItemsToCraftingGrid() { clearToPush = false; int windowId = ctx.player().openContainer.windowId; + if (!canCraft(recipe,1) && amount > 0) { + recipe = getCraftingRecipeForItem(recipe.getRecipeOutput().getItem()); + } //try to put the recipe the required amount of times in to the crafting grid. for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { ctx.player().connection.sendPacket(new CPacketPlaceRecipe(windowId, recipe, GuiScreen.isShiftKeyDown())); From 1ef0feb63aacb67738329049adc30dc9166f755c Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 18 Jun 2023 00:49:31 +0200 Subject: [PATCH 36/39] ready for round two --- .../java/baritone/process/CraftingProcess.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 9cb7e994e..1a1d8cc1f 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -90,6 +90,13 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } else { //we no longer pathing so it's time to craft try { + if (!canCraft(recipe,1) && amount > 0) { + recipe = getCraftingRecipeForItem(recipe.getRecipeOutput().getItem()); + if (!canCraftInInventory(recipe) && !(ctx.player().openContainer instanceof ContainerWorkbench)) { + pathToACraftingTable(); + return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); + } + } if (clearToPush) { moveItemsToCraftingGrid(); } @@ -176,9 +183,7 @@ public boolean canCraft(Item item, int amount) { } int totalPossibleToCraft = 0; for (IRecipe recipe : recipeList) { - if (canCraft(recipe, 1)) { - totalPossibleToCraft = totalPossibleToCraft + (recipeItemHelper.getBiggestCraftableStack(recipe,null) * recipe.getRecipeOutput().getCount()); - } + totalPossibleToCraft = totalPossibleToCraft + (recipeItemHelper.getBiggestCraftableStack(recipe,null) * recipe.getRecipeOutput().getCount()); } return totalPossibleToCraft >= amount; } @@ -213,9 +218,6 @@ private IRecipe getCraftingRecipeForItem(Item item) { private void moveItemsToCraftingGrid() { clearToPush = false; int windowId = ctx.player().openContainer.windowId; - if (!canCraft(recipe,1) && amount > 0) { - recipe = getCraftingRecipeForItem(recipe.getRecipeOutput().getItem()); - } //try to put the recipe the required amount of times in to the crafting grid. for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { ctx.player().connection.sendPacket(new CPacketPlaceRecipe(windowId, recipe, GuiScreen.isShiftKeyDown())); From fbd1e0cdc1cea5e8f6766fc38415d9bf314ca5d7 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Sun, 18 Jun 2023 02:50:49 +0200 Subject: [PATCH 37/39] oopsie --- src/main/java/baritone/Baritone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index b92ed3e2e..da0575ac9 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -118,7 +118,7 @@ public class Baritone implements IBaritone { this.builderProcess = this.registerProcess(BuilderProcess::new); this.exploreProcess = this.registerProcess(ExploreProcess::new); this.farmProcess = this.registerProcess(FarmProcess::new); - this.craftingProcess = this.registerBehavior(CraftingProcess::new); + this.craftingProcess = this.registerProcess(CraftingProcess::new); this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); this.registerProcess(BackfillProcess::new); } From 6ddfdd5f3ae0610542fc4846ac7e5f8d946b6aa1 Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:47:36 +0200 Subject: [PATCH 38/39] change CraftCommand --- .../java/baritone/command/defaults/CraftCommand.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index b3379b0fa..54933c3cc 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -40,26 +40,26 @@ protected CraftCommand(IBaritone baritone) { public void execute(String label, IArgConsumer args) throws CommandException { int amount = args.getAsOrDefault(Integer.class, 1); - Item item = args.getAsOrNull(Item.class); + Item item = args.getDatatypeForOrNull(ItemById.INSTANCE); if (item == null) { String itemName = args.rawRest(); - //boolean recipeExists = false; + boolean recipeExists = false; for (IRecipe recipe : CraftingManager.REGISTRY) { if (recipe.getRecipeOutput().getDisplayName().equalsIgnoreCase(itemName)) { if (baritone.getCraftingProcess().canCraft(recipe, amount)) { baritone.getCraftingProcess().craftRecipe(recipe, amount); return; - } /*else { //a recipe exists but we cant craft it + } else { //a recipe exists but we cant craft it recipeExists = true; - }/**/ + } } - }/* + } if (recipeExists) { logDirect("Insufficient Resources"); } else { logDirect("Invalid Item"); - }/**/ + } } else if (!baritone.getCraftingProcess().hasCraftingRecipe(item)) { logDirect("no crafting recipe for "+item.getTranslationKey()+" found."); } else if (!baritone.getCraftingProcess().canCraft(item, amount)){ From 927fa4356903764f56cbcc7ef95c5d49ef6e4b7a Mon Sep 17 00:00:00 2001 From: rycbar0 <100363533+rycbar0@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:59:12 +0200 Subject: [PATCH 39/39] CraftingProcess uses now List --- .../api/process/ICraftingProcess.java | 38 ++----- .../command/defaults/CraftCommand.java | 31 +++--- .../baritone/process/CraftingProcess.java | 105 ++++++------------ 3 files changed, 54 insertions(+), 120 deletions(-) diff --git a/src/api/java/baritone/api/process/ICraftingProcess.java b/src/api/java/baritone/api/process/ICraftingProcess.java index 1bf7b3a2f..8fb260150 100644 --- a/src/api/java/baritone/api/process/ICraftingProcess.java +++ b/src/api/java/baritone/api/process/ICraftingProcess.java @@ -28,44 +28,26 @@ public interface ICraftingProcess extends IBaritoneProcess { /** - * Executes the crafting of the requested item such that we obtain the requested amount. - * @param item that should be crafted - * @param amount how much of that item is wanted. - */ - void craftItem(Item item, int amount); - - /** - * Executes the crafting of the requested recipe such that we obtain the requested amount of output. - * @param recipe recipe that should be used. + * Executes the crafting of the requested recipes such that we obtain the requested amount of output. + * It is possible to mix recipes with different out puts, but it may lead to strange results. + * @param recipes List of recipes that should be used. * @param amount how many result items are wanted. */ - void craftRecipe(IRecipe recipe, int amount); - - /** - * @param item that should be crafted. - * @return Can the item be crafted in a crafting table? - */ - boolean hasCraftingRecipe(Item item); - - /** - * @param item that should be crafted. - * @return List of all recipes that result in the provided Item. - */ - List getCraftingRecipes(Item item); + void craft(List recipes, int amount); /** * @param item that should be crafted. - * @param amount how much of this item should be crafted. - * @return Can we craft this item the requested amount of times? + * @param allCraftingRecipes if all crafting recipes should be returned or only the one that can be crafted + * @return List of recipes that result in the provided Item. */ - boolean canCraft(Item item, int amount); + List getCraftingRecipes(Item item, boolean allCraftingRecipes); /** - * @param recipe that should be crafted. + * @param recipes that should be crafted. * @param amount how much output is wanted. - * @return Can we craft this recipe to get the requested amount of output? + * @return Can we craft this the requested amount of output from the provided recipes? */ - boolean canCraft(IRecipe recipe, int amount); + boolean canCraft(List recipes, int amount); /** * @param recipe the recipe we want to craft. diff --git a/src/main/java/baritone/command/defaults/CraftCommand.java b/src/main/java/baritone/command/defaults/CraftCommand.java index 54933c3cc..70c22d363 100644 --- a/src/main/java/baritone/command/defaults/CraftCommand.java +++ b/src/main/java/baritone/command/defaults/CraftCommand.java @@ -26,6 +26,7 @@ import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; @@ -39,33 +40,27 @@ protected CraftCommand(IBaritone baritone) { @Override public void execute(String label, IArgConsumer args) throws CommandException { int amount = args.getAsOrDefault(Integer.class, 1); - Item item = args.getDatatypeForOrNull(ItemById.INSTANCE); + List recipes; - if (item == null) { + if (item != null) { + recipes = baritone.getCraftingProcess().getCraftingRecipes(item, false); + } else { String itemName = args.rawRest(); - boolean recipeExists = false; + recipes = new ArrayList<>(); for (IRecipe recipe : CraftingManager.REGISTRY) { if (recipe.getRecipeOutput().getDisplayName().equalsIgnoreCase(itemName)) { - if (baritone.getCraftingProcess().canCraft(recipe, amount)) { - baritone.getCraftingProcess().craftRecipe(recipe, amount); - return; - } else { //a recipe exists but we cant craft it - recipeExists = true; - } + recipes.add(recipe); } } - if (recipeExists) { - logDirect("Insufficient Resources"); - } else { - logDirect("Invalid Item"); - } - } else if (!baritone.getCraftingProcess().hasCraftingRecipe(item)) { - logDirect("no crafting recipe for "+item.getTranslationKey()+" found."); - } else if (!baritone.getCraftingProcess().canCraft(item, amount)){ + } + + if (recipes.isEmpty()) { + logDirect("no crafting recipe found."); + } else if (!baritone.getCraftingProcess().canCraft(recipes, amount)) { logDirect("Insufficient Resources"); } else { - baritone.getCraftingProcess().craftItem(item, amount); + baritone.getCraftingProcess().craft(recipes, amount); } } diff --git a/src/main/java/baritone/process/CraftingProcess.java b/src/main/java/baritone/process/CraftingProcess.java index 1a1d8cc1f..bfd6630e5 100644 --- a/src/main/java/baritone/process/CraftingProcess.java +++ b/src/main/java/baritone/process/CraftingProcess.java @@ -53,7 +53,7 @@ public final class CraftingProcess extends BaritoneProcessHelper implements ICraftingProcess { private int amount; - private IRecipe recipe; + private List recipes; private Goal goal; private boolean placeCraftingTable = false; private boolean clearToPush; @@ -65,7 +65,7 @@ public CraftingProcess(Baritone baritone) { @Override public boolean isActive() { - return recipe != null && amount >= 1; + return recipes != null && amount >= 1; } @Override @@ -90,12 +90,17 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa } else { //we no longer pathing so it's time to craft try { - if (!canCraft(recipe,1) && amount > 0) { - recipe = getCraftingRecipeForItem(recipe.getRecipeOutput().getItem()); - if (!canCraftInInventory(recipe) && !(ctx.player().openContainer instanceof ContainerWorkbench)) { - pathToACraftingTable(); - return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); + while (!canCraft(recipes.subList(0,1), 1) && amount > 0) { + if (recipes.size() == 1) { + logDirect("Insufficient Resources"); + onLostControl(); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } + recipes = recipes.subList(1, recipes.size()); + } + if (!canCraftInInventory(recipes.get(0)) && !(ctx.player().openContainer instanceof ContainerWorkbench)) { + pathToACraftingTable(); + return new PathingCommand(goal, PathingCommandType.SET_GOAL_AND_PATH); } if (clearToPush) { moveItemsToCraftingGrid(); @@ -112,7 +117,7 @@ public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCa @Override public synchronized void onLostControl() { amount = 0; - recipe = null; + recipes = null; goal = null; placeCraftingTable = false; knownLocations = null; @@ -121,52 +126,22 @@ public synchronized void onLostControl() { @Override public String displayName0() { - return "Crafting " + amount + "x " + recipe.getRecipeOutput().getDisplayName(); - } - - @Override - public void craftItem(Item item, int amount) { - if (canCraft(item, amount)) { - this.recipe = getCraftingRecipeForItem(item); - this.amount = amount; - clearToPush = true; - logDirect("Crafting now " + amount + "x [" + item.getTranslationKey() + "]"); - if (!canCraftInInventory(recipe)) { - pathToACraftingTable(); - } - } else { - logDirect("Insufficient resources."); - } - } - - @Override - public void craftRecipe(IRecipe recipe, int amount) { - if (canCraft(recipe, amount)) { - this.recipe = recipe; - this.amount = amount; - clearToPush = true; - logDirect("Crafting now " + amount + "x [" + recipe.getRecipeOutput().getDisplayName() + "]"); - if (!canCraftInInventory(recipe)) { - pathToACraftingTable(); - } - } else { - logDirect("Insufficient resources."); - } + return "Crafting " + amount + "x " + recipes.get(0).getRecipeOutput().getDisplayName(); } @Override - //should this be in a helper class? - public boolean hasCraftingRecipe(Item item) { - ArrayList recipes = getCraftingRecipes(item); - return !recipes.isEmpty(); + public void craft(List recipes, int amount) { + this.recipes = recipes; + this.amount = amount; + clearToPush = true; + logDirect("Crafting now " + amount + "x [" + recipes.get(0).getRecipeOutput().getDisplayName() + "]"); } @Override - //should this be in a helper class? - public ArrayList getCraftingRecipes(Item item) { - ArrayList recipes = new ArrayList<>(); + public List getCraftingRecipes(Item item, boolean allCraftingRecipes) { + List recipes = new ArrayList<>(); for (IRecipe recipe : CraftingManager.REGISTRY) { - if (recipe.getRecipeOutput().getItem().equals(item)) { + if (recipe.getRecipeOutput().getItem().equals(item) && (canCraft(recipe) || allCraftingRecipes)) { recipes.add(recipe); } } @@ -174,30 +149,22 @@ public ArrayList getCraftingRecipes(Item item) { } @Override - //should this be in a helper class? - public boolean canCraft(Item item, int amount) { - List recipeList = getCraftingRecipes(item); + public boolean canCraft(List recipes, int amount) { RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); for (ItemStack stack : ctx.player().inventory.mainInventory) { recipeItemHelper.accountStack(stack); } int totalPossibleToCraft = 0; - for (IRecipe recipe : recipeList) { + for (IRecipe recipe : recipes) { totalPossibleToCraft = totalPossibleToCraft + (recipeItemHelper.getBiggestCraftableStack(recipe,null) * recipe.getRecipeOutput().getCount()); } return totalPossibleToCraft >= amount; } - @Override - //should this be in a helper class? - public boolean canCraft(IRecipe recipe, int amount) { - RecipeItemHelper recipeItemHelper = new RecipeItemHelper(); - for (ItemStack stack : ctx.player().inventory.mainInventory) { - recipeItemHelper.accountStack(stack); - } - int outputCount = recipe.getRecipeOutput().getCount(); - int times = amount % outputCount == 0 ? amount / outputCount : (amount / outputCount) + 1; - return recipeItemHelper.canCraft(recipe, null, times); + private boolean canCraft(IRecipe recipe) { + List recipeList = new ArrayList<>(); + recipeList.add(recipe); + return canCraft(recipeList, 1); } @Override @@ -205,22 +172,12 @@ public boolean canCraftInInventory(IRecipe recipe) { return recipe.canFit(2, 2) && !ctx.player().isCreative(); } - private IRecipe getCraftingRecipeForItem(Item item) { - List recipeList = getCraftingRecipes(item); - for (IRecipe recipe : recipeList) { - if (canCraft(recipe, 1)) { - return recipe; - } - } - return null; - } - private void moveItemsToCraftingGrid() { clearToPush = false; int windowId = ctx.player().openContainer.windowId; //try to put the recipe the required amount of times in to the crafting grid. - for (int i = 0; i * recipe.getRecipeOutput().getCount() < amount; i++) { - ctx.player().connection.sendPacket(new CPacketPlaceRecipe(windowId, recipe, GuiScreen.isShiftKeyDown())); + for (int i = 0; i * recipes.get(0).getRecipeOutput().getCount() < amount; i++) { + ctx.player().connection.sendPacket(new CPacketPlaceRecipe(windowId, recipes.get(0), GuiScreen.isShiftKeyDown())); } } @@ -231,7 +188,7 @@ private void takeResultFromOutput() { int slotID = 0; //see cheat sheet https://wiki.vg/Inventory int mouseButton = 0; ctx.playerController().windowClick(windowId, slotID, mouseButton, ClickType.QUICK_MOVE, ctx.player()); - amount = amount - (recipe.getRecipeOutput().getCount() * inputCount); + amount = amount - (recipes.get(0).getRecipeOutput().getCount() * inputCount); clearToPush = true; }