From eb053d60f5a52606d85fc21dcac13dde86e2bc29 Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Thu, 18 Jun 2026 14:48:36 +0200 Subject: [PATCH 1/9] Release 5.4.0+fn-26.2 (#20) Port to 26.2 --- .gitignore | 122 +++---- gradle.properties | 22 +- .../api/client/events/ClientEvent.java | 4 - .../api/client/gui/misc/TEntityElement.java | 34 +- .../api/client/gui/misc/TItemElement.java | 48 --- .../client/gui/misc/TItemStackElement.java | 32 +- .../api/client/gui/render/TGuiGraphics.java | 19 +- .../gui/screen/ILastScreenProvider.java | 9 +- .../api/client/gui/screen/TScreen.java | 15 +- .../api/client/gui/screen/TScreenWrapper.java | 6 +- .../gui/widget/stats/TEntityStatsWidget.java | 5 +- .../client/registry/TClientRegistries.java | 3 + .../commonmc/client/TCDCommonsClient.java | 2 +- .../client/gui/screen/TTestScreen.java | 2 +- .../client/mixin/events/MixinClientLevel.java | 19 +- .../MixinClientboundAwardStatsPacket.java | 6 +- .../client/mixin/events/MixinGui.java | 24 +- .../client/mixin/events/MixinHud.java | 29 ++ .../client/mixin/events/MixinMinecraft.java | 2 +- .../client/mixin/events/MixinNativeImage.java | 2 +- .../mixin/hooks/AccessorGuiRenderer.java | 13 - .../commonmc/mixin/events/MixinCommands.java | 4 +- .../mixin/events/MixinCreativeModeTabs.java | 4 +- .../commonmc/resource/TComponent.java | 15 +- .../commonmc/world/sandbox/SandboxLevel.java | 10 +- .../assets/tcdcommons/lang/docs/index.html | 304 ++++++++++++++++++ .../tcdcommons.client.mixin.events.json | 3 +- .../tcdcommons.client.mixin.hooks.json | 4 +- 28 files changed, 539 insertions(+), 223 deletions(-) delete mode 100644 src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemElement.java create mode 100644 src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java delete mode 100644 src/main/java/com/thecsdev/commonmc/client/mixin/hooks/AccessorGuiRenderer.java create mode 100644 src/main/resources/assets/tcdcommons/lang/docs/index.html diff --git a/.gitignore b/.gitignore index dc686f6..a9aa65c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,66 @@ -# -------------------- Eclipse IDE ------------------- +# ================================================== +# Gradle +# ================================================== +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Avoid ignore Gradle wrappper properties +!gradle-wrapper.properties + +# Cache of project +.gradletasknamecache + +# Eclipse Gradle plugin generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# ================================================== +# Java +# ================================================== +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +!**/src/main/resources/**/*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +/.gradle/ +/build/ + +# ================================================== +# FabricMC +# ================================================== +run/ + +# ================================================== +# Eclipse IDE +# ================================================== .metadata bin/ tmp/ @@ -60,59 +122,7 @@ local.properties # Typically, this file would be tracked if it contains build/dependency configurations: #.project -# ----------------------- Java ----------------------- -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -!**/src/main/resources/**/*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -/.gradle/ -/build/ - -# -------------------- Idea IDE ------------------- +# ================================================== +# IntelliJ Idea IDE +# ================================================== **/.idea/ - -# ----------------------- Gradle ----------------------- -.gradle -**/build/ -!src/**/build/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Avoid ignore Gradle wrappper properties -!gradle-wrapper.properties - -# Cache of project -.gradletasknamecache - -# Eclipse Gradle plugin generated files -# Eclipse Core -.project -# JDT-specific (Eclipse Java Development Tools) -.classpath - -# ----------------------- Fabric ----------------------- -run/ diff --git a/gradle.properties b/gradle.properties index 192a3da..54e7980 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.3.2 +mod.version = 5.4.0 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev @@ -22,14 +22,14 @@ mod.link.sources = https://thecsdev.com/fwd/tcdcommons-sources/ mod.link.issues = https://thecsdev.com/fwd/tcdcommons-issues/ # 'pack.mcmeta' properties -pack.format = 84.0 +pack.format = 88 # Minecraft properties -minecraft.version = 26.1 +minecraft.version = 26.2 # Fabric properties -fabric.loader_version = 0.18.6 -fabric.api_version = 0.145.1+26.1 +fabric.loader_version = 0.19.3 +fabric.api_version = 0.152.1+26.2 # fabric.mod.json properties fabric.json.entrypoints.main = com.thecsdev.commonmc.fabric.TCDCommonsFabric @@ -37,14 +37,14 @@ fabric.api_version = 0.145.1+26.1 fabric.json.entrypoints.server = com.thecsdev.commonmc.fabric.TCDCommonsFabric fabric.json.depends.java = >=25 - fabric.json.depends.minecraft = ~26.1 - fabric.json.depends.fabricloader = >=0.18.4 - fabric.json.depends.fabric-api = >=0.145.1 + fabric.json.depends.minecraft = ~26.2 + fabric.json.depends.fabricloader = >=0.19.3 + fabric.json.depends.fabric-api = >=0.152.1 # Neo-Forge properties neoforge.version = 26.1.0.7-beta # neoforge.mods.toml properties - net.toml.loaderVersion = [2,) - neo.toml.dependencies.neoforge = [26.1.0.7-beta,) - neo.toml.dependencies.minecraft = [26.1, 26.2) + net.toml.loaderVersion = [4,) + neo.toml.dependencies.neoforge = [26.2.0.1-beta,) + neo.toml.dependencies.minecraft = [26.2, 26.3) diff --git a/src/main/java/com/thecsdev/commonmc/api/client/events/ClientEvent.java b/src/main/java/com/thecsdev/commonmc/api/client/events/ClientEvent.java index 3bb23d0..8ffc602 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/events/ClientEvent.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/events/ClientEvent.java @@ -10,10 +10,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.core.Holder; import net.minecraft.network.protocol.game.ClientboundLoginPacket; -import net.minecraft.resources.ResourceKey; import org.jetbrains.annotations.NotNull; /** @@ -40,7 +37,6 @@ public interface ClientEvent /** * Trigger: Whenever a {@link ClientLevel} is initialized.
* Thread: Main (client) - * @see ClientLevel#ClientLevel(ClientPacketListener, ClientLevel.ClientLevelData, ResourceKey, Holder, int, int, LevelRenderer, boolean, long, int) */ Event LEVEL_INIT = Events.createLoop(); // -------------------------------------------------- diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java index a31a174..683fa8c 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java @@ -14,6 +14,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.level.Level; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -35,7 +36,7 @@ // ================================================== ================================================== // TEntityElement IMPLEMENTATION // ================================================== ================================================== - private final NotNullProperty> entityType = new NotNullProperty<>(EntityType.MARKER); + private final NotNullProperty> entityType = new NotNullProperty<>(EntityTypes.MARKER); private final BooleanProperty followsCursor = new BooleanProperty(true); private final DoubleProperty entityScale = new DoubleProperty(1d); // -------------------------------------------------- @@ -51,8 +52,8 @@ public TEntityElement() { focusableProperty().set(false, TEntityElement.class); hoverableProperty().set(false, TEntityElement.class); //automatic display data refreshing when relevant properties update - boundsProperty().addChangeListener((p, o, n) -> { if(!o.hasSameSize(n)) refresh(); }); - this.entityType.addChangeListener((p, o, n) -> refresh()); + boundsProperty().addChangeListener((_, o, n) -> { if(!o.hasSameSize(n)) refresh(); }); + this.entityType.addChangeListener((_, _, _) -> refresh()); //the initial display data refresh refresh(); } @@ -157,14 +158,16 @@ public TEntityElement() { public static final @ApiStatus.Internal class EntityProvider { // ================================================== + private static int NEXT_ID = 1048576; + // -------------------------------------------------- private static final Map, Object> CACHE = new HashMap<>(); // ================================================== private EntityProvider() {} static { //clear cache when world-related events happen - ClientEvent.PLAYER_JOIN.addListener(__ -> CACHE.clear()); - ClientEvent.PLAYER_QUIT.addListener(__ -> CACHE.clear()); - ClientEvent.LEVEL_INIT.addListener(__ -> CACHE.clear()); + ClientEvent.PLAYER_JOIN.addListener(_ -> CACHE.clear()); + ClientEvent.PLAYER_QUIT.addListener(_ -> CACHE.clear()); + ClientEvent.LEVEL_INIT.addListener(_ -> CACHE.clear()); } // ================================================== /** @@ -192,7 +195,7 @@ else if(cached instanceof RuntimeException error) //create the entity if not done so before final var client = Minecraft.getInstance(); - if(entityType == EntityType.PLAYER) try { + if(entityType == EntityTypes.PLAYER) try { final var player = Objects.requireNonNull(client.player, "Missing 'Minecraft#player' instance"); CACHE.put(entityType, player); return (E) player; @@ -206,8 +209,11 @@ else if(cached instanceof RuntimeException error) Level level = client.level; if(level == null) level = SandboxLevel.INSTANCE; - final var entity = entityType.create(level, MOB_SUMMONED); - CACHE.put(entityType, Objects.requireNonNull(entity, "'EntityType#create(...)' returned 'null' for " + entityType)); + final var entity = Objects.requireNonNull( + entityType.create(level, MOB_SUMMONED), + "'EntityType#create(...)' returned 'null' for " + entityType); + entity.setId(nextEntityId()); + CACHE.put(entityType, entity); return entity; } catch (Exception e) { final var error = new RuntimeException("Failed to create 'Entity' instance of type " + entityType, e); @@ -215,6 +221,16 @@ else if(cached instanceof RuntimeException error) throw error; } } + // -------------------------------------------------- + /** + * Generate next ID integer for a created {@link Entity} instance. + * @see Entity#setId(int) + */ + private static final int nextEntityId() { + NEXT_ID++; //increment next id + if(NEXT_ID < 1048576) NEXT_ID = 1048576; //counteract overflows (values '< 1' are prohibited) + return NEXT_ID; //return next id + } // ================================================== } // ================================================== ================================================== diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemElement.java deleted file mode 100644 index da96c41..0000000 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemElement.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.thecsdev.commonmc.api.client.gui.misc; - -import com.thecsdev.common.properties.NotNullProperty; -import com.thecsdev.common.util.annotations.Virtual; -import com.thecsdev.commonmc.api.client.gui.TElement; -import com.thecsdev.commonmc.api.client.gui.render.TGuiGraphics; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * {@link TElement} that renders a given {@link ItemStack} on the screen, - * like how the game does it in the inventory screen. - *

- * {@link Deprecated}. Please use {@link TItemStackElement} instead. - */ -@Environment(EnvType.CLIENT) -@Deprecated(since = "5.3.0", forRemoval = true) -public @Virtual class TItemElement extends TElement -{ - // ================================================== - private final NotNullProperty itemStack = new NotNullProperty<>(Items.AIR.getDefaultInstance()); - // ================================================== - public TItemElement() { this(Items.AIR.getDefaultInstance()); } - public TItemElement(@Nullable ItemStack itemStack) - { - //this element should not be focusable or hoverable - focusableProperty().set(false, TItemElement.class); - hoverableProperty().set(false, TItemElement.class); - //initialize properties - this.itemStack.set(itemStack, TItemElement.class); - } - // ================================================== - /** - * Returns the {@link NotNullProperty} holding the {@link ItemStack} - * that is to be rendered by this {@link TItemElement}. - */ - public final NotNullProperty itemStackProperty() { return this.itemStack; } - // ================================================== - public @Virtual @Override void renderCallback(@NotNull TGuiGraphics pencil) { - final var bb = getBounds(); - pencil.renderItem(this.itemStack.get(), bb.x, bb.y, bb.width, bb.height); - } - // ================================================== -} diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemStackElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemStackElement.java index 00f058a..99c7f7f 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemStackElement.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TItemStackElement.java @@ -1,10 +1,14 @@ package com.thecsdev.commonmc.api.client.gui.misc; +import com.thecsdev.common.properties.NotNullProperty; import com.thecsdev.common.util.annotations.Virtual; import com.thecsdev.commonmc.api.client.gui.TElement; +import com.thecsdev.commonmc.api.client.gui.render.TGuiGraphics; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -12,8 +16,30 @@ * like how the game does it in the inventory screen. */ @Environment(EnvType.CLIENT) -public @Virtual class TItemStackElement extends TItemElement +public @Virtual class TItemStackElement extends TElement { - public TItemStackElement() { super(); } - public TItemStackElement(@Nullable ItemStack itemStack) { super(itemStack); } + // ================================================== + private final NotNullProperty itemStack = new NotNullProperty<>(Items.AIR.getDefaultInstance()); + // ================================================== + public TItemStackElement() { this(Items.AIR.getDefaultInstance()); } + public TItemStackElement(@Nullable ItemStack itemStack) + { + //this element should not be focusable or hoverable + focusableProperty().set(false, TItemStackElement.class); + hoverableProperty().set(false, TItemStackElement.class); + //initialize properties + this.itemStack.set(itemStack, TItemStackElement.class); + } + // ================================================== + /** + * Returns the {@link NotNullProperty} holding the {@link ItemStack} + * that is to be rendered by this {@link TItemStackElement}. + */ + public final NotNullProperty itemStackProperty() { return this.itemStack; } + // ================================================== + public @Virtual @Override void renderCallback(@NotNull TGuiGraphics pencil) { + final var bb = getBounds(); + pencil.renderItem(this.itemStack.get(), bb.x, bb.y, bb.width, bb.height); + } + // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java index a84e965..7ffa8a2 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java @@ -8,7 +8,6 @@ import com.thecsdev.commonmc.api.client.gui.screen.TScreen; import com.thecsdev.commonmc.api.client.gui.screen.TScreenWrapper; import com.thecsdev.commonmc.client.mixin.hooks.AccessorGuiGraphicsExtractor; -import com.thecsdev.commonmc.client.mixin.hooks.AccessorGuiRenderer; import com.thecsdev.commonmc.resource.TSprites; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -16,7 +15,6 @@ import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.render.GuiRenderer; import net.minecraft.client.gui.screens.inventory.InventoryScreen; -import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.data.AtlasIds; import net.minecraft.resources.Identifier; @@ -32,7 +30,6 @@ import java.util.Objects; -import static com.thecsdev.commonmc.api.client.gui.util.TGuiUtils.getGuiRenderer; import static net.minecraft.client.renderer.RenderPipelines.GUI_TEXTURED; /** @@ -59,10 +56,9 @@ public static final TGuiGraphics createInstance(@NotNull GuiGraphicsExtractor dr return new TGuiGraphicsDefault(drawContext, mouseX, mouseY, deltaTicks); } // ================================================== - private final GuiGraphicsExtractor drawContext; - private final Minecraft client; - private final Matrix3x2fStack matrices; - private final MultiBufferSource.BufferSource bufferSource; + private final GuiGraphicsExtractor drawContext; + private final Minecraft client; + private final Matrix3x2fStack matrices; // -------------------------------------------------- private final int mouseX, mouseY; private final float deltaTicks; @@ -76,7 +72,6 @@ protected TGuiGraphics(GuiGraphicsExtractor drawContext, int mouseX, int mouseY, this.drawContext = drawContext; this.client = aDrawContext.getClient(); this.matrices = aDrawContext.getMatrices(); - this.bufferSource = ((AccessorGuiRenderer)(Object)getGuiRenderer(aDrawContext.getClient())).getVertexConsumers(); this.mouseX = mouseX; this.mouseY = mouseY; this.deltaTicks = deltaTicks; @@ -98,12 +93,6 @@ protected TGuiGraphics(GuiGraphicsExtractor drawContext, int mouseX, int mouseY, @ApiStatus.Experimental public final Minecraft getNativeClient() { return this.client; } - /** - * Returns the game-{@link GuiRenderer}'s {@link MultiBufferSource.BufferSource}. - */ - @ApiStatus.Experimental - public final MultiBufferSource.BufferSource getNativeBufferSource() { return this.bufferSource; } - /** * Returns the native {@link GuiRenderer}'s {@link Matrix3x2fStack}. */ @@ -725,7 +714,7 @@ public final void renderTScreen(@NotNull TScreen screen) //do not render tooltip and cursor if the screen isn't open. //this prevents annoyances from 'last/previous screens' when //a screen is rendering its 'last/previous screen'. - if(this.client.screen != screen.getAsScreen()) + if(this.client.gui.screen() != screen.getAsScreen()) return; // ---------- TOOLTIP RENDERING diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java index 5ee92df..a209911 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java @@ -3,6 +3,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.screens.Screen; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -16,7 +17,7 @@ * This is generally used to open the previous screen when closing * the current one. * - * @see Minecraft#setScreen(Screen) + * @see Gui#setScreen(Screen) * @see TScreen#close() */ @Environment(EnvType.CLIENT) @@ -59,14 +60,14 @@ public interface ILastScreenProvider * {@link ILastScreenProvider}. * * @param client The {@link Minecraft} client. - * @return Any {@link ILastScreenProvider} associated with the current {@link Minecraft#screen}, if any. + * @return Any {@link ILastScreenProvider} associated with the current {@link Gui#screen()}, if any. * @throws NullPointerException If the argument is {@code null}. */ public static @Nullable ILastScreenProvider getCurrent( @NotNull Minecraft client) throws NullPointerException { - if(client.screen instanceof ILastScreenProvider lsp) + if(client.gui.screen() instanceof ILastScreenProvider lsp) return lsp; - else if(client.screen instanceof TScreenWrapper tsw && tsw.getTargetTScreen() instanceof ILastScreenProvider lsp) + else if(client.gui.screen() instanceof TScreenWrapper tsw && tsw.getTargetTScreen() instanceof ILastScreenProvider lsp) return lsp; return null; } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java index 790d7b0..9986f80 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java @@ -11,6 +11,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.ApiStatus.Internal; @@ -124,13 +125,13 @@ public TScreen() /** * Returns {@code true} if this {@link TScreen} is currently opened by * a {@link Minecraft} client instance. - * @see Minecraft#screen + * @see Gui#screen() */ @Contract(pure = true) public final boolean isOpen() { final var screen = getAsScreen(); final @Nullable var client = screen.getClient(); - return client.screen == screen; + return client.gui.screen() == screen; } /** @@ -162,7 +163,7 @@ public final boolean isOpen() { // -------------------------------------------------- /** * Callback method that is invoked whenever this {@link TScreen} is opened - * via {@link Minecraft#setScreen(Screen)}.
+ * via {@link Gui#setScreen(Screen)}.
* This takes place before {@link #initCallback()} is invoked. * @see Screen#added() */ @@ -170,7 +171,7 @@ public final boolean isOpen() { /** * Callback method that is invoked whenever this {@link TScreen} is closed - * via {@link Minecraft#setScreen(Screen)}.
+ * via {@link Gui#setScreen(Screen)}.
* This takes place after {@link #close()} is invoked. * @see Screen#removed() */ @@ -178,14 +179,14 @@ public final boolean isOpen() { // -------------------------------------------------- /** * Callback method that is invoked whenever this {@link TScreen} is closing. - * By default, this sets {@link Minecraft#screen} to {@code null}, but you + * By default, this sets {@link Gui#screen()} to {@code null}, but you * may override this to set another {@link Screen} instance if necessary. - * @apiNote This method must use {@link Minecraft#setScreen(Screen)}. + * @apiNote This method must use {@link Gui#setScreen(Screen)}. */ public @Virtual void close() { //set screen to last screen if available, else to null final @Nullable var client = getClient(); - if(isOpen()) client.setScreen(getLastScreen(this)); + if(isOpen()) client.gui.setScreen(getLastScreen(this)); } // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java index dec44ee..dec8820 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java @@ -86,13 +86,13 @@ protected TScreenWrapper(@NotNull T target) { // ================================================== public final @Override void added() { this.minecraft.schedule(() -> { - if(this.minecraft.screen == this) this.target.openCallback(); + if(this.minecraft.gui.screen() == this) this.target.openCallback(); }); } // -------------------------------------------------- protected final @Override void init() { this.minecraft.schedule(() -> { - if(this.minecraft.screen != this) return; + if(this.minecraft.gui.screen() != this) return; //begin measuring initialization time final var ns = nanoTime(); //trigger (re/)initialization by updating the bounds @@ -109,7 +109,7 @@ protected TScreenWrapper(@NotNull T target) { public final @Override void removed() { this.minecraft.schedule(() -> { //do nothing in case something reopened this screen by the time this method got called - if(this.minecraft.screen == this) return; + if(this.minecraft.gui.screen() == this) return; //invoke the corresponding callback method this.target.closeCallback(); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java index 387a28a..837fd06 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java @@ -13,6 +13,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EntityTypes; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,14 +38,14 @@ public final class TEntityStatsWidget extends TStatsWidget // ================================================== private final ObjectProperty stats = new ObjectProperty<>(); // -------------------------------------------------- - private final TEntityElement el_entity = new TEntityElement(EntityType.MARKER); + private final TEntityElement el_entity = new TEntityElement(EntityTypes.MARKER); // ================================================== public TEntityStatsWidget() { this(null); } public TEntityStatsWidget(@NotNull EntityType subject, @NotNull IStatsProvider provider) { this(new EntityStats(subject, provider)); } public TEntityStatsWidget(@Nullable EntityStats stats) { //initialize properties - this.stats.addChangeListener((p, o, n) -> refresh()); + this.stats.addChangeListener((_, _, _) -> refresh()); this.stats.getHandle().set(stats); //initialize elements this.el_entity.entityScaleProperty().set(0.7d, TEntityStatsWidget.class); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java b/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java index 6129925..e519053 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java @@ -1,6 +1,7 @@ package com.thecsdev.commonmc.api.client.registry; import com.thecsdev.commonmc.TCDCommons; +import io.netty.util.internal.UnstableApi; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screens.Screen; @@ -33,6 +34,8 @@ private TClientRegistries() {} /** * {@link Screen}s that are to be rendered on the game's HUD (heads-up display). */ + @UnstableApi + @ApiStatus.Experimental public static final Registry HUD_SCREEN; // ================================================== public static final void bootstrap() { /*invokes */ } diff --git a/src/main/java/com/thecsdev/commonmc/client/TCDCommonsClient.java b/src/main/java/com/thecsdev/commonmc/client/TCDCommonsClient.java index 43be2de..1de8702 100644 --- a/src/main/java/com/thecsdev/commonmc/client/TCDCommonsClient.java +++ b/src/main/java/com/thecsdev/commonmc/client/TCDCommonsClient.java @@ -58,7 +58,7 @@ public TCDCommonsClient() try { Thread.sleep(1000); } catch (Exception _) {} //open the testing screen on the game's main thread final var client = Minecraft.getInstance(); - client.execute(() -> client.setScreen(new TTestScreen(client.screen).getAsScreen())); + client.execute(() -> client.gui.setScreen(new TTestScreen(client.gui.screen()).getAsScreen())); }, TUtils.getVirtualThreadPerTaskExecutor())); */ } diff --git a/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java b/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java index e599259..5d7b471 100644 --- a/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java +++ b/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java @@ -83,7 +83,7 @@ else if(throwable != null) LOGGER.error("File chooser completed exceptionally: ", throwable); return null; }); - getClient().setScreen(screen.getAsScreen()); + getClient().gui.setScreen(screen.getAsScreen()); }); panel.add(btn1); diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java index 714dc5c..e66ee7f 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java @@ -4,7 +4,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.extract.LevelExtractor; import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; import org.spongepowered.asm.mixin.Mixin; @@ -19,13 +19,16 @@ public abstract class MixinClientLevel @SuppressWarnings("rawtypes") @Inject(method = "", at = @At("RETURN")) private void onInit( - ClientPacketListener clientPacketListener, - ClientLevel.ClientLevelData clientLevelData, - ResourceKey resourceKey, - Holder holder, - int i, int j, - LevelRenderer levelRenderer, - boolean bl, long l, int k, + ClientPacketListener connection, + ClientLevel.ClientLevelData levelData, + ResourceKey dimension, + Holder dimensionType, + int serverChunkRadius, + int serverSimulationDistance, + LevelExtractor levelExtractor, + boolean isDebug, + long biomeZoomSeed, + int seaLevel, CallbackInfo ci) { Minecraft.getInstance().execute(() -> diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java index 85db99c..4135e23 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java @@ -15,17 +15,17 @@ public abstract class MixinClientboundAwardStatsPacket { // ================================================== @Inject(method = "handle*", at = @At("RETURN"), require = 1, remap = true) - private void onHandle(ClientGamePacketListener clientPlayPacketListener, CallbackInfo callbackInfo) + private void onHandle(ClientGamePacketListener listener, CallbackInfo callbackInfo) { //execute handlers for this packet, but on the client's thread final var client = Minecraft.getInstance(); client.execute(() -> { //invoke callback method for screens - if(client.screen instanceof IStatsListener isl) + if(client.gui.screen() instanceof IStatsListener isl) isl.statsReceivedCallback(); //or invoke callback method for t-screens - else if(client.screen instanceof TScreenWrapper tsw && + else if(client.gui.screen() instanceof TScreenWrapper tsw && tsw.getTargetTScreen() instanceof IStatsListener isl) isl.statsReceivedCallback(); }); diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java index 819fc0d..5613769 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java @@ -1,6 +1,6 @@ package com.thecsdev.commonmc.client.mixin.events; -import com.thecsdev.commonmc.api.client.gui.screen.TScreenWrapper; +import com.llamalad7.mixinextras.sugar.Local; import com.thecsdev.commonmc.api.client.registry.TClientRegistries; import com.thecsdev.commonmc.client.mixin.hooks.AccessorScreen; import net.minecraft.CrashReport; @@ -15,6 +15,7 @@ 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.LocalCapture; /** * Mixins for the game's HUD (heads-up display). @@ -25,22 +26,19 @@ public abstract class MixinGui // ================================================== private @Final @Shadow Minecraft minecraft; // ================================================== - @Inject(method = "extractRenderState", at = @At("HEAD"), cancellable = true) - private void onPreRender(GuiGraphicsExtractor pencil, DeltaTracker tickCounter, CallbackInfo ci) - { - //cancel HUD rendering if a currently opened t-screen does not allow this - if(this.minecraft.screen instanceof TScreenWrapper tsw && !tsw.isAllowingInGameHud()) - ci.cancel(); - } - // -------------------------------------------------- - @Inject(method = "extractRenderState", at = @At("RETURN")) - private void onPostRender(GuiGraphicsExtractor pencil, DeltaTracker tickCounter, CallbackInfo ci) + @Inject(method = "extractRenderState", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILHARD) + private void onPostRender( + DeltaTracker deltaTracker, + boolean shouldRenderLevel, + boolean resourcesLoaded, + CallbackInfo ci, + @Local(name = "graphics") GuiGraphicsExtractor graphics) { //render in-game-hud screens if(TClientRegistries.HUD_SCREEN.size() > 0) { //prepare variables for rendering - final var currentScreen = minecraft.screen; + final var currentScreen = minecraft.gui.screen(); final var clientWindow = minecraft.getWindow(); final var mouse = minecraft.mouseHandler; final int windowW = clientWindow.getGuiScaledWidth(); @@ -59,7 +57,7 @@ private void onPostRender(GuiGraphicsExtractor pencil, DeltaTracker tickCounter, hudScreen.init(windowW, windowH); } //render the screen onto the in-game-hud - hudScreen.extractRenderState(pencil, mouseX, mouseY, tickCounter.getGameTimeDeltaPartialTick(false)); + hudScreen.extractRenderState(graphics, mouseX, mouseY, deltaTracker.getGameTimeDeltaPartialTick(false)); //note: ticking screens is not done here, to avoid weird visual bugs } catch(Exception exc) { //hold modded screens accountable for any exceptions they throw diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java new file mode 100644 index 0000000..2399ead --- /dev/null +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java @@ -0,0 +1,29 @@ +package com.thecsdev.commonmc.client.mixin.events; + +import com.thecsdev.commonmc.api.client.gui.screen.TScreenWrapper; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.Hud; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Hud.class) +public abstract class MixinHud +{ + // ================================================== + private @Final @Shadow Minecraft minecraft; + // ================================================== + @Inject(method = "extractHotbarAndDecorations", at = @At("HEAD"), cancellable = true) + private final void onExtractHotbarAndDecorations(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker, CallbackInfo ci) + { + //cancel hotbar rendering if a currently opened t-screen does not allow this + if(this.minecraft.gui.screen() instanceof TScreenWrapper tsw && !tsw.isAllowingInGameHud()) + ci.cancel(); + } + // ================================================== +} diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java index f1ef15c..6a70df3 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java @@ -19,7 +19,7 @@ public abstract class MixinMinecraft // ================================================== public @Shadow @Nullable LocalPlayer player; // ================================================== - @Inject(method = "clearClientLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/Gui;onDisconnected()V")) + @Inject(method = "clearClientLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/Hud;onDisconnected()V")) private final void onLocalPlayerQuit(Screen screen, CallbackInfo ci) { final var lp = Objects.requireNonNull(player, "Missing 'LocalPlayer' instance"); ((Minecraft)(Object)this).execute(() -> ClientEvent.PLAYER_QUIT.invoker().invoke(lp)); diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java index d348030..8ed579b 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java @@ -10,7 +10,7 @@ /** * This {@link Mixin}'s sole purpose is to put image byte data loading up to * LWJGL's digression, rather than having the game enforce PNG. And on another note, - * the game even fails to validate PNG properly most the time anyways, so this + * the game even fails to validate PNG properly most the time anyway, so this * is kind of more of a bug fix in a way. */ @Mixin(value = NativeImage.class) diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/hooks/AccessorGuiRenderer.java b/src/main/java/com/thecsdev/commonmc/client/mixin/hooks/AccessorGuiRenderer.java deleted file mode 100644 index 9d11b97..0000000 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/hooks/AccessorGuiRenderer.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.thecsdev.commonmc.client.mixin.hooks; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.gui.render.GuiRenderer; -import net.minecraft.client.renderer.MultiBufferSource; - -@Mixin(GuiRenderer.class) -public interface AccessorGuiRenderer -{ - public @Accessor("bufferSource") MultiBufferSource.BufferSource getVertexConsumers(); -} \ No newline at end of file diff --git a/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCommands.java b/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCommands.java index 733366f..fdafb7f 100644 --- a/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCommands.java +++ b/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCommands.java @@ -19,8 +19,8 @@ public abstract class MixinCommands private @Final @Shadow CommandDispatcher dispatcher; // ================================================== @Inject(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;setConsumer(Lcom/mojang/brigadier/ResultConsumer;)V")) - private void onInit(Commands.CommandSelection sel, CommandBuildContext ctx, CallbackInfo ci) { - CommandEvent.INIT_COMMANDS.invoker().invoke(dispatcher, ctx, sel); + private void onInit(Commands.CommandSelection commandSelection, CommandBuildContext context, CallbackInfo ci) { + CommandEvent.INIT_COMMANDS.invoker().invoke(dispatcher, context, commandSelection); } // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCreativeModeTabs.java b/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCreativeModeTabs.java index 93a9d3c..ac43db3 100644 --- a/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCreativeModeTabs.java +++ b/src/main/java/com/thecsdev/commonmc/mixin/events/MixinCreativeModeTabs.java @@ -16,7 +16,7 @@ public abstract class MixinCreativeModeTabs @Inject(method = "tryRebuildTabContents", at = @At("RETURN")) private static void onRebuildTabContents( FeatureFlagSet enabledFeatures, - boolean operatorEnabled, + boolean hasPermissions, HolderLookup.Provider lookup, CallbackInfoReturnable callback) { @@ -25,6 +25,6 @@ private static void onRebuildTabContents( //rebuild the internal map and invoke the event TItemUtils.rebuildI2TMap(); - CreativeModeTabEvent.REBUILD_CONTENTS.invoker().invoke(enabledFeatures, operatorEnabled, lookup); + CreativeModeTabEvent.REBUILD_CONTENTS.invoker().invoke(enabledFeatures, hasPermissions, lookup); } } diff --git a/src/main/java/com/thecsdev/commonmc/resource/TComponent.java b/src/main/java/com/thecsdev/commonmc/resource/TComponent.java index d37acea..c0c3e09 100644 --- a/src/main/java/com/thecsdev/commonmc/resource/TComponent.java +++ b/src/main/java/com/thecsdev/commonmc/resource/TComponent.java @@ -29,25 +29,22 @@ private TComponent() {} public static final MutableComponent air() { return literal("").append(object(new AtlasSprite(AtlasIds.GUI, Identifier.fromNamespaceAndPath(MOD_ID, "air")))); } public static final MutableComponent missingNo() { return literal("").append(object(new AtlasSprite(AtlasSprite.DEFAULT_ATLAS, TextureManager.INTENTIONAL_MISSING_TEXTURE))); } // -------------------------------------------------- + public static final MutableComponent head(@NotNull UUID uuid) { return literal("").append(object(new PlayerSprite(ResolvableProfile.createUnresolved(uuid), true))); } + public static final MutableComponent head(@NotNull String username) { return literal("").append(object(new PlayerSprite(ResolvableProfile.createUnresolved(username), true))); } + // ================================================== public static final MutableComponent block(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.BLOCKS, Identifier.parse(texId)))); } public static final MutableComponent block(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.BLOCKS, texId))); } // -------------------------------------------------- public static final MutableComponent item(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.ITEMS, Identifier.parse(texId)))); } public static final MutableComponent item(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.ITEMS, texId))); } // -------------------------------------------------- + public static final MutableComponent gui(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.GUI, Identifier.parse(texId)))); } + public static final MutableComponent gui(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.GUI, texId))); } + // -------------------------------------------------- public static final MutableComponent painting(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.PAINTINGS, Identifier.parse(texId)))); } public static final MutableComponent painting(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.PAINTINGS, texId))); } // -------------------------------------------------- public static final MutableComponent particle(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.PARTICLES, Identifier.parse(texId)))); } public static final MutableComponent particle(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.PARTICLES, texId))); } - // -------------------------------------------------- - public static final MutableComponent gui(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.GUI, Identifier.parse(texId)))); } - public static final MutableComponent gui(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.GUI, texId))); } - // -------------------------------------------------- - public static final MutableComponent sign(@NotNull String texId) { return literal("").append(object(new AtlasSprite(AtlasIds.SIGNS, Identifier.parse(texId)))); } - public static final MutableComponent sign(@NotNull Identifier texId) { return literal("").append(object(new AtlasSprite(AtlasIds.SIGNS, texId))); } - // -------------------------------------------------- - public static final MutableComponent head(@NotNull UUID uuid) { return literal("").append(object(new PlayerSprite(ResolvableProfile.createUnresolved(uuid), true))); } - public static final MutableComponent head(@NotNull String username) { return literal("").append(object(new PlayerSprite(ResolvableProfile.createUnresolved(username), true))); } // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java b/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java index 7ac52d9..821e752 100644 --- a/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java +++ b/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java @@ -1,14 +1,16 @@ package com.thecsdev.commonmc.world.sandbox; import com.thecsdev.common.util.annotations.Virtual; -import net.minecraft.core.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.particles.ExplosionParticleInfo; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; -import net.minecraft.tags.BlockTags; import net.minecraft.util.random.WeightedList; import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.TickRateManager; @@ -75,7 +77,7 @@ 0, // minimum Y 32, // height 32, // logicalHeight - BlockTags.INFINIBURN_OVERWORLD, // infiniburn + HolderSet.empty(), // infiniburn 1.0F, // ambientLight new DimensionType.MonsterSettings(UniformInt.of(0, 7), 0), DimensionType.Skybox.OVERWORLD, @@ -94,7 +96,7 @@ public void onTrackingStart(Entity object) {} public void onTrackingEnd(Entity object) {} public void onSectionChange(Entity object) {} }); - protected @NotNull ClockManager clockManager = __ -> 0; + protected @NotNull ClockManager clockManager = _ -> 0; protected @NotNull List dragonParts = new ArrayList<>(); protected @NotNull TickRateManager tickRateManager = new TickRateManager(); protected @NotNull Scoreboard scoreboard = new Scoreboard(); diff --git a/src/main/resources/assets/tcdcommons/lang/docs/index.html b/src/main/resources/assets/tcdcommons/lang/docs/index.html new file mode 100644 index 0000000..61b0cf1 --- /dev/null +++ b/src/main/resources/assets/tcdcommons/lang/docs/index.html @@ -0,0 +1,304 @@ + + + + + + TCDCommons API | Language documentation + + + + + +

Mod description for 'Mod Menu'

+

Name and descriptions for this mod, that show up in Mod Menu.

+
+
+

modmenu.nameTranslation.tcdcommons

+ The display name of the mod within the 'Mod Menu' interface. +
+
+ +
+

modmenu.summaryTranslation.tcdcommons

+ The summary description of the mod within the 'Mod Menu' interface. +
+
+
+ +

Configurations/Settings related to this mod

+

Language texts used when presenting the user with a GUI interface to configure this mod.

+
+
+

tcdcommons.config.common

+ Configuration section for common client and server properties. +
+
+ +
+

tcdcommons.config.client

+ Configuration section for client-side properties. +
+
+ +
+

tcdcommons.config.client.update_item_groups_on_join

+ Name of the "Update item groups on join" configuration property. +
+
+ +
+

tcdcommons.config.client.update_item_groups_on_join.tooltip

+ Explanation for how "Update item groups on join" works. +
+
+ +
+

tcdcommons.config.server

+ Configuration section for server-side properties. +
+
+ +
+

tcdcommons.config.property_value

+ Generic word "Value" that shows up in configuration GUIs to indicate the value of a given property. +
+
+
+ +

Stat types

+

+ A "stat type" refers to a "type" of statistic the game tracks for a given player. Examples include "Times used", "Times mined", + "Times crafted", etc. Some stat types are related to items, some to entities, and some to something else. Each stat type + is related to a certain aspect of the game. +

+
+
+

tcdcommons.stat_type.minecraft.custom

+ Name of the minecraft:custom stat type.
+ This stat type refers to "General" statistics (ex. "Distance walked", "Time since last death", etc.). Internally, the + game calls it "custom" in its code, but we players call it "General" in font-end GUIs. +
+
+ +
+

tcdcommons.stat_type.minecraft.killed

+ Name of the minecraft:killed stat type.
+ This stat type is for tracking how many of a given entity a player killed. +
+
+ +
+

tcdcommons.stat_type.minecraft.killed_by

+ Name of the minecraft:killed_by stat type.
+ This stat type is for tracking how many times a player got killed by a given entity. +
+
+ +
+

tcdcommons.stat_type.morestats.damaged

+ Name of the morestats:damaged stat type.
+ This stat type is for tracking how much damage a player dealt to a given entity. +
+
+ +
+

tcdcommons.stat_type.morestats.damaged_by

+ Name of the morestats:damaged_by stat type.
+ This stat type is for tracking how much damage a given entity dealt to a player. +
+
+ +
+

tcdcommons.stat_type.morestats.totem_popped_by

+ Name of the morestats:totem_popped_by stat type.
+ This stat type is for tracking how many times a given entity caused a player to use their totem of undying. +
+
+
+ +

GUI textual dialog

+

+ This API mod offers mod developers a GUI textual dialog they could use to display messages on screen in dialog form. + This "template" dialog has some default texts associated with it. +

+
+
+

tcdcommons.gui.screen.text_dialog.default_title

+ Default title for textual dialogs. This text is used as dialog title only if a mod developer does not assign a + name themselves. +
+
+ +
+

tcdcommons.gui.screen.text_dialog.error_title

+ This text is used as title of textual dialogs that display error information on screen. For example you could + have a textual dialog appear with title "Something went wrong" and then the contents of the dialog explain + what exactly went wrong. +
+
+
+ +

GUI dropdown widget

+

+ This API mod offers a GUI dropdown widget that other mod developers could use to then display dropdowns that allow + users to select an option from a list of options. +

+
+
+

tcdcommons.gui.dropdown.default_label

+ Default placeholder text for when a dropdown widget does not have an option selected yet. + Here is what that (sort of) looks like in practice: +
+ That "Select an option..." is the placeholder text this translation key is for. +
+
+
+ +

GUI File chooser / File explorer

+

+ This API mod offers mod developers a GUI file explorer they could use to have the user select/open/create files + on their machine. Think of it like an in-game implementation of explorer.exe.
+ Why have an in-game file explorer instead of using one provided by OS? Because Java and Minecraft are very limited + and interacting with OS would require writing native code for each existing OS out there (a hell to deal with), + meaning, mod instantly becomes incompatible with every other operating system. +

+
+
+

tcdcommons.gui.filechooser.mode.explore

+ The text that appears in the title-bar (top left side of the in-game file explorer dialog), when the file explorer + is in "explore" mode.
+ In this mode, the file explorer is just that. It lets the user interact with their files without prompting them + to select or create one. +
+
+ +
+

tcdcommons.gui.filechooser.mode.choose_file

+ The text that appears in the title-bar (top left side of the in-game file explorer dialog), when the file explorer + is in "choose a file" mode.
+ In this mode, the file explorer prompts the user to choose an existing file from their device. Usually done when + opening/loading files from disk. +
+
+ +
+

tcdcommons.gui.filechooser.mode.create_file

+ The text that appears in the title-bar (top left side of the in-game file explorer dialog), when the file explorer + is in "create a file" mode.
+ In this mode, the file explorer prompts the user to choose where a new file will be created and what said file's name + will be. Usually done when saving files to disk. +
+
+ +
+

tcdcommons.gui.filechooser.quick_access

+ On the left side of the file explorer, the "Quick access" section that contains useful shortcuts to quickly navigate + to specific directories. +
+
+ +
+

tcdcommons.gui.filechooser.quick_access.mount_points

+ Below the "Quick access" section, there's another section of shortcuts, this time featuring "mount points" aka + external storage disks (like D:/, E:/, F:/, G:/, etc.). +
+
+ +
+

tcdcommons.gui.filechooser.ctxmenu.select

+ When the user right-clicks a file, a context menu appears. This is the "Select" option that may appear + in that context menu.
+ It selects a given file. +
+
+ +
+

tcdcommons.gui.filechooser.ctxmenu.open

+ When the user right-clicks a file, a context menu appears. This is the "Open" option that may appear + in that context menu.
+ It opens a given file. +
+
+ +
+

tcdcommons.gui.filechooser.ctxmenu.open_with

+ When the user right-clicks a file, a context menu appears. This is the "Open in" option that may appear + in that context menu.
+ It brings up another context menu prompting the user to select where they wish to open a given file. +
+
+ +
+

tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app

+ When the user right-clicks a file and then clicks on "Open in", this option may appear.
+ When clicked, the file is opened with the default installed program that handles files of that type. +
+
+ +
+

tcdcommons.gui.filechooser.action.file_name

+ File name field label or column header. +
+
+ +
+

tcdcommons.gui.filechooser.action.file_type

+ File type field label or column header. +
+
+
+ +

Miscellaneous

+

Miscellaneous texts, usually simple generic words and short phrases that could be used anywhere in any context.

+
+
+

tcdcommons.misc.loading

+ Generic loading indicator. +
+
+ +
+

tcdcommons.misc.something_went_wrong

+ Generic "Something went wrong" label. +
+
+ +
+

tcdcommons.misc.coming_soon

+ Generic "Coming soon" label. +
+
+ +
+

tcdcommons.misc.preview

+ Generic word "Preview". +
+
+ +
+

tcdcommons.misc.from

+ Generic word "For". +
+
+ +
+

tcdcommons.misc.to

+ Generic word "To". +
+
+
+ + diff --git a/src/main/resources/tcdcommons.client.mixin.events.json b/src/main/resources/tcdcommons.client.mixin.events.json index 24e3116..bc06cb9 100644 --- a/src/main/resources/tcdcommons.client.mixin.events.json +++ b/src/main/resources/tcdcommons.client.mixin.events.json @@ -12,6 +12,7 @@ "MixinMinecraft", "MixinClientPacketListener", "MixinClientLevel", - "MixinScreen" + "MixinScreen", + "MixinHud" ] } diff --git a/src/main/resources/tcdcommons.client.mixin.hooks.json b/src/main/resources/tcdcommons.client.mixin.hooks.json index 08150e7..99fa94e 100644 --- a/src/main/resources/tcdcommons.client.mixin.hooks.json +++ b/src/main/resources/tcdcommons.client.mixin.hooks.json @@ -4,10 +4,10 @@ "minVersion": "0.8", "compatibilityLevel": "JAVA_25", "injectors": { "defaultRequire": 1 }, - "client": [ + "client": + [ "AccessorGuiGraphicsExtractor", "AccessorGameRenderer", - "AccessorGuiRenderer", "AccessorNativeImage", "AccessorScreen", "AccessorTElement", From 7d218b5faf32becdf65a48005289c7c5658b7496 Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Mon, 6 Jul 2026 15:34:17 +0200 Subject: [PATCH 2/9] Release 5.4.1+fn-26.2 (#22) * Add Russian localization for TCDCommons (#21) --------- Co-authored-by: ADevnin <131694536+ADevnin@users.noreply.github.com> --- README.md | 2 +- gradle.properties | 2 +- .../api/client/gui/screen/TScreen.java | 8 ++-- .../api/client/gui/screen/TScreenWrapper.java | 8 +++- .../client/registry/TClientRegistries.java | 15 ++++--- .../client/mixin/events/MixinGui.java | 18 ++++---- .../assets/tcdcommons/lang/ru_ru.json | 42 +++++++++++++++++++ 7 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 src/main/resources/assets/tcdcommons/lang/ru_ru.json diff --git a/README.md b/README.md index 8db8307..bed1700 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This mod depends on some other mods that first need to be installed before this Follow these steps to build the project from source. ### Prerequisites -* **Java 21**: Ensure you have the Java Development Kit (JDK) 21 installed. +* **Java 25**: Ensure you have the Java Development Kit (JDK) installed. * **Git**: Required to clone this repository. ### Instructions diff --git a/gradle.properties b/gradle.properties index 54e7980..44d62be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.4.0 +mod.version = 5.4.1 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java index 9986f80..f09fbb8 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java @@ -50,14 +50,14 @@ public TScreen() this.dragged.addFilter(el -> (el != null && el.screenProperty().get() != this) ? null : el, TScreen.class); //invalidate tooltip caches for hovered/focused elements as they change - this.hovered.addChangeListener((p, o, n) -> { + this.hovered.addChangeListener((_, o, n) -> { if(o != null) ((AccessorTElement)(Object)o)._hoverLostCallback(); if(n != null) { n.invalidateTooltipCache(); ((AccessorTElement)(Object)n)._hoverGainedCallback(); } }); - this.focused.addChangeListener((p, o, n) -> { + this.focused.addChangeListener((_, o, n) -> { if(o != null) ((AccessorTElement)(Object)o)._focusLostCallback(); if(n != null) { n.invalidateTooltipCache(); @@ -65,7 +65,7 @@ public TScreen() TGuiUtils.scrollToElement(n); //scroll to element AFTER notifying it } }); - this.dragged.addChangeListener((p, o, n) -> { + this.dragged.addChangeListener((_, o, n) -> { if(o != null) ((AccessorTElement)(Object)o)._dragEndCallback(); if(n != null) ((AccessorTElement)(Object)n)._dragStartCallback(); }); @@ -75,7 +75,7 @@ public TScreen() bb -> (bb.x != 0 || bb.y != 0) ? new Bounds2i(0, 0, bb.width, bb.height) : bb, TScreen.class); //handle stuff on resize - boundsProperty().addChangeListener((p, o, n) -> { + boundsProperty().addChangeListener((_, _, _) -> { //clear hovered and focused elements on resize, as they are no longer valid this.hovered.set(null, TScreen.class); //clear and init is what makes it invalid this.focused.set(null, TScreen.class); //clear and init is what makes it invalid diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java index dec8820..e84bd92 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java @@ -59,6 +59,12 @@ protected TScreenWrapper(@NotNull T target) { super(Component.empty()); this.target = Objects.requireNonNull(target); } + // -------------------------------------------------- + public @Override String toString() { + final var bb = this.target.getBounds(); + return String.format("%s[x=%d,y=%d,width=%d,height=%d]", + super.toString(), bb.x, bb.y, bb.width, bb.height); + } // ================================================== /** * Returns the {@link #target} {@link TScreen} for this {@link TScreenWrapper}. @@ -92,7 +98,7 @@ protected TScreenWrapper(@NotNull T target) { // -------------------------------------------------- protected final @Override void init() { this.minecraft.schedule(() -> { - if(this.minecraft.gui.screen() != this) return; + //if(this.minecraft.gui.screen() != this) return; -- line dropped; breaks hud-screens //begin measuring initialization time final var ns = nanoTime(); //trigger (re/)initialization by updating the bounds diff --git a/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java b/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java index e519053..a789b7b 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/registry/TClientRegistries.java @@ -1,7 +1,6 @@ package com.thecsdev.commonmc.api.client.registry; import com.thecsdev.commonmc.TCDCommons; -import io.netty.util.internal.UnstableApi; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screens.Screen; @@ -10,7 +9,9 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NonNull; import static com.mojang.serialization.Lifecycle.stable; import static com.thecsdev.commonmc.TCDCommons.MOD_ID; @@ -34,8 +35,6 @@ private TClientRegistries() {} /** * {@link Screen}s that are to be rendered on the game's HUD (heads-up display). */ - @UnstableApi - @ApiStatus.Experimental public static final Registry HUD_SCREEN; // ================================================== public static final void bootstrap() { /*invokes */ } @@ -44,8 +43,14 @@ public static final void bootstrap() { /*invokes */ } HUD_SCREEN = new MappedRegistry<>(createRegistryKey(id("hud_screen")), stable()); } // -------------------------------------------------- - private static final @ApiStatus.Internal Identifier id(@NotNull String id) { - return fromNamespaceAndPath(MOD_ID, id); + /** + * Creates an {@link Identifier} instance that uses this mod's + * ID as the namespace. + * @param path The {@link Identifier#getPath()} value. + */ + @Contract("_ -> new") + private static final @ApiStatus.Internal @NonNull Identifier id(@NotNull String path) { + return fromNamespaceAndPath(MOD_ID, path); } // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java index 5613769..d333ac2 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java @@ -15,7 +15,6 @@ 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.LocalCapture; /** * Mixins for the game's HUD (heads-up display). @@ -26,7 +25,13 @@ public abstract class MixinGui // ================================================== private @Final @Shadow Minecraft minecraft; // ================================================== - @Inject(method = "extractRenderState", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILHARD) + @Inject( + method = "extractRenderState", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/Hud;extractRenderState(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", + shift = At.Shift.AFTER) + ) private void onPostRender( DeltaTracker deltaTracker, boolean shouldRenderLevel, @@ -49,13 +54,12 @@ private void onPostRender( //iterate hud screens and render them for(final var hudScreen : TClientRegistries.HUD_SCREEN) try { - //do not render the current screen - if(hudScreen == currentScreen) continue; + //do not render current screen or screens of different clients + if(hudScreen == currentScreen || ((AccessorScreen)hudScreen).getMinecraft() != this.minecraft) + continue; //(re/)initialize screens whenever necessary - if(((AccessorScreen)hudScreen).getMinecraft() != this.minecraft || - hudScreen.width != windowW || hudScreen.height != windowH) { + if(hudScreen.width != windowW || hudScreen.height != windowH) hudScreen.init(windowW, windowH); - } //render the screen onto the in-game-hud hudScreen.extractRenderState(graphics, mouseX, mouseY, deltaTracker.getGameTimeDeltaPartialTick(false)); //note: ticking screens is not done here, to avoid weird visual bugs diff --git a/src/main/resources/assets/tcdcommons/lang/ru_ru.json b/src/main/resources/assets/tcdcommons/lang/ru_ru.json new file mode 100644 index 0000000..c0c4b87 --- /dev/null +++ b/src/main/resources/assets/tcdcommons/lang/ru_ru.json @@ -0,0 +1,42 @@ +{ + "modmenu.nameTranslation.tcdcommons" : "TCDCommons API", + "modmenu.summaryTranslation.tcdcommons" : "Персональная библиотека для моддинга Minecraft от TheCSDev.", + + "tcdcommons.config.common" : "Настройки клиента и сервера", + "tcdcommons.config.client" : "Настройки клиента", + "tcdcommons.config.client.update_item_groups_on_join" : "Обновлять группы предметов при входе", + "tcdcommons.config.client.update_item_groups_on_join.tooltip" : "Функция оптимизации быстродействия. Ванильная версия игры обновляет группы предметов при открытии инвентаря, что вызывает скачки задержки в крупных сборках модов. Эта функция выполняет данную операцию во время отображения экранов загрузки, что позволяет избежать просадок производительности в игровом процессе.", + "tcdcommons.config.server" : "Настройки сервера", + "tcdcommons.config.property_value" : "Значение", + + "tcdcommons.stat_type.minecraft.custom" : "Общие", + "tcdcommons.stat_type.minecraft.killed" : "Убийств", + "tcdcommons.stat_type.minecraft.killed_by" : "Погиб от", + "tcdcommons.stat_type.morestats.damaged" : "Нанесённый урон", + "tcdcommons.stat_type.morestats.damaged_by" : "Полученный урон", + "tcdcommons.stat_type.morestats.totem_popped_by" : "Использовано тотемов бессмертия от", + + "tcdcommons.gui.screen.text_dialog.default_title" : "Диалог", + "tcdcommons.gui.screen.text_dialog.error_title" : "Произошла ошибка", + + "tcdcommons.gui.dropdown.default_label" : "Выберите вариант...", + + "tcdcommons.gui.filechooser.mode.explore" : "Проводник", + "tcdcommons.gui.filechooser.mode.choose_file" : "Выбор файла", + "tcdcommons.gui.filechooser.mode.create_file" : "Создание файла", + "tcdcommons.gui.filechooser.quick_access" : "Быстрый доступ", + "tcdcommons.gui.filechooser.quick_access.mount_points" : "Точки монтирования", + "tcdcommons.gui.filechooser.ctxmenu.select" : "Выбрать", + "tcdcommons.gui.filechooser.ctxmenu.open" : "Открыть", + "tcdcommons.gui.filechooser.ctxmenu.open_with" : "Открыть с помощью", + "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app" : "Ассоциированное приложение", + "tcdcommons.gui.filechooser.action.file_name" : "Имя файла", + "tcdcommons.gui.filechooser.action.file_type" : "Тип файла", + + "tcdcommons.misc.loading" : "Загрузка...", + "tcdcommons.misc.something_went_wrong" : "Что-то пошло не так", + "tcdcommons.misc.coming_soon" : "Ожидается в будущем", + "tcdcommons.misc.preview" : "Предпросмотр", + "tcdcommons.misc.from" : "От", + "tcdcommons.misc.to" : "До" +} From c996596c39c9ccf36c8a7bc820d342a3ee2afec1 Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Wed, 15 Jul 2026 13:41:36 +0200 Subject: [PATCH 3/9] Release 5.5.0+fn-26.2 (#23) - Add 'Item descriptions' integration - Tooltips for statistics no longer show IDs unless "advanced tooltips" is enabled - Add `isCtrlDown` in `TGuiUtils` --- .github/ISSUE_TEMPLATE/bug_report.yml | 9 +- gradle.properties | 2 +- .../api/client/gui/tooltip/TTooltip.java | 14 ++- .../gui/tooltip/TTooltipCustomStat.java | 13 ++- .../api/client/gui/tooltip/TTooltipLabel.java | 2 +- .../gui/tooltip/TTooltipSubjectStats.java | 101 ++++++++++++++++-- .../api/client/gui/util/TGuiUtils.java | 14 ++- .../gui/widget/stats/TBlockStatsWidget.java | 3 +- .../gui/widget/stats/TEntityStatsWidget.java | 3 +- .../gui/widget/stats/TItemStatsWidget.java | 3 +- .../commonmc/api/stats/util/SubjectStats.java | 10 +- 11 files changed, 145 insertions(+), 29 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5c9f819..336707d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -20,8 +20,8 @@ body: **Version format:** v[mod_version]+[mod_loader]-[minecraft_version] - **Version example:** v5.0+fabric-1.26 - **Title example:** [v5.3.1+neoforge-1.26.2] Red "Do not click" button + **Version example:** v5.0+fabric-26 + **Title example:** [v5.3.1+neoforge-26.1.2] Red "Do not click" button crashes the game when clicked - type: textarea id: description @@ -69,9 +69,8 @@ body: mod-pack. This helps project maintainers reproduce the issue, as other mods often can and do cause issues. placeholder: >- - Name a list of mods or link a mod-pack here. Please do not expect - project maintainers to manually download and install like 300 separate - mods. + Name a list of mods or link a mod-pack here. To rule out mod conflicts, it is + advised to reproduce the issue without other mods present (except for dependencies). validations: required: true - type: checkboxes diff --git a/gradle.properties b/gradle.properties index 44d62be..dd4d63a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.4.1 +mod.version = 5.5.0 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltip.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltip.java index f629444..d428a77 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltip.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltip.java @@ -51,7 +51,19 @@ public static final TTooltip of(@NotNull CustomStat stat) throws NullPointerExce * @throws NullPointerException If the argument is {@code null}. */ public static final TTooltip of(@NotNull SubjectStats stats) throws NullPointerException { - return new TTooltipSubjectStats(stats); + return of(stats, false); + } + + /** + * A tooltip that shows the player statistics for a given {@link SubjectStats}. + * @param stats The {@link SubjectStats} whose statistics are to be shown. + * @param showItemDescription Whether to include texts from Item Descriptions where possible. + * @throws NullPointerException If the argument is {@code null}. + */ + public static final TTooltip of( + @NotNull SubjectStats stats, boolean showItemDescription) + throws NullPointerException { + return new TTooltipSubjectStats(stats, showItemDescription); } // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipCustomStat.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipCustomStat.java index 20e622e..dba43d4 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipCustomStat.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipCustomStat.java @@ -3,6 +3,7 @@ import com.thecsdev.commonmc.api.stats.util.CustomStat; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.Minecraft; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -33,10 +34,16 @@ //start constructing the tooltip text final var tt = literal(""); tt.append(literal("").append(stat.getSubjectDisplayName()).withStyle(YELLOW)).append("\n"); - tt.append(literal("K: " + stat.getSubjectID()).withStyle(GRAY)).append("\n"); - tt.append(literal("V: " + stat.getSubject()).withStyle(GRAY)); - tt.append("\n\n"); + //add advanced tooltips + if(Minecraft.getInstance().options.advancedItemTooltips) { + tt.append(literal("K: " + stat.getSubjectID()).withStyle(DARK_GRAY)).append("\n"); + tt.append(literal("V: " + stat.getSubject()).withStyle(DARK_GRAY)); + tt.append("\n"); + } + + //add stat value + tt.append("\n"); tt.append(literal(stat.getValueF()).withStyle(GOLD)); if(FLAG_DEV_ENV) tt.append(literal(" (" + stat.getValue() + ")").withStyle(GRAY)); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipLabel.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipLabel.java index be08314..ec4a9c5 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipLabel.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipLabel.java @@ -30,7 +30,7 @@ TTooltipLabel(Component text) { //reinit whenever text property changes - textProperty().addChangeListener((p, o, n) -> clearAndInit()); + textProperty().addChangeListener((_, _, _) -> clearAndInit()); //initialize properties this.label.wrapTextProperty().set(true, TTooltipLabel.class); this.label.parentProperty() .set(this, TTooltipLabel.class); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipSubjectStats.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipSubjectStats.java index 09e356e..7f20f8b 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipSubjectStats.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/tooltip/TTooltipSubjectStats.java @@ -3,14 +3,24 @@ import com.thecsdev.commonmc.api.stats.util.SubjectStats; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Objects; +import java.util.Optional; import static com.thecsdev.commonmc.api.stats.IStatsProvider.getStatTypeName; +import static net.minecraft.ChatFormatting.*; import static net.minecraft.network.chat.Component.literal; +import static net.minecraft.network.chat.Component.translatable; /** * {@link TTooltip} that shows statistics related to a given {@link SubjectStats}. @@ -21,7 +31,8 @@ // ================================================== private final @NotNull SubjectStats stats; // ================================================== - public TTooltipSubjectStats(@NotNull SubjectStats stats) throws NullPointerException + public TTooltipSubjectStats(@NotNull SubjectStats stats, boolean showItemDescription) + throws NullPointerException { //initialize fields this.stats = Objects.requireNonNull(stats); @@ -30,19 +41,26 @@ public TTooltipSubjectStats(@NotNull SubjectStats stats) throws NullPointerEx { //start constructing the tooltip text final var tt = literal(""); - tt.append(literal("").append(stats.getSubjectDisplayName()).withStyle(ChatFormatting.YELLOW)).append("\n"); - tt.append(literal(stats.getSubjectID().toString()).withStyle(ChatFormatting.GRAY)); - tt.append("\n\n"); + tt.append(literal("").append(stats.getSubjectDisplayName()).withStyle(YELLOW)).append("\n"); - //add block stats + //add subject description + if(showItemDescription && computeItemDescription(stats) instanceof MutableComponent desc) + tt.append(desc.withStyle(GRAY)).append("\n"); + + //add advanced tooltips + if(Minecraft.getInstance().options.advancedItemTooltips) + tt.append(literal(stats.getSubjectID().toString()).withStyle(DARK_GRAY)).append("\n"); + + //add subject stats + tt.append("\n"); final var entries = stats.getValuesF().entrySet().iterator(); while(entries.hasNext()) { final var entry = entries.next(); final var stName = getStatTypeName(entry.getKey().getType()); - tt.append(literal("- ").withStyle(ChatFormatting.YELLOW)); + tt.append(literal("- ").withStyle(YELLOW)); tt.append(stName); - tt.append(literal(" - ").withStyle(ChatFormatting.YELLOW)); - tt.append(literal(entry.getValue()).withStyle(ChatFormatting.GOLD)); + tt.append(literal(": ").withStyle(YELLOW)); + tt.append(literal(entry.getValue()).withStyle(GOLD)); if(entries.hasNext()) tt.append("\n"); } @@ -56,4 +74,69 @@ public TTooltipSubjectStats(@NotNull SubjectStats stats) throws NullPointerEx */ public final @NotNull SubjectStats getStats() { return this.stats; } // ================================================== + /** + * Attempts to pull an "item description" for a given {@link SubjectStats#getSubject()}. + * @param stats The item to obtain the description for. + * @throws NullPointerException If the argument is {@code null}. + */ + @ApiStatus.Internal + private static final @Nullable MutableComponent computeItemDescription( + @NotNull SubjectStats stats) throws NullPointerException + { + //general preparation for all cases + final var lang = Language.getInstance(); + + //handle items + if(stats.getSubject() instanceof Item item) + return (MutableComponent) Optional.empty() + .or(() -> { + final var sid = stats.getSubjectID(); + final var key = String.format("lore.%s.%s", sid.getNamespace(), sid.getPath()); + return Optional.ofNullable(lang.has(key) ? translatable(key) : null); + }) + .or(() -> item.getDefaultInstance().tags() + .map(TagKey::location) + .map(id -> String.format("tag.%s.%s.description", id.getNamespace(), id.getPath())) + .map(key -> lang.has(key) ? translatable(key) : null) + .filter(Objects::nonNull) + .findFirst() + ) + .orElse(null); + //handle blocks + else if(stats.getSubject() instanceof Block block) + return (MutableComponent) Optional.empty() + .or(() -> { + final var sid = stats.getSubjectID(); + final var key = String.format("lore.%s.%s", sid.getNamespace(), sid.getPath()); + return Optional.ofNullable(lang.has(key) ? translatable(key) : null); + }) + .or(() -> block.defaultBlockState().tags() + .map(TagKey::location) + .map(id -> String.format("tag.%s.%s.description", id.getNamespace(), id.getPath())) + .map(key -> lang.has(key) ? translatable(key) : null) + .filter(Objects::nonNull) + .findFirst() + ) + .orElse(null); + //handle entities + else if(stats.getSubject() instanceof EntityType entityType) { + return (MutableComponent) Optional.empty() + .or(() -> { + final var sid = stats.getSubjectID(); + final var key = String.format("entity.%s.%s.description", sid.getNamespace(), sid.getPath()); + return Optional.ofNullable(lang.has(key) ? translatable(key) : null); + }) + .or(() -> entityType.builtInRegistryHolder().tags() + .map(TagKey::location) + .map(id -> String.format("tag.%s.%s.description", id.getNamespace(), id.getPath())) + .map(key -> lang.has(key) ? translatable(key) : null) + .filter(Objects::nonNull) + .findFirst() + ) + .orElse(null); + } + //all other types return nothing + else return null; + } + // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java index a98f7df..82042cb 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java @@ -25,8 +25,7 @@ import java.util.Objects; import java.util.Random; -import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_SHIFT; -import static org.lwjgl.glfw.GLFW.GLFW_KEY_RIGHT_SHIFT; +import static org.lwjgl.glfw.GLFW.*; /** * {@link TCDCommons} API's GUI-related utility methods. @@ -92,7 +91,16 @@ public static final boolean isKeyDown(int keyCode) { } /** - * Returns {@code true} is the left or right shift key is currently held down + * Returns {@code true} is either the left or right control key is currently held down + * for the current game window. + * @see #isKeyDown(int) + */ + public static final boolean isCtrlDown() { + return isKeyDown(GLFW_KEY_LEFT_CONTROL) || isKeyDown(GLFW_KEY_RIGHT_CONTROL); + } + + /** + * Returns {@code true} is either the left or right shift key is currently held down * for the current game window. * @see #isKeyDown(int) */ diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TBlockStatsWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TBlockStatsWidget.java index 5f9fa04..13a8bc5 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TBlockStatsWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TBlockStatsWidget.java @@ -5,6 +5,7 @@ import com.thecsdev.commonmc.api.client.gui.TElement; import com.thecsdev.commonmc.api.client.gui.render.TGuiGraphics; import com.thecsdev.commonmc.api.client.gui.tooltip.TTooltip; +import com.thecsdev.commonmc.api.client.gui.util.TGuiUtils; import com.thecsdev.commonmc.api.stats.IStatsProvider; import com.thecsdev.commonmc.api.stats.util.BlockStats; import net.fabricmc.api.EnvType; @@ -34,7 +35,7 @@ public final class TBlockStatsWidget extends TStatsWidget final var isw = (TBlockStatsWidget) el; final var stats = isw.stats.get(); Objects.requireNonNull(stats, "Stats value is missing while constructing tooltip."); - return TTooltip.of(stats); + return TTooltip.of(stats, TGuiUtils.isCtrlDown()); }; // ================================================== private final ObjectProperty stats = new ObjectProperty<>(); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java index 837fd06..8204a09 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java @@ -6,6 +6,7 @@ import com.thecsdev.commonmc.api.client.gui.TElement; import com.thecsdev.commonmc.api.client.gui.misc.TEntityElement; import com.thecsdev.commonmc.api.client.gui.tooltip.TTooltip; +import com.thecsdev.commonmc.api.client.gui.util.TGuiUtils; import com.thecsdev.commonmc.api.stats.IStatsProvider; import com.thecsdev.commonmc.api.stats.util.EntityStats; import net.fabricmc.api.EnvType; @@ -33,7 +34,7 @@ public final class TEntityStatsWidget extends TStatsWidget final var mstw = (TEntityStatsWidget) el; final var stats = mstw.stats.get(); Objects.requireNonNull(stats, "Stats value is missing while constructing tooltip."); - return TTooltip.of(stats); + return TTooltip.of(stats, TGuiUtils.isCtrlDown()); }; // ================================================== private final ObjectProperty stats = new ObjectProperty<>(); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TItemStatsWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TItemStatsWidget.java index 6a4c04b..d402295 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TItemStatsWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TItemStatsWidget.java @@ -5,6 +5,7 @@ import com.thecsdev.commonmc.api.client.gui.TElement; import com.thecsdev.commonmc.api.client.gui.render.TGuiGraphics; import com.thecsdev.commonmc.api.client.gui.tooltip.TTooltip; +import com.thecsdev.commonmc.api.client.gui.util.TGuiUtils; import com.thecsdev.commonmc.api.stats.EmptyStatsProvider; import com.thecsdev.commonmc.api.stats.IStatsProvider; import com.thecsdev.commonmc.api.stats.util.ItemStats; @@ -31,7 +32,7 @@ public final class TItemStatsWidget extends TStatsWidget final var isw = (TItemStatsWidget) el; final var stats = isw.stats.get(); Objects.requireNonNull(stats, "Stats value is missing while constructing tooltip."); - return TTooltip.of(stats); + return TTooltip.of(stats, TGuiUtils.isCtrlDown()); }; // ================================================== private final ObjectProperty stats = new ObjectProperty<>(); diff --git a/src/main/java/com/thecsdev/commonmc/api/stats/util/SubjectStats.java b/src/main/java/com/thecsdev/commonmc/api/stats/util/SubjectStats.java index 8d216dd..2f7ae83 100644 --- a/src/main/java/com/thecsdev/commonmc/api/stats/util/SubjectStats.java +++ b/src/main/java/com/thecsdev/commonmc/api/stats/util/SubjectStats.java @@ -27,8 +27,8 @@ public sealed abstract class SubjectStats permits CustomStat, ItemStats, Bloc { // ================================================== private final @NotNull IStatsProvider statsProvider; - private final @NotNull S subject; - private final @NotNull Identifier subjectID; + private final @NotNull S subject; + private final @NotNull Identifier subjectID; // ================================================== /** * @throws NullPointerException If an argument is {@code null}. @@ -118,7 +118,11 @@ protected SubjectStats( * Returns {@code true} if all {@link StatType}s for the given * {@link #getSubject()} have the value {@code 0}. */ - public @Virtual boolean isEmpty() { return getValues().values().stream().noneMatch(val -> val != 0); } + public @Virtual boolean isEmpty() { + for(final int value : getValues().values()) + if(value != 0) return false; + return true; + } // -------------------------------------------------- /** * Returns {@code true} if this {@link #getSubject()} matches a given search query. From 64455f57258487a0798fbcb9f6c7692f530480fa Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Thu, 16 Jul 2026 10:57:35 +0200 Subject: [PATCH 4/9] Release 5.5.1+fn-26.2 (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated 'Simplified Chinese' and added 'Traditional Chinese' translations. --------- Co-authored-by: 高新炀 --- gradle.properties | 2 +- .../assets/tcdcommons/lang/zh_cn.json | 22 +++++----- .../assets/tcdcommons/lang/zh_tw.json | 42 +++++++++++++++++++ 3 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/assets/tcdcommons/lang/zh_tw.json diff --git a/gradle.properties b/gradle.properties index dd4d63a..2c05e57 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.5.0 +mod.version = 5.5.1 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/src/main/resources/assets/tcdcommons/lang/zh_cn.json b/src/main/resources/assets/tcdcommons/lang/zh_cn.json index dfb8afa..b2496d7 100644 --- a/src/main/resources/assets/tcdcommons/lang/zh_cn.json +++ b/src/main/resources/assets/tcdcommons/lang/zh_cn.json @@ -1,20 +1,20 @@ { "modmenu.nameTranslation.tcdcommons": "TCDCommons API", - "modmenu.summaryTranslation.tcdcommons": "TheCSDev's personal Minecraft modding library.", + "modmenu.summaryTranslation.tcdcommons": "TheCSDev 的个人 Minecraft 模组开发库。", "tcdcommons.config.common": "客户端/服务端属性", "tcdcommons.config.client": "客户端属性", "tcdcommons.config.client.update_item_groups_on_join": "加入游戏时更新物品组", "tcdcommons.config.client.update_item_groups_on_join.tooltip": "性能优化功能。原版游戏在打开物品栏时更新物品组,这在大型模组包中会导致卡顿。此功能在加载界面期间执行该操作,使游戏内不再会因此发生卡顿。", "tcdcommons.config.server": "服务端属性", - "tcdcommons.config.property_value": "Value", + "tcdcommons.config.property_value": "值", - "tcdcommons.stat_type.minecraft.custom": "General", + "tcdcommons.stat_type.minecraft.custom": "通用", "tcdcommons.stat_type.minecraft.killed": "击杀", "tcdcommons.stat_type.minecraft.killed_by": "被击杀", "tcdcommons.stat_type.morestats.damaged": "造成伤害", "tcdcommons.stat_type.morestats.damaged_by": "受到伤害", - "tcdcommons.stat_type.morestats.totem_popped_by": "触发图腾", + "tcdcommons.stat_type.morestats.totem_popped_by": "触发不死图腾", "tcdcommons.gui.screen.text_dialog.default_title": "对话框", "tcdcommons.gui.screen.text_dialog.error_title": "出现错误", @@ -22,21 +22,21 @@ "tcdcommons.gui.dropdown.default_label": "选择一个选项……", "tcdcommons.gui.filechooser.mode.explore": "文件浏览器", - "tcdcommons.gui.filechooser.mode.choose_file": "先择文件", + "tcdcommons.gui.filechooser.mode.choose_file": "选择文件", "tcdcommons.gui.filechooser.mode.create_file": "创建文件", "tcdcommons.gui.filechooser.quick_access": "快速访问", "tcdcommons.gui.filechooser.quick_access.mount_points": "设备和驱动器", "tcdcommons.gui.filechooser.ctxmenu.select": "选择", "tcdcommons.gui.filechooser.ctxmenu.open": "打开", "tcdcommons.gui.filechooser.ctxmenu.open_with": "打开方式", - "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app": "关联的应用程序", + "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app": "关联应用", "tcdcommons.gui.filechooser.action.file_name": "文件名", "tcdcommons.gui.filechooser.action.file_type": "文件类型", "tcdcommons.misc.loading": "加载中……", "tcdcommons.misc.something_went_wrong": "出现错误", - "tcdcommons.misc.coming_soon": "即将到来", - "tcdcommons.misc.preview": "Preview", - "tcdcommons.misc.from": "From", - "tcdcommons.misc.to": "To" -} + "tcdcommons.misc.coming_soon": "即将推出", + "tcdcommons.misc.preview": "预览", + "tcdcommons.misc.from": "从", + "tcdcommons.misc.to": "到" +} \ No newline at end of file diff --git a/src/main/resources/assets/tcdcommons/lang/zh_tw.json b/src/main/resources/assets/tcdcommons/lang/zh_tw.json new file mode 100644 index 0000000..bdff6ae --- /dev/null +++ b/src/main/resources/assets/tcdcommons/lang/zh_tw.json @@ -0,0 +1,42 @@ +{ + "modmenu.nameTranslation.tcdcommons": "TCDCommons API", + "modmenu.summaryTranslation.tcdcommons": "TheCSDev 的個人 Minecraft 模組開發庫。", + + "tcdcommons.config.common": "用戶端/伺服器端屬性", + "tcdcommons.config.client": "用戶端屬性", + "tcdcommons.config.client.update_item_groups_on_join": "加入遊戲時更新物品組", + "tcdcommons.config.client.update_item_groups_on_join.tooltip": "效能最佳化功能。原版遊戲在開啟物品欄時更新物品組,這在大型模組包中會導致延遲。此功能在載入畫面期間執行該操作,使遊戲內不再因此發生卡頓。", + "tcdcommons.config.server": "伺服器端屬性", + "tcdcommons.config.property_value": "值", + + "tcdcommons.stat_type.minecraft.custom": "一般", + "tcdcommons.stat_type.minecraft.killed": "擊殺", + "tcdcommons.stat_type.minecraft.killed_by": "被擊殺", + "tcdcommons.stat_type.morestats.damaged": "造成傷害", + "tcdcommons.stat_type.morestats.damaged_by": "受到傷害", + "tcdcommons.stat_type.morestats.totem_popped_by": "觸發不死圖騰", + + "tcdcommons.gui.screen.text_dialog.default_title": "對話框", + "tcdcommons.gui.screen.text_dialog.error_title": "發生錯誤", + + "tcdcommons.gui.dropdown.default_label": "選擇一個選項……", + + "tcdcommons.gui.filechooser.mode.explore": "檔案瀏覽器", + "tcdcommons.gui.filechooser.mode.choose_file": "選取檔案", + "tcdcommons.gui.filechooser.mode.create_file": "建立檔案", + "tcdcommons.gui.filechooser.quick_access": "快速存取", + "tcdcommons.gui.filechooser.quick_access.mount_points": "裝置和磁碟機", + "tcdcommons.gui.filechooser.ctxmenu.select": "選取", + "tcdcommons.gui.filechooser.ctxmenu.open": "開啟", + "tcdcommons.gui.filechooser.ctxmenu.open_with": "開啟方式", + "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app": "關聯應用程式", + "tcdcommons.gui.filechooser.action.file_name": "檔案名稱", + "tcdcommons.gui.filechooser.action.file_type": "檔案類型", + + "tcdcommons.misc.loading": "載入中……", + "tcdcommons.misc.something_went_wrong": "發生錯誤", + "tcdcommons.misc.coming_soon": "即將推出", + "tcdcommons.misc.preview": "預覽", + "tcdcommons.misc.from": "從", + "tcdcommons.misc.to": "到" +} \ No newline at end of file From 1d05791acbf629e801d21a62a3a69c5835366e6b Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Sat, 18 Jul 2026 00:28:09 +0200 Subject: [PATCH 5/9] Release 5.5.2+fn-26.2 (#27) * Add Polish translation (#26) --------- Co-authored-by: JustShadow78 --- gradle.properties | 2 +- .../assets/tcdcommons/lang/pl_pl.json | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/tcdcommons/lang/pl_pl.json diff --git a/gradle.properties b/gradle.properties index 2c05e57..626e501 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.5.1 +mod.version = 5.5.2 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/src/main/resources/assets/tcdcommons/lang/pl_pl.json b/src/main/resources/assets/tcdcommons/lang/pl_pl.json new file mode 100644 index 0000000..09df5e9 --- /dev/null +++ b/src/main/resources/assets/tcdcommons/lang/pl_pl.json @@ -0,0 +1,42 @@ +{ + "modmenu.nameTranslation.tcdcommons": "TCDCommons API", + "modmenu.summaryTranslation.tcdcommons": "Personalna biblioteka TheCSDev do tworzenia modów do Minecrafta.", + + "tcdcommons.config.common": "Ustawienia klienta/serwera", + "tcdcommons.config.client": "Ustawienia klienta", + "tcdcommons.config.client.update_item_groups_on_join": "Aktualizuj grupy przedmiotów po dołączeniu", + "tcdcommons.config.client.update_item_groups_on_join.tooltip": "Funkcja poprawiająca wydajność. Domyślna gra aktualizuje grupy przedmiotów podczas otwierania ekwipunku, co powoduje chwilowe przycięcie na dużych paczkach modów. Ta funkcja wykonuje tą operację podczas ekranu ładowania, dzięki czemu przycięcie nie występuje podczas rozgrywki.", + "tcdcommons.config.server": "Ustawienia Serwera", + "tcdcommons.config.property_value": "Wartość", + + "tcdcommons.stat_type.minecraft.custom": "Ogólne", + "tcdcommons.stat_type.minecraft.killed": "Zabito", + "tcdcommons.stat_type.minecraft.killed_by": "Zabity przez", + "tcdcommons.stat_type.morestats.damaged": "Obrażenia zadane", + "tcdcommons.stat_type.morestats.damaged_by": "Obrażenia otrzymane", + "tcdcommons.stat_type.morestats.totem_popped_by": "Zużyte totemy przez", + + "tcdcommons.gui.screen.text_dialog.default_title": "Dialog", + "tcdcommons.gui.screen.text_dialog.error_title": "Coś poszło nie tak", + + "tcdcommons.gui.dropdown.default_label": "Wybierz opcję...", + + "tcdcommons.gui.filechooser.mode.explore": "Eksplorator plików", + "tcdcommons.gui.filechooser.mode.choose_file": "Wybierz plik", + "tcdcommons.gui.filechooser.mode.create_file": "Utwórz plik", + "tcdcommons.gui.filechooser.quick_access": "Szybki dostęp", + "tcdcommons.gui.filechooser.quick_access.mount_points": "Punkty montowania", + "tcdcommons.gui.filechooser.ctxmenu.select": "Wybierz", + "tcdcommons.gui.filechooser.ctxmenu.open": "Otwórz", + "tcdcommons.gui.filechooser.ctxmenu.open_with": "Otwórz w", + "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app": "Powiązanej aplikacji", + "tcdcommons.gui.filechooser.action.file_name": "Nazwa pliku", + "tcdcommons.gui.filechooser.action.file_type": "Typ pliku", + + "tcdcommons.misc.loading": "Ładowanie...", + "tcdcommons.misc.something_went_wrong": "Coś poszło nie tak", + "tcdcommons.misc.coming_soon": "Wkrótce", + "tcdcommons.misc.preview": "Podgląd", + "tcdcommons.misc.from": "Od", + "tcdcommons.misc.to": "Do" +} \ No newline at end of file From 21d296296859eacb83db226dd1a19d8007fa1604 Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Sun, 19 Jul 2026 21:41:26 +0200 Subject: [PATCH 6/9] Release 5.5.3+fn-26.2 (#29) * Add de_de.json (#28) --------- Co-authored-by: Ultra --- README.md | 2 +- gradle.properties | 2 +- .../assets/tcdcommons/lang/de_de.json | 42 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/assets/tcdcommons/lang/de_de.json diff --git a/README.md b/README.md index bed1700..159d232 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ TCDCommons is a Minecraft modding API library that features its own GUI system a ## Dependencies This mod depends on some other mods that first need to be installed before this mod can be installed. Those dependencies are as follows: -- 🏗 [Architectury API](https://github.com/architectury/architectury-api) - Allows this mod to run on `Fabric` and `NeoForge` +- 🧵 [Fabric API](https://github.com/FabricMC/fabric-api) (Fabric only) - Loads this mod's assets and resources. ## Building diff --git a/gradle.properties b/gradle.properties index 626e501..0156ccd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.5.2 +mod.version = 5.5.3 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/src/main/resources/assets/tcdcommons/lang/de_de.json b/src/main/resources/assets/tcdcommons/lang/de_de.json new file mode 100644 index 0000000..6e591c6 --- /dev/null +++ b/src/main/resources/assets/tcdcommons/lang/de_de.json @@ -0,0 +1,42 @@ +{ + "modmenu.nameTranslation.tcdcommons": "TCDCommons API", + "modmenu.summaryTranslation.tcdcommons": "TheCSDev's Persönliche Minecraft-Modding-Bibliothek.", + + "tcdcommons.config.common": "Klient/Server Eigenschaften", + "tcdcommons.config.client": "Klient Eigenschaften", + "tcdcommons.config.client.update_item_groups_on_join": "Artikelgruppen beim Betritt aktualisieren", + "tcdcommons.config.client.update_item_groups_on_join.tooltip": "Leistungs-Funktion. Das Basisspiel aktualisiert beim Öffnen des Inventars die Item-Gruppen, was bei größeren Modpacks zur einer Verzögerungsspitze führen kann. Diese Funktion führt den Vorgang während des Ladebildschirms aus, damit es im Spiel nicht zum Verzögern auftretet.", + "tcdcommons.config.server": "Server Eigenschaften", + "tcdcommons.config.property_value": "Wert", + + "tcdcommons.stat_type.minecraft.custom": "Allgemein", + "tcdcommons.stat_type.minecraft.killed": "Getötet", + "tcdcommons.stat_type.minecraft.killed_by": "Getötet an", + "tcdcommons.stat_type.morestats.damaged": "Schaden verursacht", + "tcdcommons.stat_type.morestats.damaged_by": "Schaden erlitten", + "tcdcommons.stat_type.morestats.totem_popped_by": "Totems Ausgelöst von", + + "tcdcommons.gui.screen.text_dialog.default_title": "Dialog", + "tcdcommons.gui.screen.text_dialog.error_title": "Etwas ist schiefaufgelaufen", + + "tcdcommons.gui.dropdown.default_label": "Wähle eine Option...", + + "tcdcommons.gui.filechooser.mode.explore": "Datei-Explorer", + "tcdcommons.gui.filechooser.mode.choose_file": "Datei auswählen", + "tcdcommons.gui.filechooser.mode.create_file": "Datei erstellen", + "tcdcommons.gui.filechooser.quick_access": "Schnellzugriff", + "tcdcommons.gui.filechooser.quick_access.mount_points": "Einhängepunkte", + "tcdcommons.gui.filechooser.ctxmenu.select": "Auswählen", + "tcdcommons.gui.filechooser.ctxmenu.open": "Öffnen", + "tcdcommons.gui.filechooser.ctxmenu.open_with": "Öffnen mit", + "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app": "Zugehörige Anwendung", + "tcdcommons.gui.filechooser.action.file_name": "Dateiname", + "tcdcommons.gui.filechooser.action.file_type": "Dateityp", + + "tcdcommons.misc.loading": "Wird Geladen...", + "tcdcommons.misc.something_went_wrong": "Etwas ist schiefaufgelaufen", + "tcdcommons.misc.coming_soon": "Bald verfügbar", + "tcdcommons.misc.preview": "Vorschau", + "tcdcommons.misc.from": "Von", + "tcdcommons.misc.to": "Zu" +} From bdb1d8752b1fcac3af409bacc7fe467c17ebd492 Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Fri, 24 Jul 2026 19:30:19 +0200 Subject: [PATCH 7/9] Release 5.5.4+fn-26.2 (#30) --- gradle.properties | 2 +- .../assets/tcdcommons/lang/bs_ba.json | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/tcdcommons/lang/bs_ba.json diff --git a/gradle.properties b/gradle.properties index 0156ccd..f8b47d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.5.3 +mod.version = 5.5.4 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/src/main/resources/assets/tcdcommons/lang/bs_ba.json b/src/main/resources/assets/tcdcommons/lang/bs_ba.json new file mode 100644 index 0000000..83cb857 --- /dev/null +++ b/src/main/resources/assets/tcdcommons/lang/bs_ba.json @@ -0,0 +1,42 @@ +{ + "modmenu.nameTranslation.tcdcommons": "TCDCommons API", + "modmenu.summaryTranslation.tcdcommons": "TheCSDev-ova lična biblioteka za modovanje Minecraft-a.", + + "tcdcommons.config.common": "Klijent/server postavke", + "tcdcommons.config.client": "Klijent postavke", + "tcdcommons.config.client.update_item_groups_on_join": "Ažuriraj grupe predmeta pri pridruživanju", + "tcdcommons.config.client.update_item_groups_on_join.tooltip": "Funkcija za poboljšanje performanse. Vanilla igra ažurira grupe predmeta prilikom otvaranja inventara, što uzrokuje lag kod velikih modpack-ova. Ova funkcija izvršava tu radnju tokom ekrana učitavanja, tako da se lag ne pojavljuje tokom igre.", + "tcdcommons.config.server": "Server postavke", + "tcdcommons.config.property_value": "Vrijednost", + + "tcdcommons.stat_type.minecraft.custom": "Uopšteno", + "tcdcommons.stat_type.minecraft.killed": "Ubijeno", + "tcdcommons.stat_type.minecraft.killed_by": "Ubilo te", + "tcdcommons.stat_type.morestats.damaged": "Nanesena šteta", + "tcdcommons.stat_type.morestats.damaged_by": "Primljena šteta", + "tcdcommons.stat_type.morestats.totem_popped_by": "Potrošeni totemi zbog", + + "tcdcommons.gui.screen.text_dialog.default_title": "Dijalog", + "tcdcommons.gui.screen.text_dialog.error_title": "Nešto je pošlo po zlu", + + "tcdcommons.gui.dropdown.default_label": "Izaberi opciju...", + + "tcdcommons.gui.filechooser.mode.explore": "Pregled datoteka", + "tcdcommons.gui.filechooser.mode.choose_file": "Izaberi datoteku", + "tcdcommons.gui.filechooser.mode.create_file": "Kreiraj datoteku", + "tcdcommons.gui.filechooser.quick_access": "Brzi pristup", + "tcdcommons.gui.filechooser.quick_access.mount_points": "Tačke montiranja", + "tcdcommons.gui.filechooser.ctxmenu.select": "Izaberi", + "tcdcommons.gui.filechooser.ctxmenu.open": "Otvori", + "tcdcommons.gui.filechooser.ctxmenu.open_with": "Otvori pomoću", + "tcdcommons.gui.filechooser.ctxmenu.open_with.assoc_app": "Povezana aplikacija", + "tcdcommons.gui.filechooser.action.file_name": "Naziv datoteke", + "tcdcommons.gui.filechooser.action.file_type": "Vrsta datoteke", + + "tcdcommons.misc.loading": "Učitavanje...", + "tcdcommons.misc.something_went_wrong": "Nešto je pošlo po zlu", + "tcdcommons.misc.coming_soon": "Dolazi uskoro", + "tcdcommons.misc.preview": "Pregled", + "tcdcommons.misc.from": "Od", + "tcdcommons.misc.to": "Do" +} From 91fc0c84531f7719f3ceeb6293078321715fee1b Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Thu, 30 Jul 2026 14:49:36 +0200 Subject: [PATCH 8/9] Release 5.5.5+fn-26.2 (#31) --- build.gradle | 2 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +++- .../com/thecsdev/commonmc/client/mixin/events/MixinHud.java | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 67c9366..aa2802a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'net.fabricmc.fabric-loom' version "1.15-SNAPSHOT" + id 'net.fabricmc.fabric-loom' version "1.17-SNAPSHOT" } dependencies { diff --git a/gradle.properties b/gradle.properties index f8b47d3..10bf9eb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.5.4 +mod.version = 5.5.5 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 19a6bde..df6a6ad 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java index 2399ead..eb94496 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java @@ -18,7 +18,7 @@ public abstract class MixinHud // ================================================== private @Final @Shadow Minecraft minecraft; // ================================================== - @Inject(method = "extractHotbarAndDecorations", at = @At("HEAD"), cancellable = true) + @Inject(method = "extractHotbarAndDecorations", at = @At("HEAD"), cancellable = true, require = 0) private final void onExtractHotbarAndDecorations(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker, CallbackInfo ci) { //cancel hotbar rendering if a currently opened t-screen does not allow this From ec0b5aafc58bd14a6881caaa41784e814db2973e Mon Sep 17 00:00:00 2001 From: TheCSDev Date: Thu, 6 Aug 2026 19:56:36 +0200 Subject: [PATCH 9/9] Backport to 26.1 --- gradle.properties | 20 +++++----- .../api/client/gui/misc/TEntityElement.java | 5 +-- .../api/client/gui/render/TGuiGraphics.java | 2 +- .../gui/screen/ILastScreenProvider.java | 9 ++--- .../api/client/gui/screen/TScreen.java | 15 ++++---- .../api/client/gui/screen/TScreenWrapper.java | 4 +- .../gui/widget/stats/TEntityStatsWidget.java | 3 +- .../client/gui/screen/TTestScreen.java | 2 +- .../client/mixin/events/MixinClientLevel.java | 19 ++++------ .../MixinClientboundAwardStatsPacket.java | 6 +-- .../client/mixin/events/MixinGui.java | 38 +++++++++---------- .../client/mixin/events/MixinHud.java | 29 -------------- .../client/mixin/events/MixinMinecraft.java | 2 +- .../client/mixin/events/MixinNativeImage.java | 2 +- .../commonmc/world/sandbox/SandboxLevel.java | 12 +++--- .../tcdcommons.client.mixin.events.json | 3 +- 16 files changed, 65 insertions(+), 106 deletions(-) delete mode 100644 src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java diff --git a/gradle.properties b/gradle.properties index 10bf9eb..aed616c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,14 +22,14 @@ mod.link.sources = https://thecsdev.com/fwd/tcdcommons-sources/ mod.link.issues = https://thecsdev.com/fwd/tcdcommons-issues/ # 'pack.mcmeta' properties -pack.format = 88 +pack.format = 84 # Minecraft properties -minecraft.version = 26.2 +minecraft.version = 26.1 # Fabric properties -fabric.loader_version = 0.19.3 -fabric.api_version = 0.152.1+26.2 +fabric.loader_version = 0.18.5 +fabric.api_version = 0.144.0+26.1 # fabric.mod.json properties fabric.json.entrypoints.main = com.thecsdev.commonmc.fabric.TCDCommonsFabric @@ -37,14 +37,14 @@ fabric.api_version = 0.152.1+26.2 fabric.json.entrypoints.server = com.thecsdev.commonmc.fabric.TCDCommonsFabric fabric.json.depends.java = >=25 - fabric.json.depends.minecraft = ~26.2 - fabric.json.depends.fabricloader = >=0.19.3 - fabric.json.depends.fabric-api = >=0.152.1 + fabric.json.depends.minecraft = ~26.1 + fabric.json.depends.fabricloader = >=0.18.5 + fabric.json.depends.fabric-api = >=0.144.0 # Neo-Forge properties neoforge.version = 26.1.0.7-beta # neoforge.mods.toml properties - net.toml.loaderVersion = [4,) - neo.toml.dependencies.neoforge = [26.2.0.1-beta,) - neo.toml.dependencies.minecraft = [26.2, 26.3) + net.toml.loaderVersion = [2,) + neo.toml.dependencies.neoforge = [26.1.0.7-beta,) + neo.toml.dependencies.minecraft = [26.1, 26.2) diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java index 683fa8c..5797c22 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TEntityElement.java @@ -14,7 +14,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.level.Level; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -36,7 +35,7 @@ // ================================================== ================================================== // TEntityElement IMPLEMENTATION // ================================================== ================================================== - private final NotNullProperty> entityType = new NotNullProperty<>(EntityTypes.MARKER); + private final NotNullProperty> entityType = new NotNullProperty<>(EntityType.MARKER); private final BooleanProperty followsCursor = new BooleanProperty(true); private final DoubleProperty entityScale = new DoubleProperty(1d); // -------------------------------------------------- @@ -195,7 +194,7 @@ else if(cached instanceof RuntimeException error) //create the entity if not done so before final var client = Minecraft.getInstance(); - if(entityType == EntityTypes.PLAYER) try { + if(entityType == EntityType.PLAYER) try { final var player = Objects.requireNonNull(client.player, "Missing 'Minecraft#player' instance"); CACHE.put(entityType, player); return (E) player; diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java index 7ffa8a2..672fc09 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java @@ -714,7 +714,7 @@ public final void renderTScreen(@NotNull TScreen screen) //do not render tooltip and cursor if the screen isn't open. //this prevents annoyances from 'last/previous screens' when //a screen is rendering its 'last/previous screen'. - if(this.client.gui.screen() != screen.getAsScreen()) + if(this.client.screen != screen.getAsScreen()) return; // ---------- TOOLTIP RENDERING diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java index a209911..5ee92df 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/ILastScreenProvider.java @@ -3,7 +3,6 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.screens.Screen; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -17,7 +16,7 @@ * This is generally used to open the previous screen when closing * the current one. * - * @see Gui#setScreen(Screen) + * @see Minecraft#setScreen(Screen) * @see TScreen#close() */ @Environment(EnvType.CLIENT) @@ -60,14 +59,14 @@ public interface ILastScreenProvider * {@link ILastScreenProvider}. * * @param client The {@link Minecraft} client. - * @return Any {@link ILastScreenProvider} associated with the current {@link Gui#screen()}, if any. + * @return Any {@link ILastScreenProvider} associated with the current {@link Minecraft#screen}, if any. * @throws NullPointerException If the argument is {@code null}. */ public static @Nullable ILastScreenProvider getCurrent( @NotNull Minecraft client) throws NullPointerException { - if(client.gui.screen() instanceof ILastScreenProvider lsp) + if(client.screen instanceof ILastScreenProvider lsp) return lsp; - else if(client.gui.screen() instanceof TScreenWrapper tsw && tsw.getTargetTScreen() instanceof ILastScreenProvider lsp) + else if(client.screen instanceof TScreenWrapper tsw && tsw.getTargetTScreen() instanceof ILastScreenProvider lsp) return lsp; return null; } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java index f09fbb8..06e5e43 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreen.java @@ -11,7 +11,6 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.ApiStatus.Internal; @@ -125,13 +124,13 @@ public TScreen() /** * Returns {@code true} if this {@link TScreen} is currently opened by * a {@link Minecraft} client instance. - * @see Gui#screen() + * @see Minecraft#screen */ @Contract(pure = true) public final boolean isOpen() { final var screen = getAsScreen(); final @Nullable var client = screen.getClient(); - return client.gui.screen() == screen; + return client.screen == screen; } /** @@ -163,7 +162,7 @@ public final boolean isOpen() { // -------------------------------------------------- /** * Callback method that is invoked whenever this {@link TScreen} is opened - * via {@link Gui#setScreen(Screen)}.
+ * via {@link Minecraft#setScreen(Screen)}.
* This takes place before {@link #initCallback()} is invoked. * @see Screen#added() */ @@ -171,7 +170,7 @@ public final boolean isOpen() { /** * Callback method that is invoked whenever this {@link TScreen} is closed - * via {@link Gui#setScreen(Screen)}.
+ * via {@link Minecraft#setScreen(Screen)}.
* This takes place after {@link #close()} is invoked. * @see Screen#removed() */ @@ -179,14 +178,14 @@ public final boolean isOpen() { // -------------------------------------------------- /** * Callback method that is invoked whenever this {@link TScreen} is closing. - * By default, this sets {@link Gui#screen()} to {@code null}, but you + * By default, this sets {@link Minecraft#screen} to {@code null}, but you * may override this to set another {@link Screen} instance if necessary. - * @apiNote This method must use {@link Gui#setScreen(Screen)}. + * @apiNote This method must use {@link Minecraft#setScreen(Screen)}. */ public @Virtual void close() { //set screen to last screen if available, else to null final @Nullable var client = getClient(); - if(isOpen()) client.gui.setScreen(getLastScreen(this)); + if(isOpen()) client.setScreen(getLastScreen(this)); } // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java index e84bd92..27c3359 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java @@ -92,7 +92,7 @@ protected TScreenWrapper(@NotNull T target) { // ================================================== public final @Override void added() { this.minecraft.schedule(() -> { - if(this.minecraft.gui.screen() == this) this.target.openCallback(); + if(this.minecraft.screen == this) this.target.openCallback(); }); } // -------------------------------------------------- @@ -115,7 +115,7 @@ protected TScreenWrapper(@NotNull T target) { public final @Override void removed() { this.minecraft.schedule(() -> { //do nothing in case something reopened this screen by the time this method got called - if(this.minecraft.gui.screen() == this) return; + if(this.minecraft.screen == this) return; //invoke the corresponding callback method this.target.closeCallback(); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java index 8204a09..6bae490 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/stats/TEntityStatsWidget.java @@ -14,7 +14,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EntityTypes; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,7 +38,7 @@ public final class TEntityStatsWidget extends TStatsWidget // ================================================== private final ObjectProperty stats = new ObjectProperty<>(); // -------------------------------------------------- - private final TEntityElement el_entity = new TEntityElement(EntityTypes.MARKER); + private final TEntityElement el_entity = new TEntityElement(EntityType.MARKER); // ================================================== public TEntityStatsWidget() { this(null); } public TEntityStatsWidget(@NotNull EntityType subject, @NotNull IStatsProvider provider) { this(new EntityStats(subject, provider)); } diff --git a/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java b/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java index 5d7b471..e599259 100644 --- a/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java +++ b/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java @@ -83,7 +83,7 @@ else if(throwable != null) LOGGER.error("File chooser completed exceptionally: ", throwable); return null; }); - getClient().gui.setScreen(screen.getAsScreen()); + getClient().setScreen(screen.getAsScreen()); }); panel.add(btn1); diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java index e66ee7f..714dc5c 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientLevel.java @@ -4,7 +4,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.client.renderer.extract.LevelExtractor; +import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.core.Holder; import net.minecraft.resources.ResourceKey; import org.spongepowered.asm.mixin.Mixin; @@ -19,16 +19,13 @@ public abstract class MixinClientLevel @SuppressWarnings("rawtypes") @Inject(method = "", at = @At("RETURN")) private void onInit( - ClientPacketListener connection, - ClientLevel.ClientLevelData levelData, - ResourceKey dimension, - Holder dimensionType, - int serverChunkRadius, - int serverSimulationDistance, - LevelExtractor levelExtractor, - boolean isDebug, - long biomeZoomSeed, - int seaLevel, + ClientPacketListener clientPacketListener, + ClientLevel.ClientLevelData clientLevelData, + ResourceKey resourceKey, + Holder holder, + int i, int j, + LevelRenderer levelRenderer, + boolean bl, long l, int k, CallbackInfo ci) { Minecraft.getInstance().execute(() -> diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java index 4135e23..85db99c 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinClientboundAwardStatsPacket.java @@ -15,17 +15,17 @@ public abstract class MixinClientboundAwardStatsPacket { // ================================================== @Inject(method = "handle*", at = @At("RETURN"), require = 1, remap = true) - private void onHandle(ClientGamePacketListener listener, CallbackInfo callbackInfo) + private void onHandle(ClientGamePacketListener clientPlayPacketListener, CallbackInfo callbackInfo) { //execute handlers for this packet, but on the client's thread final var client = Minecraft.getInstance(); client.execute(() -> { //invoke callback method for screens - if(client.gui.screen() instanceof IStatsListener isl) + if(client.screen instanceof IStatsListener isl) isl.statsReceivedCallback(); //or invoke callback method for t-screens - else if(client.gui.screen() instanceof TScreenWrapper tsw && + else if(client.screen instanceof TScreenWrapper tsw && tsw.getTargetTScreen() instanceof IStatsListener isl) isl.statsReceivedCallback(); }); diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java index d333ac2..b10ca25 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinGui.java @@ -1,6 +1,6 @@ package com.thecsdev.commonmc.client.mixin.events; -import com.llamalad7.mixinextras.sugar.Local; +import com.thecsdev.commonmc.api.client.gui.screen.TScreenWrapper; import com.thecsdev.commonmc.api.client.registry.TClientRegistries; import com.thecsdev.commonmc.client.mixin.hooks.AccessorScreen; import net.minecraft.CrashReport; @@ -25,25 +25,22 @@ public abstract class MixinGui // ================================================== private @Final @Shadow Minecraft minecraft; // ================================================== - @Inject( - method = "extractRenderState", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/Hud;extractRenderState(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V", - shift = At.Shift.AFTER) - ) - private void onPostRender( - DeltaTracker deltaTracker, - boolean shouldRenderLevel, - boolean resourcesLoaded, - CallbackInfo ci, - @Local(name = "graphics") GuiGraphicsExtractor graphics) + @Inject(method = "extractRenderState", at = @At("HEAD"), cancellable = true, require = 0) + private void onPreRender(GuiGraphicsExtractor pencil, DeltaTracker tickCounter, CallbackInfo ci) + { + //cancel HUD rendering if a currently opened t-screen does not allow this + if(this.minecraft.screen instanceof TScreenWrapper tsw && !tsw.isAllowingInGameHud()) + ci.cancel(); + } + // -------------------------------------------------- + @Inject(method = "extractRenderState", at = @At("RETURN")) + private void onPostRender(GuiGraphicsExtractor pencil, DeltaTracker tickCounter, CallbackInfo ci) { //render in-game-hud screens if(TClientRegistries.HUD_SCREEN.size() > 0) { //prepare variables for rendering - final var currentScreen = minecraft.gui.screen(); + final var currentScreen = minecraft.screen; final var clientWindow = minecraft.getWindow(); final var mouse = minecraft.mouseHandler; final int windowW = clientWindow.getGuiScaledWidth(); @@ -54,14 +51,15 @@ private void onPostRender( //iterate hud screens and render them for(final var hudScreen : TClientRegistries.HUD_SCREEN) try { - //do not render current screen or screens of different clients - if(hudScreen == currentScreen || ((AccessorScreen)hudScreen).getMinecraft() != this.minecraft) - continue; + //do not render the current screen + if(hudScreen == currentScreen) continue; //(re/)initialize screens whenever necessary - if(hudScreen.width != windowW || hudScreen.height != windowH) + if(((AccessorScreen)hudScreen).getMinecraft() != this.minecraft || + hudScreen.width != windowW || hudScreen.height != windowH) { hudScreen.init(windowW, windowH); + } //render the screen onto the in-game-hud - hudScreen.extractRenderState(graphics, mouseX, mouseY, deltaTracker.getGameTimeDeltaPartialTick(false)); + hudScreen.extractRenderState(pencil, mouseX, mouseY, tickCounter.getGameTimeDeltaPartialTick(false)); //note: ticking screens is not done here, to avoid weird visual bugs } catch(Exception exc) { //hold modded screens accountable for any exceptions they throw diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java deleted file mode 100644 index eb94496..0000000 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinHud.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.thecsdev.commonmc.client.mixin.events; - -import com.thecsdev.commonmc.api.client.gui.screen.TScreenWrapper; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphicsExtractor; -import net.minecraft.client.gui.Hud; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Hud.class) -public abstract class MixinHud -{ - // ================================================== - private @Final @Shadow Minecraft minecraft; - // ================================================== - @Inject(method = "extractHotbarAndDecorations", at = @At("HEAD"), cancellable = true, require = 0) - private final void onExtractHotbarAndDecorations(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker, CallbackInfo ci) - { - //cancel hotbar rendering if a currently opened t-screen does not allow this - if(this.minecraft.gui.screen() instanceof TScreenWrapper tsw && !tsw.isAllowingInGameHud()) - ci.cancel(); - } - // ================================================== -} diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java index 6a70df3..f1ef15c 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinMinecraft.java @@ -19,7 +19,7 @@ public abstract class MixinMinecraft // ================================================== public @Shadow @Nullable LocalPlayer player; // ================================================== - @Inject(method = "clearClientLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/Hud;onDisconnected()V")) + @Inject(method = "clearClientLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/Gui;onDisconnected()V")) private final void onLocalPlayerQuit(Screen screen, CallbackInfo ci) { final var lp = Objects.requireNonNull(player, "Missing 'LocalPlayer' instance"); ((Minecraft)(Object)this).execute(() -> ClientEvent.PLAYER_QUIT.invoker().invoke(lp)); diff --git a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java index 8ed579b..d348030 100644 --- a/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java +++ b/src/main/java/com/thecsdev/commonmc/client/mixin/events/MixinNativeImage.java @@ -10,7 +10,7 @@ /** * This {@link Mixin}'s sole purpose is to put image byte data loading up to * LWJGL's digression, rather than having the game enforce PNG. And on another note, - * the game even fails to validate PNG properly most the time anyway, so this + * the game even fails to validate PNG properly most the time anyways, so this * is kind of more of a bug fix in a way. */ @Mixin(value = NativeImage.class) diff --git a/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java b/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java index 821e752..dab8a71 100644 --- a/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java +++ b/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java @@ -1,16 +1,14 @@ package com.thecsdev.commonmc.world.sandbox; import com.thecsdev.common.util.annotations.Virtual; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryAccess; +import net.minecraft.core.*; import net.minecraft.core.particles.ExplosionParticleInfo; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.BlockTags; import net.minecraft.util.random.WeightedList; import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.TickRateManager; @@ -77,7 +75,7 @@ 0, // minimum Y 32, // height 32, // logicalHeight - HolderSet.empty(), // infiniburn + BlockTags.INFINIBURN_OVERWORLD, // infiniburn 1.0F, // ambientLight new DimensionType.MonsterSettings(UniformInt.of(0, 7), 0), DimensionType.Skybox.OVERWORLD, @@ -96,7 +94,7 @@ public void onTrackingStart(Entity object) {} public void onTrackingEnd(Entity object) {} public void onSectionChange(Entity object) {} }); - protected @NotNull ClockManager clockManager = _ -> 0; + protected @NotNull ClockManager clockManager = __ -> 0; protected @NotNull List dragonParts = new ArrayList<>(); protected @NotNull TickRateManager tickRateManager = new TickRateManager(); protected @NotNull Scoreboard scoreboard = new Scoreboard(); @@ -124,7 +122,7 @@ public SandboxLevel(WritableLevelData properties, ResourceKey registryRef public @Virtual @Override void playSeededSound(@Nullable Entity source, Entity entity, Holder sound, SoundSource category, float volume, float pitch, long speed) {} public @Virtual @Override void explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, ExplosionInteraction explosionSourceType, ParticleOptions smallParticle, ParticleOptions largeParticle, WeightedList blockParticles, Holder soundEvent) {} public @Virtual @Override String gatherChunkSourceStats() { - return "Chunks[C] W: " + getChunkSource().gatherStats() + " E: " + this.entityManager.gatherStats(); + return "Chunks[C] W: " + getChunkSource().gatherStats() + " E: " + this.entityManager.gatherStats(); } public @Virtual @Override void setRespawnData(LevelData.RespawnData spawnPoint) {} public @Virtual @Override LevelData.RespawnData getRespawnData() { return getLevelData().getRespawnData(); } diff --git a/src/main/resources/tcdcommons.client.mixin.events.json b/src/main/resources/tcdcommons.client.mixin.events.json index bc06cb9..24e3116 100644 --- a/src/main/resources/tcdcommons.client.mixin.events.json +++ b/src/main/resources/tcdcommons.client.mixin.events.json @@ -12,7 +12,6 @@ "MixinMinecraft", "MixinClientPacketListener", "MixinClientLevel", - "MixinScreen", - "MixinHud" + "MixinScreen" ] }