diff --git a/src/main/java/dev/latvian/mods/kubejs/CommonProperties.java b/src/main/java/dev/latvian/mods/kubejs/CommonProperties.java index 957f56a78..e6e7de864 100644 --- a/src/main/java/dev/latvian/mods/kubejs/CommonProperties.java +++ b/src/main/java/dev/latvian/mods/kubejs/CommonProperties.java @@ -35,6 +35,9 @@ public static void reload() { public boolean ignoreCustomUniqueRecipeIds; public boolean startupErrorGUI; public String startupErrorReportUrl; + public boolean removeSlotLimit; + public int defaultMaxStackSize; + public boolean customStackSizeText; public JsonElement creativeModeTabIcon; public JsonElement creativeModeTabName; @@ -54,9 +57,13 @@ protected void load() { ignoreCustomUniqueRecipeIds = get("ignore_custom_unique_recipe_ids", false); startupErrorGUI = get("startup_error_gui", true); startupErrorReportUrl = get("startup_error_report_url", ""); + removeSlotLimit = get("remove_slot_limit", false); + defaultMaxStackSize = Math.max(0, Math.min(1_000_000_000, get("default_max_stack_size", 0))); + customStackSizeText = get("custom_stack_size_text", true); creativeModeTabIcon = get("creative_mode_tab_icon", new JsonObject()); creativeModeTabName = get("creative_mode_tab_name", JsonNull.INSTANCE); + } public void setPackMode(String s) { @@ -72,4 +79,12 @@ public Component getCreativeModeTabName() { return TextIcons.NAME; } + + public int getMaxSlotSize(int original) { + return removeSlotLimit ? 1_000_000_000 : original; + } + + public int getMaxStackSize(int original) { + return defaultMaxStackSize == 0 ? original : defaultMaxStackSize; + } } \ No newline at end of file diff --git a/src/main/java/dev/latvian/mods/kubejs/client/KubeJSClient.java b/src/main/java/dev/latvian/mods/kubejs/client/KubeJSClient.java index 5ebfdab96..9798b7279 100644 --- a/src/main/java/dev/latvian/mods/kubejs/client/KubeJSClient.java +++ b/src/main/java/dev/latvian/mods/kubejs/client/KubeJSClient.java @@ -15,11 +15,15 @@ import net.minecraft.SharedConstants; import net.minecraft.Util; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.commands.CommandSourceStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.PreparableReloadListener; +import net.minecraft.util.Mth; import net.minecraft.util.profiling.InactiveProfiler; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.CreativeModeTabs; @@ -180,4 +184,39 @@ public static void loadPostChains(Minecraft mc) { public static void resizePostChains(int width, int height) { KubedexHighlight.INSTANCE.resizePostChains(width, height); } + + private static final char[] POWER = {'K', 'M', 'B', 'T'}; + + public static String formatNumber(int count) { + if (Screen.hasAltDown()) { + return String.format("%,d", count); + } + + int index = 0; + + if (count > 9999) { + while (count / 1000 != 0) { + count /= 1000; + index++; + } + } + + if (index > 0) { + return count + String.valueOf(POWER[index - 1]); + } else { + return String.valueOf(count); + } + } + + public static int drawStackSize(GuiGraphics graphics, Font font, int size, int x, int y, int color, boolean dropShadow) { + var str = formatNumber(size); + float scale = str.length() >= 4 ? 0.5F : str.length() == 3 ? 0.75F : 1F; + graphics.pose().pushPose(); + graphics.pose().translate(x + 16F, y + 16F, 0F); + graphics.pose().scale(scale, scale, 1F); + int w = font.width(str); + int s = graphics.drawString(font, str, -w, -8F, color, dropShadow); + graphics.pose().popPose(); + return Mth.ceil(s * scale); + } } \ No newline at end of file diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/ContainerMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/ContainerMixin.java index cbecccd3a..1dfb95c34 100644 --- a/src/main/java/dev/latvian/mods/kubejs/core/mixin/ContainerMixin.java +++ b/src/main/java/dev/latvian/mods/kubejs/core/mixin/ContainerMixin.java @@ -1,9 +1,16 @@ package dev.latvian.mods.kubejs.core.mixin; +import dev.latvian.mods.kubejs.CommonProperties; import dev.latvian.mods.kubejs.core.ContainerKJS; import net.minecraft.world.Container; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; @Mixin(Container.class) public interface ContainerMixin extends ContainerKJS { + @ModifyConstant(method = "getMaxStackSize()I", constant = @Constant(intValue = 99)) + private int kjs$maxSlotSize(int original) { + return CommonProperties.get().getMaxSlotSize(original); + } } diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/DataComponentsMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/DataComponentsMixin.java new file mode 100644 index 000000000..b28937527 --- /dev/null +++ b/src/main/java/dev/latvian/mods/kubejs/core/mixin/DataComponentsMixin.java @@ -0,0 +1,20 @@ +package dev.latvian.mods.kubejs.core.mixin; + +import dev.latvian.mods.kubejs.CommonProperties; +import net.minecraft.core.component.DataComponents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(DataComponents.class) +public class DataComponentsMixin { + @ModifyConstant(method = "lambda$static$1", constant = @Constant(intValue = 99)) + private static int kjs$maxSlotSize(int original) { + return CommonProperties.get().getMaxSlotSize(original); + } + + @ModifyConstant(method = "", constant = @Constant(intValue = 64)) + private static int kjs$maxStackSize(int original) { + return CommonProperties.get().getMaxStackSize(original); + } +} diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/GuiGraphicsMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/GuiGraphicsMixin.java new file mode 100644 index 000000000..828d3c32c --- /dev/null +++ b/src/main/java/dev/latvian/mods/kubejs/core/mixin/GuiGraphicsMixin.java @@ -0,0 +1,42 @@ +package dev.latvian.mods.kubejs.core.mixin; + +import dev.latvian.mods.kubejs.CommonProperties; +import dev.latvian.mods.kubejs.client.KubeJSClient; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +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(GuiGraphics.class) +public abstract class GuiGraphicsMixin { + @Unique + private final int[] kjs$itemSize = new int[3]; + + @Inject(method = "renderItemDecorations(Lnet/minecraft/client/gui/Font;Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawString(Lnet/minecraft/client/gui/Font;Ljava/lang/String;IIIZ)I", shift = At.Shift.BEFORE)) + private void kjs$beforeDrawSize(Font font, ItemStack stack, int x, int y, String text, CallbackInfo ci) { + if (text == null && CommonProperties.get().removeSlotLimit && CommonProperties.get().customStackSizeText && stack.getCount() > 1) { + kjs$itemSize[0] = stack.getCount(); + kjs$itemSize[1] = x; + kjs$itemSize[2] = y; + } else { + kjs$itemSize[0] = 0; + } + } + + @Inject(method = "renderItemDecorations(Lnet/minecraft/client/gui/Font;Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawString(Lnet/minecraft/client/gui/Font;Ljava/lang/String;IIIZ)I", shift = At.Shift.AFTER)) + private void kjs$afterDrawSize(Font font, ItemStack stack, int x, int y, String text, CallbackInfo ci) { + kjs$itemSize[0] = 0; + } + + @Inject(method = "drawString(Lnet/minecraft/client/gui/Font;Ljava/lang/String;IIIZ)I", at = @At("HEAD"), cancellable = true) + private void kjs$drawString(Font font, String text, int x, int y, int color, boolean dropShadow, CallbackInfoReturnable cir) { + if (kjs$itemSize[0] != 0) { + cir.setReturnValue(KubeJSClient.drawStackSize((GuiGraphics) (Object) this, font, kjs$itemSize[0], kjs$itemSize[1], kjs$itemSize[2], color, dropShadow)); + } + } +} diff --git a/src/main/java/dev/latvian/mods/kubejs/core/mixin/ItemStackMixin.java b/src/main/java/dev/latvian/mods/kubejs/core/mixin/ItemStackMixin.java index d2eb36e3f..501116a28 100644 --- a/src/main/java/dev/latvian/mods/kubejs/core/mixin/ItemStackMixin.java +++ b/src/main/java/dev/latvian/mods/kubejs/core/mixin/ItemStackMixin.java @@ -1,5 +1,6 @@ package dev.latvian.mods.kubejs.core.mixin; +import dev.latvian.mods.kubejs.CommonProperties; import dev.latvian.mods.kubejs.core.ItemStackKJS; import dev.latvian.mods.rhino.util.HideFromJS; import dev.latvian.mods.rhino.util.RemapPrefixForJS; @@ -11,6 +12,8 @@ import net.minecraft.world.item.enchantment.ItemEnchantments; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; import java.util.stream.Stream; @@ -28,4 +31,9 @@ public abstract class ItemStackMixin implements ItemStackKJS { @Shadow @HideFromJS public abstract Stream> getTags(); + + @ModifyConstant(method = "lambda$static$3", constant = @Constant(intValue = 99)) + private static int kjs$maxSlotSize(int original) { + return CommonProperties.get().getMaxSlotSize(original); + } } diff --git a/src/main/resources/kubejs.mixins.json b/src/main/resources/kubejs.mixins.json index fe3608c76..fb467228c 100644 --- a/src/main/resources/kubejs.mixins.json +++ b/src/main/resources/kubejs.mixins.json @@ -16,6 +16,7 @@ "ContainerMixin", "CreativeModeTabMixin", "DamageSourceMixin", + "DataComponentsMixin", "DifferenceIngredientMixin", "DirectionMixin", "DyeColorMixin", @@ -71,6 +72,7 @@ "ClientPacketListenerMixin", "CreativeModeInventoryScreenMixin", "GameRendererMixin", + "GuiGraphicsMixin", "ItemStackClientMixin", "KeyboardHandlerMixin", "LevelRendererMixin",