Skip to content

Commit

Permalink
feat: Sort inventory (#4)
Browse files Browse the repository at this point in the history
* feat: Sort inventory

* feat: Sort inventory

* refactor: make ItemType a record class

* feat: MASS_CRAFT_RECIPE_BOOK, craft by clicking on vanilla recipe book

* fix

* fix

* fix: MASS_CRAFT_RECIPE_BOOK

* fix: translations

* fix

* fix

* fix

* fix: drop CraftFailedResponseS2CPacket

* fix: Sort inventory

* nothing, have no idea about incorrect crafting results

* fix: creative mode dead loop

* revert: revert changes to `MASS_CRAFT_RECIPE_BOOK`; code cleanup

* style

* style

* chore

* chore
  • Loading branch information
zly2006 authored Jul 20, 2024
1 parent e0ce351 commit 37f9e2c
Show file tree
Hide file tree
Showing 13 changed files with 448 additions and 17 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ author = masa
mod_file_name = itemscroller-fabric

# Current mod version
mod_version = 0.23.999-sakura.4
mod_version = 0.23.999-sakura.5

# Required malilib version
malilib_version = 0.19.999-sakura.8
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/fi/dy/masa/itemscroller/config/Configs.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public static class Generic
public static final ConfigBoolean SLOT_POSITION_AWARE_SCROLL_DIRECTION = new ConfigBoolean("useSlotPositionAwareScrollDirection", false, "itemscroller.config.generic.comment.useSlotPositionAwareScrollDirection").translatedName("itemscroller.config.generic.name.useSlotPositionAwareScrollDirection");
public static final ConfigBoolean VILLAGER_TRADE_USE_GLOBAL_FAVORITES = new ConfigBoolean("villagerTradeUseGlobalFavorites", true, "itemscroller.config.generic.comment.villagerTradeUseGlobalFavorites").translatedName("itemscroller.config.generic.name.villagerTradeUseGlobalFavorites");
public static final ConfigBoolean VILLAGER_TRADE_LIST_REMEMBER_SCROLL = new ConfigBoolean("villagerTradeListRememberScrollPosition", true, "itemscroller.config.generic.comment.villagerTradeListRememberScrollPosition").translatedName("itemscroller.config.generic.name.villagerTradeListRememberScrollPosition");
public static final ConfigBoolean SORT_ASSUME_EMPTY_BOX_STACKS = new ConfigBoolean("sortAssumeEmptyBoxStacks", true, "itemscroller.config.generic.comment.sortAssumeEmptyBoxStacks").translatedName("itemscroller.config.generic.name.sortAssumeEmptyBoxStacks");
public static final ConfigBoolean SORT_SHULKER_BOXES_AT_END = new ConfigBoolean("sortShulkerBoxesAtEnd", true, "itemscroller.config.generic.comment.sortShulkerBoxesAtEnd").translatedName("itemscroller.config.generic.name.sortShulkerBoxesAtEnd");

public static final ImmutableList<IConfigValue> OPTIONS = ImmutableList.of(
CARPET_CTRL_Q_CRAFTING,
Expand All @@ -65,7 +67,10 @@ public static class Generic
SLOT_POSITION_AWARE_SCROLL_DIRECTION,
USE_RECIPE_CACHING,
VILLAGER_TRADE_USE_GLOBAL_FAVORITES,
VILLAGER_TRADE_LIST_REMEMBER_SCROLL
VILLAGER_TRADE_LIST_REMEMBER_SCROLL,

SORT_ASSUME_EMPTY_BOX_STACKS,
SORT_SHULKER_BOXES_AT_END
);
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/java/fi/dy/masa/itemscroller/config/Hotkeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class Hotkeys
public static final ConfigHotkey MODIFIER_MOVE_STACK = new ConfigHotkey("modifierMoveStack", "LEFT_SHIFT", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.modifierMoveStack").translatedName("itemscroller.config.hotkeys.name.modifierMoveStack");
public static final ConfigHotkey MODIFIER_TOGGLE_VILLAGER_GLOBAL_FAVORITE = new ConfigHotkey("modifierToggleVillagerGlobalFavorite", "LEFT_SHIFT", GUI_RELAXED, "itemscroller.config.hotkeys.comment.modifierToggleVillagerGlobalFavorite").translatedName("itemscroller.config.hotkeys.name.modifierToggleVillagerGlobalFavorite");

public static final ConfigHotkey SORT_INVENTORY = new ConfigHotkey("sortInventory", "R", GUI_NO_ORDER, "itemscroller.config.hotkeys.comment.sortInventory").translatedName("itemscroller.config.hotkeys.name.sortInventory");

public static final List<ConfigHotkey> HOTKEY_LIST = ImmutableList.of(
OPEN_CONFIG_GUI,
TOGGLE_MOD_ON_OFF,
Expand Down Expand Up @@ -87,6 +89,8 @@ public class Hotkeys
KEY_WS_MOVE_UP_LEAVE_ONE,
KEY_WS_MOVE_UP_MATCHING,
KEY_WS_MOVE_UP_SINGLE,
KEY_WS_MOVE_UP_STACKS
KEY_WS_MOVE_UP_STACKS,

SORT_INVENTORY
);
}
11 changes: 11 additions & 0 deletions src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package fi.dy.masa.itemscroller.event;

import fi.dy.masa.itemscroller.mixin.IMixinCraftingResultSlot;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.inventory.RecipeInputInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.recipe.Recipe;
import net.minecraft.screen.CraftingScreenHandler;
import net.minecraft.screen.slot.Slot;
import fi.dy.masa.malilib.config.options.ConfigHotkey;
import fi.dy.masa.malilib.gui.GuiBase;
Expand Down Expand Up @@ -164,6 +170,11 @@ else if (key == Hotkeys.SLOT_DEBUG.getKeybind())

return true;
}
else if (key == Hotkeys.SORT_INVENTORY.getKeybind())
{
InventoryUtils.sortInventory(gui);
return true;
}

