Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Crafting command #3960

Draft
wants to merge 44 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e14afe5
Create CraftCommand.java
strubium May 18, 2023
aa18fdf
Update CraftCommand.java
strubium May 18, 2023
5c0fe9c
Update Settings.java
strubium May 18, 2023
15efa2b
More info in description
strubium May 18, 2023
4c5a5da
Update DefaultCommands.java
strubium May 18, 2023
31976c1
Add chat notifier
strubium May 18, 2023
6e71d89
Merge pull request #5 from strubium/master
rycbar0 May 22, 2023
1547431
prototype
rycbar0 May 25, 2023
a443dcc
not sure if this goes in the right direction
rycbar0 May 25, 2023
e7a36ec
resolving some mixin problems
rycbar0 May 26, 2023
98c1d64
revert some changes as they didnt worked out.
rycbar0 May 28, 2023
645dbc4
Update CraftingProcess.java
strubium Jun 2, 2023
5c61f53
Merge pull request #6 from strubium/patch-1
rycbar0 Jun 6, 2023
b009df2
craft-ability check
rycbar0 Jun 7, 2023
13c31c1
refactoring
rycbar0 Jun 7, 2023
c34eb89
small fix
rycbar0 Jun 8, 2023
49a33d0
remove autocraft setting because unused
rycbar0 Jun 8, 2023
79e417e
refactoring CraftingProcess
rycbar0 Jun 8, 2023
8d1b2c7
delete mixins because unused
rycbar0 Jun 8, 2023
1cb53c7
delete mixins because unused
rycbar0 Jun 8, 2023
c1f2d0c
revert changes on GetToBlockProcess
rycbar0 Jun 8, 2023
6d34c50
im hard at my limit here
rycbar0 Jun 8, 2023
f5c50df
i need help
rycbar0 Jun 8, 2023
f79077f
its amazing that it works sometimes
rycbar0 Jun 9, 2023
eae2dc3
delete extra line
rycbar0 Jun 11, 2023
ecfbc49
craft command
rycbar0 Jun 11, 2023
48dc674
getting closer to a finished product
rycbar0 Jun 11, 2023
0a85399
todos
rycbar0 Jun 11, 2023
4e71b04
codacy and selecting crafting table
rycbar0 Jun 13, 2023
d8c8884
comments and edge cases
rycbar0 Jun 13, 2023
857acd4
copying a good part of builder process
rycbar0 Jun 14, 2023
4285f53
small tweaks
rycbar0 Jun 14, 2023
8c40be4
i think its ready
rycbar0 Jun 14, 2023
49e7892
Merge branch 'cabaletta:master' into crafting
rycbar0 Jun 14, 2023
7eed809
Merge remote-tracking branch 'origin/crafting' into crafting
rycbar0 Jun 14, 2023
32bd0b4
changes on CraftCommand
rycbar0 Jun 15, 2023
15a4cc3
changes on CraftingProcess
rycbar0 Jun 15, 2023
df3f7a3
changes on CraftingProcess II
rycbar0 Jun 17, 2023
29d1df4
add recipe switching for item crafting
rycbar0 Jun 17, 2023
1ef0feb
ready for round two
rycbar0 Jun 17, 2023
913ae06
Merge remote-tracking branch 'upstream/master' into crafting
rycbar0 Jun 18, 2023
fbd1e0c
oopsie
rycbar0 Jun 18, 2023
6ddfdd5
change CraftCommand
rycbar0 Jun 20, 2023
927fa43
CraftingProcess uses now List<IRecipe>
rycbar0 Jun 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactoring CraftingProcess
  • Loading branch information
rycbar0 committed Jun 8, 2023
commit 79e417e17def7eb62e6fcbc58421534229a0dc20
50 changes: 27 additions & 23 deletions src/api/java/baritone/api/process/ICraftingProcess.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<IRecipe> 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<IRecipe> 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);
}
137 changes: 60 additions & 77 deletions src/main/java/baritone/process/CraftingProcess.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -44,7 +43,6 @@ public CraftingProcess(Baritone baritone) {
super(baritone);
}


@Override
public boolean isActive() {
return recipe != null && amount >= 1;
Expand All @@ -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();
Expand All @@ -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() {
Expand All @@ -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());
}
}

Expand All @@ -144,25 +156,12 @@ public ArrayList<IRecipe> 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<IRecipe> recipeList = getCraftingRecipes(item);
for (IRecipe recipe : recipeList) {
if(canCraft(recipe, amount)) {
if (canCraft(recipe, amount)) {
this.recipe = recipe;
rycbar0 marked this conversation as resolved.
Show resolved Hide resolved
return true;
}
Expand All @@ -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);
}
}