Skip to content

Commit

Permalink
Merge pull request #2 from wendavid552/fabric_1.18.x
Browse files Browse the repository at this point in the history
添加切石机批量合成功能
  • Loading branch information
wendavid552 authored Feb 23, 2023
2 parents 5ddf34c + 3dba299 commit 9fcc168
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 35 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ jobs:

- uses: actions/[email protected]
with:
name: build-artifacts
path: build/libs/*
103 changes: 103 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Release

on:
release:
types:
- published
workflow_dispatch:
inputs:
target_release_tag:
description: The tag of the release you want to append the artifact to
type: string
required: true


jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.setmatrix.outputs.matrix }}
steps:
- uses: actions/[email protected]

- name: Display context
run: |
echo ref_name = ${{ github.ref_name }}
echo target_release_tag = ${{ github.event.inputs.target_release_tag }}
build:
uses: ./.github/workflows/build.yml
with:
release: true

release:
needs:
- build
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
path: build-artifacts

- name: Get github release information
if: ${{ github.event_name == 'workflow_dispatch' }}
id: get_release
uses: cardinalby/[email protected]
env:
GITHUB_TOKEN: ${{ github.token }}
with:
tag: ${{ github.event.inputs.target_release_tag }}

- name: Generate publish related infomation
id: release_info
run: |
if [ $GITHUB_EVENT_NAME == 'release' ]
then
echo "::set-output name=tag_name::" # leave an empty value here so softprops/action-gh-release will use the default value
elif [ $GITHUB_EVENT_NAME == 'workflow_dispatch' ]
then
echo "::set-output name=tag_name::${{ github.event.inputs.target_release_tag }}"
else
echo Unknown github event name $GITHUB_EVENT_NAME
exit 1
fi
- name: Read Properties mod_version
id: mod_version
uses: christian-draeger/[email protected]
with:
path: gradle.properties
property: mod_version

- name: Read Properties minecraft_version
id: minecraft_version
uses: christian-draeger/[email protected]
with:
path: gradle.properties
property: minecraft_version

- name: Publish Minecraft Mods
uses: Kir-Antipov/[email protected]
with:
github-tag: ${{ steps.release_info.outputs.tag_name }}
github-token: ${{ secrets.GITHUB_TOKEN }}

files-primary: ${{'build-artifacts/!(*-@(dev|sources)).jar'}}
files-secondary: ''

name: ${{ format('Itemscroller v {0} for mc{1}', steps.mod_version.outputs.value, steps.minecraft_version.outputs.value) }}
version: ${{ format('mc{0}-v{1}', steps.minecraft_version.outputs.value, steps.mod_version.outputs.value) }}
version-type: release
changelog: ${{ format('{0}{1}', github.event.release.body, steps.get_release.outputs.body) }} # one of them should be an empty string (null)

loaders: fabric
game-versions: ${{ matrix.game_versions }}
version-resolver: exact

retry-attempts: 3
retry-delay: 10000
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
## Note
This is a customized version of Masa's itemscroller mod that fixes crafting features for 1.18. Masa's original mod can be found [here](https://github.com/maruohon/itemscroller)
This is a customized version of Andrew54757's itemscroller-crafting-fix, which is a customized version of Masa's itemscroller mod that fixes crafting features for 1.18.

Customizations:
* More accurate/faster crafting through recipe book protocol
* Toggleable crafting (so you can keep crafting without holding down a key, eg for crafting millions of pistons)
* Honey crafting
Masa's original mod can be found [here](https://github.com/maruohon/itemscroller)

- Removed carpetControlQ crafting option as it causes a "slow crafting issue"
- Removed packetRateLimit as it may lead to problems.
Andrew54757's mod can be found [here](https://github.com/Andrews54757/itemscroller-crafting-fix)

## This is not Masa's original itemscroller. If you have issues with this mod, please contact Andrews54757 (or open a bug report here).
Customizations:
Beside the customizations offered by crafting-fix, we also provide some features that are not present in the original mod:
* Apply crafting features over anvil, grindstone(could help with building overstacked items), stonecutter.
* Renaming multiple items automatically over anvil
* `reserveCrafting` to make it possible to pick up every kind of recipe items after each crafting

### What's different?
Post 1.13, Mojang has changed the crafting mechanics of the game. Before 1.13, crafting was very fast as much of the logic was handled client-side. In 1.13, most of the crafting logic was moved to the server. This broke Itemscroller's fast crafting features, since every ingredient now had to be moved one slot at a time to the crafting grid for it to work. This drastically worsened server-client desync, a compounding problem, leading to an increasing number of failed crafting attempts and accidental ingredient leaks which made afk crafting impossible.
- Fix rendering bug when recipes do not have the length of a square number

This customized version of the mod, fixes the problem by handling ingredient movement server-side using the recipe book protocols when it can.
除crafting-fix提供的功能外,还提供以下功能:
* 可以在铁砧/砂轮(可用于合成堆叠附魔书等)/切石机上使用快速合成功能
* 可以在铁砧上批量重命名物品,只需快速合成前在铁砧上预先写好名字并调用对应的快速合成功能即可,注意仅能用于`合成而不扔出`
* `reserveCrafting` 选项可以在合成后保留物品栏中合成材料的槽位,无论地上合成材料扔出的顺序,总有物品栏位置能从地上捡起合成材料

**Note: Some recipes like fireworks rockets that are not in the recipe book do not take advantage of this protocol, in those cases old itemscroller methods will be used**
## This is not Masa's original itemscroller. If you have issues with this mod, please contact WenDavid552 (or open a bug report here).

Item Scroller
==============
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ author = masa
mod_file_name = itemscroller-fabric

# Current mod version
mod_version = craftfix-1.2.6
mod_version = craftaddon-1.0.0

# Required malilib version
malilib_version = 0.12.0
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/fi/dy/masa/itemscroller/config/Configs.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.gui.screen.ingame.CraftingScreen;
import net.minecraft.client.gui.screen.ingame.GrindstoneScreen;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.screen.ingame.*;
import net.minecraft.screen.ForgingScreenHandler;
import net.minecraft.screen.GrindstoneScreenHandler;
import net.minecraft.screen.StonecutterScreenHandler;
import net.minecraft.screen.slot.CraftingResultSlot;
import fi.dy.masa.itemscroller.Reference;
import fi.dy.masa.itemscroller.recipes.CraftingHandler;
Expand Down Expand Up @@ -67,6 +65,7 @@ public static class Generic
public static class Toggles
{
public static final ConfigBoolean CRAFTING_FEATURES = new ConfigBoolean("enableCraftingFeatures", true, "Enables scrolling items to and from crafting grids,\nwith a built-in 18 recipe memory.\nHold down the Recipe key to see the stored recipes and\nto change the selection. While holding the Recipe key,\nyou can either scroll or press a number key to change the selection.\nA recipe is stored to the currently selected \"recipe slot\"\n by clicking pick block over a configured crafting output slot.\nThe supported crafting grids must be added to the scrollableCraftingGrids list.");
public static final ConfigBoolean RESERVED_CRAFTING = new ConfigBoolean("enableReservedCrafting", false, "Enables to reserve slots of items of recipes in inventory,\nso items on the ground could be picked up for further crafting");
public static final ConfigBoolean DROP_MATCHING = new ConfigBoolean("enableDropkeyDropMatching", true, "Enables dropping all matching items from the same\ninventory with the hotkey");
public static final ConfigBoolean RIGHT_CLICK_CRAFT_STACK = new ConfigBoolean("enableRightClickCraftingOneStack", true, "Enables crafting up to one full stack when right clicking on\na slot that has been configured as a crafting output slot.");
public static final ConfigBoolean SCROLL_EVERYTHING = new ConfigBoolean("enableScrollingEverything", true, "Enables scroll moving all items at once while\nholding the modifierMoveEverything keybind");
Expand All @@ -81,6 +80,7 @@ public static class Toggles

public static final ImmutableList<IConfigValue> OPTIONS = ImmutableList.of(
CRAFTING_FEATURES,
RESERVED_CRAFTING,
DROP_MATCHING,
RIGHT_CLICK_CRAFT_STACK,
SCROLL_EVERYTHING,
Expand Down Expand Up @@ -127,8 +127,10 @@ public static void loadFromFile()
CraftingHandler.addCraftingGridDefinition(InventoryScreen.class.getName(), CraftingResultSlot.class.getName(), 0, new SlotRange(1, 4));
// vanilla anvil
CraftingHandler.addCraftingGridDefinition(AnvilScreen.class.getName(), ForgingScreenHandler.class.getName()+"$2", 2, new SlotRange(0, 2));
// vanill grindstone
// vanilla grindstone
CraftingHandler.addCraftingGridDefinition(GrindstoneScreen.class.getName(), GrindstoneScreenHandler.class.getName()+"$4", 2, new SlotRange(0, 2));
// vanilla stonecutter
CraftingHandler.addCraftingGridDefinition(StonecutterScreen.class.getName(), StonecutterScreenHandler.class.getName()+"$2", 1, new SlotRange(0, 1));
}

public static void saveToFile()
Expand Down
36 changes: 26 additions & 10 deletions src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.ingame.StonecutterScreen;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.StonecuttingRecipe;
import net.minecraft.screen.StonecutterScreenHandler;
import net.minecraft.screen.slot.Slot;
import fi.dy.masa.itemscroller.ItemScroller;
import fi.dy.masa.itemscroller.config.Configs;
Expand Down Expand Up @@ -187,21 +190,34 @@ public void onClientTick(MinecraftClient mc)
RecipePattern recipe = RecipeStorage.getInstance().getSelectedRecipe();

CraftingRecipe bookRecipe = InventoryUtils.getBookRecipeFromPattern(recipe);
if (bookRecipe != null && !bookRecipe.isIgnoredInRecipeBook()) { // Use recipe book if possible
if (!(gui instanceof StonecutterScreen) && bookRecipe != null && !bookRecipe.isIgnoredInRecipeBook()) { // Use recipe book if possible
// System.out.println("recipe");
int option = InventoryUtils.checkRecipeEnough(recipe, gui);
if(option > 0) {
mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, bookRecipe, option > 1);
if(Configs.Toggles.RESERVED_CRAFTING.getBooleanValue()) {
int option = InventoryUtils.checkRecipeEnough(recipe, gui);
if (option > 0) {
mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, bookRecipe, option > 1);
}
}
} else {
// System.out.println("move");
else{
mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, bookRecipe, true);
}
}
else {
InventoryUtils.tryMoveItemsToFirstCraftingGrid(recipe, gui, true);
int stonecuttingRecipeIndex = InventoryUtils.getStonecuttingRecipeFromPattern(recipe);
if(stonecuttingRecipeIndex != -1 && gui instanceof StonecutterScreen) {
mc.interactionManager.clickButton((gui.getScreenHandler()).syncId, stonecuttingRecipeIndex);
}
}

// for (int i = 0; i < recipe.getMaxCraftAmount(); i++) {
// InventoryUtils.dropStack(gui, outputSlot.id);
// }
InventoryUtils.dropItem(gui, outputSlot.id);
if(recipe.getResult().isStackable()) {
for (int i = 0; i < recipe.getMaxCraftAmount(); i++) {
InventoryUtils.dropStack(gui, outputSlot.id);
}
}
else {
InventoryUtils.dropItem(gui, outputSlot.id);
}

InventoryUtils.tryClearCursor(gui);
InventoryUtils.throwAllCraftingResultsToGround(recipe, gui);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.StonecuttingRecipe;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
import fi.dy.masa.itemscroller.recipes.CraftingHandler.SlotRange;
Expand All @@ -20,6 +21,8 @@ public class RecipePattern
private ItemStack result = InventoryUtils.EMPTY_STACK;
private ItemStack[] recipe = new ItemStack[9];
public CraftingRecipe cachedRecipeFromBook = null;

public int cachedRecipeFromStonecutting = -1;
private int maxCraftAmount = 64;
private HashSet<Item> recipeRemainders = new HashSet<Item>();

Expand Down
43 changes: 36 additions & 7 deletions src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,26 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.recipe.RecipeType;
import net.minecraft.screen.AnvilScreenHandler;
import net.minecraft.recipe.StonecuttingRecipe;
import net.minecraft.screen.Generic3x3ContainerScreenHandler;
import net.minecraft.screen.MerchantScreenHandler;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.CraftingResultSlot;
import net.minecraft.screen.StonecutterScreenHandler;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.screen.slot.TradeOutputSlot;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.village.TradeOffer;
import net.minecraft.village.TradeOfferList;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import fi.dy.masa.itemscroller.mixin.IMixinCraftingResultSlot;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntComparator;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -1342,6 +1339,32 @@ public static CraftingRecipe getBookRecipeFromPattern(RecipePattern recipe) {
return null;
}

public static int getStonecuttingRecipeFromPattern(RecipePattern recipe) {
if(recipe.cachedRecipeFromStonecutting != -1) {
return recipe.cachedRecipeFromStonecutting;
}
else {
MinecraftClient mc = MinecraftClient.getInstance();
RecipeManager recipeManager = mc.world.getRecipeManager();

ItemStack[] items = recipe.getRecipeItems();
SimpleInventory search = new SimpleInventory(items.length);
// Set dummy slots with recipe pattern
for (int i = 0; i < items.length; i++) {
search.setStack(i, items[i]);
}
List<StonecuttingRecipe> inputRecipes = recipeManager.getAllMatches(RecipeType.STONECUTTING, search, mc.world);
for(int i=0; i<inputRecipes.size(); ++i) {
StonecuttingRecipe inputRecipe = inputRecipes.get(i);
if(inputRecipe.getOutput().getItem() == recipe.getResult().getItem()) {
recipe.cachedRecipeFromStonecutting = i;
return recipe.cachedRecipeFromStonecutting;
}
}
}
return -1;
}

public static void craftEverythingPossibleWithCurrentRecipe(RecipePattern recipe,
HandledScreen<? extends ScreenHandler> gui) {
Slot slot = CraftingHandler.getFirstCraftingOutputSlotForGui(gui);
Expand All @@ -1354,7 +1377,7 @@ public static void craftEverythingPossibleWithCurrentRecipe(RecipePattern recipe
String cacheName = null;
for (int i = 0; i < 36; i++) {
CraftingRecipe bookRecipe = getBookRecipeFromPattern(recipe);
if (bookRecipe != null && !bookRecipe.isIgnoredInRecipeBook()) { // Use recipe book if possible
if (!(gui instanceof StonecutterScreen) && bookRecipe != null && !bookRecipe.isIgnoredInRecipeBook()) { // Use recipe book if possible
MinecraftClient mc = MinecraftClient.getInstance();
mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, bookRecipe, true);
} else {
Expand All @@ -1367,6 +1390,12 @@ public static void craftEverythingPossibleWithCurrentRecipe(RecipePattern recipe
}

tryMoveItemsToCraftingGridSlots(recipe, slot, gui, true);

int stonecuttingRecipeIndex = InventoryUtils.getStonecuttingRecipeFromPattern(recipe);
if(stonecuttingRecipeIndex != -1 && gui instanceof StonecutterScreen) {
MinecraftClient mc = MinecraftClient.getInstance();
mc.interactionManager.clickButton((gui.getScreenHandler()).syncId, stonecuttingRecipeIndex);
}
}
if(!StringUtils.isBlank(cacheName) && gui instanceof AnvilScreen) {
((IMixinAnvilScreen)gui).itemscroller_setItemName(cacheName);
Expand Down

0 comments on commit 9fcc168

Please sign in to comment.