return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package fi.dy.masa.itemscroller.mixin;

import fi.dy.masa.itemscroller.util.InventoryUtils;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.StatisticsS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPlayNetworkHandler.class)
public class MixinClientPlayNetworkHandler
{
@Inject(method = "onStatistics", at = @At("RETURN"), cancellable = true)
private void onPong(StatisticsS2CPacket packet, CallbackInfo ci)
{
if (InventoryUtils.onPong(packet))
{
ci.cancel();
}
}
}
33 changes: 33 additions & 0 deletions src/main/java/fi/dy/masa/itemscroller/mixin/MixinItemStak.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package fi.dy.masa.itemscroller.mixin;

import fi.dy.masa.itemscroller.config.Configs;
import fi.dy.masa.itemscroller.util.InventoryUtils;
import net.minecraft.client.MinecraftClient;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(ItemStack.class)
public class MixinItemStak
{
@Inject(method = "capCount", at = @At("HEAD"), cancellable = true)
private void dontCap(int maxCount, CallbackInfo ci) {
// Client-side fx for empty shulker box stacking
if (MinecraftClient.getInstance().isOnThread() && Configs.Generic.SORT_ASSUME_EMPTY_BOX_STACKS.getBooleanValue())
{
ci.cancel();
}
}

@Inject(method = "getMaxCount", at = @At("HEAD"), cancellable = true)
private void getMaxCount(CallbackInfoReturnable<Integer> cir) {
// Client-side fx for empty shulker box stacking
if (MinecraftClient.getInstance().isOnThread() && Configs.Generic.SORT_ASSUME_EMPTY_BOX_STACKS.getBooleanValue() && InventoryUtils.assumeEmptyShulkerStacking)
{
cir.setReturnValue(InventoryUtils.stackMaxSize((ItemStack) (Object) this, true));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package fi.dy.masa.itemscroller.mixin;

import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
import org.spongepowered.asm.mixin.Mixin;

@Mixin(RecipeBookWidget.class)
public class MixinRecipeBookWidget
{
}
45 changes: 45 additions & 0 deletions src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package fi.dy.masa.itemscroller.recipes;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.input.CraftingRecipeInput;
import net.minecraft.recipe.input.RecipeInput;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
import fi.dy.masa.itemscroller.recipes.CraftingHandler.SlotRange;
import fi.dy.masa.itemscroller.util.Constants;
import fi.dy.masa.itemscroller.util.InventoryUtils;
import net.minecraft.world.World;

public class RecipePattern
{
private ItemStack result = InventoryUtils.EMPTY_STACK;
private ItemStack[] recipe = new ItemStack[9];
private RecipeEntry<?> vanillaRecipe;

public RecipePattern()
{
Expand All @@ -35,6 +46,7 @@ public void clearRecipe()
{
Arrays.fill(this.recipe, InventoryUtils.EMPTY_STACK);
this.result = InventoryUtils.EMPTY_STACK;
this.vanillaRecipe = null;
}

public void ensureRecipeSizeAndClearRecipe(int size)
Expand All @@ -43,6 +55,19 @@ public void ensureRecipeSizeAndClearRecipe(int size)
this.clearRecipe();
}

private void lookupVanillaRecipe(World world) {
this.vanillaRecipe = null;
var mc = MinecraftClient.getInstance();
for (RecipeEntry<CraftingRecipe> match : mc.world.getRecipeManager().getAllMatches(RecipeType.CRAFTING, CraftingRecipeInput.create(3, 3, Arrays.asList(recipe)), world))
{
if (InventoryUtils.areStacksEqual(result, match.value().getResult(world.getRegistryManager())))
{
this.vanillaRecipe = match;
return;
}
}
}

public void storeCraftingRecipe(Slot slot, HandledScreen<? extends ScreenHandler> gui, boolean clearIfEmpty)
{
SlotRange range = CraftingHandler.getCraftingGridSlots(gui, slot);
Expand All @@ -63,6 +88,7 @@ public void storeCraftingRecipe(Slot slot, HandledScreen<? extends ScreenHandler
}

this.result = slot.getStack().copy();
this.lookupVanillaRecipe(MinecraftClient.getInstance().world);
}
else if (clearIfEmpty)
{
Expand All @@ -84,6 +110,7 @@ public void copyRecipeFrom(RecipePattern other)
}

this.result = InventoryUtils.isStackEmpty(other.getResult()) == false ? other.getResult().copy() : InventoryUtils.EMPTY_STACK;
this.vanillaRecipe = other.vanillaRecipe;
}

public void readFromNBT(@Nonnull NbtCompound nbt, @Nonnull DynamicRegistryManager registryManager)
Expand Down Expand Up @@ -111,6 +138,7 @@ public void readFromNBT(@Nonnull NbtCompound nbt, @Nonnull DynamicRegistryManage
}

this.result = ItemStack.fromNbtOrEmpty(registryManager, nbt.getCompound("Result"));
this.lookupVanillaRecipe(MinecraftClient.getInstance().world);
}
}

Expand Down Expand Up @@ -172,4 +200,21 @@ public boolean isValid()
{
return InventoryUtils.isStackEmpty(this.getResult()) == false;
}

@Nullable
public RecipeEntry<?> getVanillaRecipeEntry()
{
return vanillaRecipe;
}

@SuppressWarnings("unchecked")
@Nullable
public <T extends RecipeInput> Recipe<T> getVanillaRecipe()
{
if (vanillaRecipe == null)
{
return null;
}
return (Recipe<T>) vanillaRecipe.value();
}
}
Loading

0 comments on commit 37f9e2c

Please sign in to comment.