From a711ba501db0f85777b5916a9bc9f6f3bca15ff9 Mon Sep 17 00:00:00 2001 From: DekinDev Date: Fri, 9 Jan 2026 21:48:48 +0100 Subject: [PATCH] test 3 --- README.md => README | 4 +- build.gradle | 31 +- gradle.properties | 2 +- .../api/client/screen/v1/ScreenEvents.java | 197 ++++++++++++ .../mixin/screen/GameRendererMixin.java | 36 +++ .../mixin/screen/HandledScreenMixin.java | 46 +++ .../fabric/mixin/screen/ScreenMixin.java | 280 ++++++++++++++++++ .../iconsenhanced/client/BorderRenderer.java | 17 +- .../iconsenhanced/client/ClientInit.java | 8 +- .../client/CombinedTooltipComponent.java | 85 ++++++ .../client/CombinedTooltipData.java | 23 ++ .../client/EnchantTooltipComponent.java | 89 +++--- .../client/TooltipAugmenter.java | 167 +++++++++-- .../iconsenhanced/client/TooltipTextUtil.java | 20 ++ .../AbstractContainerScreenAccessor.java | 7 + .../adapters/DefaultEnchantmentAdapter.java | 53 +++- .../dekin/iconsenhanced/common/EnchEntry.java | 8 +- .../common/EnchantSortLogic.java | 6 +- .../dekin/iconsenhanced/common/IconAtlas.java | 8 +- .../assets/iconsenhanced/lang/de_de.json | 45 +++ .../assets/iconsenhanced/lang/en_us.json | 46 ++- .../assets/iconsenhanced/lang/es_es.json | 46 ++- .../assets/iconsenhanced/lang/fr_fr.json | 45 +++ .../assets/iconsenhanced/lang/it_it.json | 45 +++ .../assets/iconsenhanced/lang/pt_br.json | 45 +++ .../assets/iconsenhanced/lang/ru_ru.json | 45 +++ .../assets/iconsenhanced/lang/zh_cn.json | 45 +++ stonecutter.gradle | 17 +- 28 files changed, 1343 insertions(+), 123 deletions(-) rename README.md => README (88%) create mode 100644 net/fabricmc/fabric/api/client/screen/v1/ScreenEvents.java create mode 100644 net/fabricmc/fabric/mixin/screen/GameRendererMixin.java create mode 100644 net/fabricmc/fabric/mixin/screen/HandledScreenMixin.java create mode 100644 net/fabricmc/fabric/mixin/screen/ScreenMixin.java create mode 100644 src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipComponent.java create mode 100644 src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipData.java create mode 100644 src/main/resources/assets/iconsenhanced/lang/de_de.json create mode 100644 src/main/resources/assets/iconsenhanced/lang/fr_fr.json create mode 100644 src/main/resources/assets/iconsenhanced/lang/it_it.json create mode 100644 src/main/resources/assets/iconsenhanced/lang/pt_br.json create mode 100644 src/main/resources/assets/iconsenhanced/lang/ru_ru.json create mode 100644 src/main/resources/assets/iconsenhanced/lang/zh_cn.json diff --git a/README.md b/README similarity index 88% rename from README.md rename to README index 6fcd8cf..16bb4bb 100644 --- a/README.md +++ b/README @@ -6,6 +6,4 @@ Icons Enhanced mejora la lectura de encantamientos y la UI sin cambiar el gamepl - Iconos y colores por encantamiento en los tooltips. - Descripciones de encantamientos. - Bordes en slots de inventario y contenedores. - -## Licencia -Apache-2.0 +- Orden de encantamientos mejorado. \ No newline at end of file diff --git a/build.gradle b/build.gradle index cca731a..18c9393 100644 --- a/build.gradle +++ b/build.gradle @@ -50,27 +50,22 @@ dependencies { modImplementation "net.fabricmc.fabric-api:fabric-api:${property('deps.fabric_api')}" } +def resourceExpandProps = [ + version: project.version, + mod_id: modId, + mod_name: modName, + mod_description: modDescription, + mod_license: modLicense, + mod_author: modAuthor, + minecraft_version: stonecutter.current.version, + fabric_loader_version: fabricLoaderVersion +] + processResources { - inputs.property "version", project.version - inputs.property "mod_id", modId - inputs.property "mod_name", modName - inputs.property "mod_description", modDescription - inputs.property "mod_license", modLicense - inputs.property "mod_author", modAuthor - inputs.property "minecraft_version", stonecutter.current.version - inputs.property "fabric_loader_version", fabricLoaderVersion + inputs.properties(resourceExpandProps) filesMatching("fabric.mod.json") { - expand( - version: project.version, - mod_id: modId, - mod_name: modName, - mod_description: modDescription, - mod_license: modLicense, - mod_author: modAuthor, - minecraft_version: stonecutter.current.version, - fabric_loader_version: fabricLoaderVersion - ) + expand(resourceExpandProps) } } diff --git a/gradle.properties b/gradle.properties index 1a61a72..86656b6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=1G -Dfile.encoding=UTF-8 org.gradle.parallel=true # IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349 diff --git a/net/fabricmc/fabric/api/client/screen/v1/ScreenEvents.java b/net/fabricmc/fabric/api/client/screen/v1/ScreenEvents.java new file mode 100644 index 0000000..88613f6 --- /dev/null +++ b/net/fabricmc/fabric/api/client/screen/v1/ScreenEvents.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.client.screen.v1; + +import java.util.Objects; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.fabricmc.fabric.impl.client.screen.ScreenExtensions; +import net.minecraft.class_310; +import net.minecraft.class_332; +import net.minecraft.class_437; + +/** + * Holds events related to {@link class_437}s. + * + *

Some events require a screen instance in order to obtain an event instance. + * The events that require a screen instance can be identified by the use of a method passing a screen instance. + * All events in {@link ScreenKeyboardEvents} and {@link ScreenMouseEvents} require a screen instance. + * This registration model is used since a screen being (re)initialized will reset the screen to its default state, therefore reverting all changes a mod developer may have applied to a screen. + * Furthermore, this design was chosen to reduce the amount of wasted iterations of events as a mod developer would only need to register screen events for rendering, ticking, keyboards and mice if needed on a per-instance basis. + * + *

The primary entrypoint into a screen is when it is being opened, this is signified by an event {@link ScreenEvents#BEFORE_INIT before} and {@link ScreenEvents#AFTER_INIT after} initialization of the screen. + * + * @see Screens + * @see ScreenKeyboardEvents + * @see ScreenMouseEvents + */ + +public final class ScreenEvents { + /** + * An event that is called before {@link class_437#method_25423(class_310, int, int) a screen is initialized} to its default state. + * It should be noted some methods in {@link Screens} such as a screen's {@link class_437#method_64506 text renderer} may not be initialized yet, and as such their use is discouraged. + * + * + * You can still use {@link ScreenEvents#AFTER_INIT} to register events such as keyboard and mouse events. + * + *

The {@link ScreenExtensions} provided by the {@code info} parameter may be used to register tick, render events, keyboard, mouse, additional and removal of child elements (including buttons). + * For example, to register an event on inventory like screens after render, the following code could be used: + *

{@code
+	 * @Override
+	 * public void onInitializeClient() {
+	 * 	ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
+	 * 		if (screen instanceof AbstractInventoryScreen) {
+	 * 			ScreenEvents.afterRender(screen).register((screen1, matrices, mouseX, mouseY, tickDelta) -> {
+	 * 				...
+	 * 			});
+	 * 		}
+	 * 	});
+	 * }
+	 * }
+ * + *

This event indicates a screen has been resized, and therefore is being re-initialized. + * This event can also indicate that the previous screen has been changed. + * @see ScreenEvents#AFTER_INIT + */ + public static final Event BEFORE_INIT = EventFactory.createArrayBacked(BeforeInit.class, callbacks -> (client, screen, scaledWidth, scaledHeight) -> { + for (BeforeInit callback : callbacks) { + callback.beforeInit(client, screen, scaledWidth, scaledHeight); + } + }); + + /** + * An event that is called after {@link class_437#method_25423(class_310, int, int) a screen is initialized} to its default state. + * + *

Typically this event is used to modify a screen after the screen has been initialized. + * Modifications such as changing sizes of buttons, removing buttons and adding/removing child elements to the screen can be done safely using this event. + * + *

For example, to add a button to the title screen, the following code could be used: + *

{@code
+	 * ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
+	 * 	if (screen instanceof TitleScreen) {
+	 * 		Screens.getButtons(screen).add(new ButtonWidget(...));
+	 * 	}
+	 * });
+	 * }
+ * + *

Note that by adding an element to a screen, the element is not automatically {@link net.minecraft.class_4068 drawn}. + * Unless the element is button, you need to call the specific {@link net.minecraft.class_4068#method_25394(class_332, int, int, float) render} methods in the corresponding screen events. + * + *

This event can also indicate that the previous screen has been closed. + * @see ScreenEvents#BEFORE_INIT + */ + public static final Event AFTER_INIT = EventFactory.createArrayBacked(AfterInit.class, callbacks -> (client, screen, scaledWidth, scaledHeight) -> { + for (AfterInit callback : callbacks) { + callback.afterInit(client, screen, scaledWidth, scaledHeight); + } + }); + + /** + * An event that is called after {@link class_437#method_25432()} is called. + * This event signifies that the screen is now closed. + * + *

This event is typically used to undo any screen specific state changes or to terminate threads spawned by a screen. + * This event may precede initialization events {@link ScreenEvents#BEFORE_INIT} but there is no guarantee that event will be called immediately afterwards. + */ + public static Event remove(class_437 screen) { + Objects.requireNonNull(screen, "Screen cannot be null"); + + return ScreenExtensions.getExtensions(screen).fabric_getRemoveEvent(); + } + + /** + * An event that is called before a screen is rendered. + * + * @return the event + */ + public static Event beforeRender(class_437 screen) { + Objects.requireNonNull(screen, "Screen cannot be null"); + + return ScreenExtensions.getExtensions(screen).fabric_getBeforeRenderEvent(); + } + + /** + * An event that is called after a screen is rendered. + * + * @return the event + */ + public static Event afterRender(class_437 screen) { + Objects.requireNonNull(screen, "Screen cannot be null"); + + return ScreenExtensions.getExtensions(screen).fabric_getAfterRenderEvent(); + } + + /** + * An event that is called before a screen is ticked. + * + * @return the event + */ + public static Event beforeTick(class_437 screen) { + Objects.requireNonNull(screen, "Screen cannot be null"); + + return ScreenExtensions.getExtensions(screen).fabric_getBeforeTickEvent(); + } + + /** + * An event that is called after a screen is ticked. + * + * @return the event + */ + public static Event afterTick(class_437 screen) { + Objects.requireNonNull(screen, "Screen cannot be null"); + + return ScreenExtensions.getExtensions(screen).fabric_getAfterTickEvent(); + } + + @FunctionalInterface + public interface BeforeInit { + void beforeInit(class_310 client, class_437 screen, int scaledWidth, int scaledHeight); + } + + @FunctionalInterface + public interface AfterInit { + void afterInit(class_310 client, class_437 screen, int scaledWidth, int scaledHeight); + } + + @FunctionalInterface + public interface Remove { + void onRemove(class_437 screen); + } + + @FunctionalInterface + public interface BeforeRender { + void beforeRender(class_437 screen, class_332 drawContext, int mouseX, int mouseY, float tickDelta); + } + + @FunctionalInterface + public interface AfterRender { + void afterRender(class_437 screen, class_332 drawContext, int mouseX, int mouseY, float tickDelta); + } + + @FunctionalInterface + public interface BeforeTick { + void beforeTick(class_437 screen); + } + + @FunctionalInterface + public interface AfterTick { + void afterTick(class_437 screen); + } + + private ScreenEvents() { + } +} diff --git a/net/fabricmc/fabric/mixin/screen/GameRendererMixin.java b/net/fabricmc/fabric/mixin/screen/GameRendererMixin.java new file mode 100644 index 0000000..3a18eb3 --- /dev/null +++ b/net/fabricmc/fabric/mixin/screen/GameRendererMixin.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.screen; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.minecraft.class_332; +import net.minecraft.class_437; +import net.minecraft.class_757; + +@Mixin(class_757.class) +abstract class GameRendererMixin { + @WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;renderWithTooltip(Lnet/minecraft/client/gui/DrawContext;IIF)V")) + private void onRenderScreen(class_437 currentScreen, class_332 drawContext, int mouseX, int mouseY, float tickDelta, Operation operation) { + ScreenEvents.beforeRender(currentScreen).invoker().beforeRender(currentScreen, drawContext, mouseX, mouseY, tickDelta); + operation.call(currentScreen, drawContext, mouseX, mouseY, tickDelta); + ScreenEvents.afterRender(currentScreen).invoker().afterRender(currentScreen, drawContext, mouseX, mouseY, tickDelta); + } +} diff --git a/net/fabricmc/fabric/mixin/screen/HandledScreenMixin.java b/net/fabricmc/fabric/mixin/screen/HandledScreenMixin.java new file mode 100644 index 0000000..c0c1bc8 --- /dev/null +++ b/net/fabricmc/fabric/mixin/screen/HandledScreenMixin.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.screen; + +import net.minecraft.class_2561; +import net.minecraft.class_437; +import net.minecraft.class_465; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(class_465.class) +public abstract class HandledScreenMixin extends class_437 { + private HandledScreenMixin(class_2561 title) { + super(title); + } + + @Inject(method = "mouseReleased", at = @At("HEAD"), cancellable = true) + private void callSuperMouseReleased(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { + if (super.method_25406(mouseX, mouseY, button)) { + cir.setReturnValue(true); + } + } + + @Inject(method = "mouseDragged", at = @At("HEAD"), cancellable = true) + private void callSuperMouseReleased(double mouseX, double mouseY, int button, double deltaX, double deltaY, CallbackInfoReturnable cir) { + if (super.method_25403(mouseX, mouseY, button, deltaX, deltaY)) { + cir.setReturnValue(true); + } + } +} diff --git a/net/fabricmc/fabric/mixin/screen/ScreenMixin.java b/net/fabricmc/fabric/mixin/screen/ScreenMixin.java new file mode 100644 index 0000000..cc2f83d --- /dev/null +++ b/net/fabricmc/fabric/mixin/screen/ScreenMixin.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.screen; + +import java.util.List; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents; +import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.impl.client.screen.ButtonList; +import net.fabricmc.fabric.impl.client.screen.ScreenEventFactory; +import net.fabricmc.fabric.impl.client.screen.ScreenExtensions; +import net.minecraft.class_310; +import net.minecraft.class_339; +import net.minecraft.class_364; +import net.minecraft.class_4068; +import net.minecraft.class_437; +import net.minecraft.class_6379; + +@Mixin(class_437.class) +abstract class ScreenMixin implements ScreenExtensions { + @Shadow + @Final + protected List selectables; + @Shadow + @Final + protected List children; + @Shadow + @Final + protected List drawables; + + @Unique + private ButtonList fabricButtons; + @Unique + private Event removeEvent; + @Unique + private Event beforeTickEvent; + @Unique + private Event afterTickEvent; + @Unique + private Event beforeRenderEvent; + @Unique + private Event afterRenderEvent; + + // Keyboard + @Unique + private Event allowKeyPressEvent; + @Unique + private Event beforeKeyPressEvent; + @Unique + private Event afterKeyPressEvent; + @Unique + private Event allowKeyReleaseEvent; + @Unique + private Event beforeKeyReleaseEvent; + @Unique + private Event afterKeyReleaseEvent; + + // Mouse + @Unique + private Event allowMouseClickEvent; + @Unique + private Event beforeMouseClickEvent; + @Unique + private Event afterMouseClickEvent; + @Unique + private Event allowMouseReleaseEvent; + @Unique + private Event beforeMouseReleaseEvent; + @Unique + private Event afterMouseReleaseEvent; + @Unique + private Event allowMouseScrollEvent; + @Unique + private Event beforeMouseScrollEvent; + @Unique + private Event afterMouseScrollEvent; + + @Inject(method = "init(Lnet/minecraft/client/MinecraftClient;II)V", at = @At("HEAD")) + private void beforeInitScreen(class_310 client, int width, int height, CallbackInfo ci) { + beforeInit(client, width, height); + } + + @Inject(method = "init(Lnet/minecraft/client/MinecraftClient;II)V", at = @At("TAIL")) + private void afterInitScreen(class_310 client, int width, int height, CallbackInfo ci) { + afterInit(client, width, height); + } + + @Inject(method = "resize", at = @At("HEAD")) + private void beforeResizeScreen(class_310 client, int width, int height, CallbackInfo ci) { + beforeInit(client, width, height); + } + + @Inject(method = "resize", at = @At("TAIL")) + private void afterResizeScreen(class_310 client, int width, int height, CallbackInfo ci) { + afterInit(client, width, height); + } + + @Unique + private void beforeInit(class_310 client, int width, int height) { + // All elements are repopulated on the screen, so we need to reinitialize all events + this.fabricButtons = null; + this.removeEvent = ScreenEventFactory.createRemoveEvent(); + this.beforeRenderEvent = ScreenEventFactory.createBeforeRenderEvent(); + this.afterRenderEvent = ScreenEventFactory.createAfterRenderEvent(); + this.beforeTickEvent = ScreenEventFactory.createBeforeTickEvent(); + this.afterTickEvent = ScreenEventFactory.createAfterTickEvent(); + + // Keyboard + this.allowKeyPressEvent = ScreenEventFactory.createAllowKeyPressEvent(); + this.beforeKeyPressEvent = ScreenEventFactory.createBeforeKeyPressEvent(); + this.afterKeyPressEvent = ScreenEventFactory.createAfterKeyPressEvent(); + this.allowKeyReleaseEvent = ScreenEventFactory.createAllowKeyReleaseEvent(); + this.beforeKeyReleaseEvent = ScreenEventFactory.createBeforeKeyReleaseEvent(); + this.afterKeyReleaseEvent = ScreenEventFactory.createAfterKeyReleaseEvent(); + + // Mouse + this.allowMouseClickEvent = ScreenEventFactory.createAllowMouseClickEvent(); + this.beforeMouseClickEvent = ScreenEventFactory.createBeforeMouseClickEvent(); + this.afterMouseClickEvent = ScreenEventFactory.createAfterMouseClickEvent(); + this.allowMouseReleaseEvent = ScreenEventFactory.createAllowMouseReleaseEvent(); + this.beforeMouseReleaseEvent = ScreenEventFactory.createBeforeMouseReleaseEvent(); + this.afterMouseReleaseEvent = ScreenEventFactory.createAfterMouseReleaseEvent(); + this.allowMouseScrollEvent = ScreenEventFactory.createAllowMouseScrollEvent(); + this.beforeMouseScrollEvent = ScreenEventFactory.createBeforeMouseScrollEvent(); + this.afterMouseScrollEvent = ScreenEventFactory.createAfterMouseScrollEvent(); + + ScreenEvents.BEFORE_INIT.invoker().beforeInit(client, (class_437) (Object) this, width, height); + } + + @Unique + private void afterInit(class_310 client, int width, int height) { + ScreenEvents.AFTER_INIT.invoker().afterInit(client, (class_437) (Object) this, width, height); + } + + @Override + public List fabric_getButtons() { + // Lazy init to make the list access safe after Screen#init + if (this.fabricButtons == null) { + this.fabricButtons = new ButtonList(this.drawables, this.selectables, this.children); + } + + return this.fabricButtons; + } + + @Unique + private Event ensureEventsAreInitialized(Event event) { + if (event == null) { + throw new IllegalStateException(String.format("[fabric-screen-api-v1] The current screen (%s) has not been correctly initialised, please send this crash log to the mod author. This is usually caused by calling setScreen on the wrong thread.", this.getClass().getName())); + } + + return event; + } + + @Override + public Event fabric_getRemoveEvent() { + return ensureEventsAreInitialized(this.removeEvent); + } + + @Override + public Event fabric_getBeforeTickEvent() { + return ensureEventsAreInitialized(this.beforeTickEvent); + } + + @Override + public Event fabric_getAfterTickEvent() { + return ensureEventsAreInitialized(this.afterTickEvent); + } + + @Override + public Event fabric_getBeforeRenderEvent() { + return ensureEventsAreInitialized(this.beforeRenderEvent); + } + + @Override + public Event fabric_getAfterRenderEvent() { + return ensureEventsAreInitialized(this.afterRenderEvent); + } + + // Keyboard + + @Override + public Event fabric_getAllowKeyPressEvent() { + return ensureEventsAreInitialized(this.allowKeyPressEvent); + } + + @Override + public Event fabric_getBeforeKeyPressEvent() { + return ensureEventsAreInitialized(this.beforeKeyPressEvent); + } + + @Override + public Event fabric_getAfterKeyPressEvent() { + return ensureEventsAreInitialized(this.afterKeyPressEvent); + } + + @Override + public Event fabric_getAllowKeyReleaseEvent() { + return ensureEventsAreInitialized(this.allowKeyReleaseEvent); + } + + @Override + public Event fabric_getBeforeKeyReleaseEvent() { + return ensureEventsAreInitialized(this.beforeKeyReleaseEvent); + } + + @Override + public Event fabric_getAfterKeyReleaseEvent() { + return ensureEventsAreInitialized(this.afterKeyReleaseEvent); + } + + // Mouse + + @Override + public Event fabric_getAllowMouseClickEvent() { + return ensureEventsAreInitialized(this.allowMouseClickEvent); + } + + @Override + public Event fabric_getBeforeMouseClickEvent() { + return ensureEventsAreInitialized(this.beforeMouseClickEvent); + } + + @Override + public Event fabric_getAfterMouseClickEvent() { + return ensureEventsAreInitialized(this.afterMouseClickEvent); + } + + @Override + public Event fabric_getAllowMouseReleaseEvent() { + return ensureEventsAreInitialized(this.allowMouseReleaseEvent); + } + + @Override + public Event fabric_getBeforeMouseReleaseEvent() { + return ensureEventsAreInitialized(this.beforeMouseReleaseEvent); + } + + @Override + public Event fabric_getAfterMouseReleaseEvent() { + return ensureEventsAreInitialized(this.afterMouseReleaseEvent); + } + + @Override + public Event fabric_getAllowMouseScrollEvent() { + return ensureEventsAreInitialized(this.allowMouseScrollEvent); + } + + @Override + public Event fabric_getBeforeMouseScrollEvent() { + return ensureEventsAreInitialized(this.beforeMouseScrollEvent); + } + + @Override + public Event fabric_getAfterMouseScrollEvent() { + return ensureEventsAreInitialized(this.afterMouseScrollEvent); + } +} diff --git a/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java b/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java index 40d9cf8..103fa59 100644 --- a/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java +++ b/src/client/java/dev/dekin/iconsenhanced/client/BorderRenderer.java @@ -20,7 +20,7 @@ public final class BorderRenderer { COLOR_LOGIC.applyConfig(ConfigManager.get()); } - public static void render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY) { + public static void render(Screen screen, GuiGraphics graphics) { IconsEnhancedConfig config = ConfigManager.get(); if (!config.borders.enabled) { return; @@ -45,12 +45,15 @@ public final class BorderRenderer { } private static void drawBorder(GuiGraphics graphics, int x, int y, int thickness, int color) { - int x2 = x + 16; - int y2 = y + 16; - graphics.fill(x, y, x2, y + thickness, color); - graphics.fill(x, y2 - thickness, x2, y2, color); - graphics.fill(x, y, x + thickness, y2, color); - graphics.fill(x2 - thickness, y, x2, y2, color); + int outerX = x - thickness; + int outerY = y - thickness; + int outerSize = 16 + thickness * 2; + int outerX2 = outerX + outerSize; + int outerY2 = outerY + outerSize; + graphics.fill(outerX, outerY, outerX2, outerY + thickness, color); + graphics.fill(outerX, outerY2 - thickness, outerX2, outerY2, color); + graphics.fill(outerX, outerY, outerX + thickness, outerY2, color); + graphics.fill(outerX2 - thickness, outerY, outerX2, outerY2, color); } private static int clamp(int value, int min, int max) { diff --git a/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java b/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java index 6c90dd6..b3e7b7c 100644 --- a/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java +++ b/src/client/java/dev/dekin/iconsenhanced/client/ClientInit.java @@ -2,6 +2,7 @@ package dev.dekin.iconsenhanced.client; import dev.dekin.iconsenhanced.common.ConfigManager; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; public final class ClientInit implements ClientModInitializer { @@ -10,11 +11,16 @@ public final class ClientInit implements ClientModInitializer { ConfigManager.load(); BorderRenderer.applyConfig(); TooltipAugmenter.register(); + ClientTickEvents.END_CLIENT_TICK.register(client -> TooltipAugmenter.registerLate()); ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { + ScreenEvents.beforeRender(screen).register((current, graphics, mouseX, mouseY, delta) -> { + TooltipAugmenter.beforeRender(current, mouseX, mouseY); + }); ScreenEvents.afterRender(screen).register((current, graphics, mouseX, mouseY, delta) -> { - BorderRenderer.render(current, graphics, mouseX, mouseY); + BorderRenderer.render(current, graphics); TooltipAugmenter.renderOverlay(current, graphics, mouseX, mouseY); + TooltipAugmenter.afterRender(current); }); }); } diff --git a/src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipComponent.java b/src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipComponent.java new file mode 100644 index 0000000..6e6fec2 --- /dev/null +++ b/src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipComponent.java @@ -0,0 +1,85 @@ +package dev.dekin.iconsenhanced.client; + +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +//? if <1.21.6 { +/*import net.minecraft.client.renderer.MultiBufferSource; +import org.joml.Matrix4f; +*///?} + +public final class CombinedTooltipComponent implements ClientTooltipComponent { + private static final int GAP = 2; + + private final ClientTooltipComponent primary; + private final ClientTooltipComponent secondary; + + public CombinedTooltipComponent(CombinedTooltipData data) { + this.primary = ClientTooltipComponent.create(data.primary()); + this.secondary = ClientTooltipComponent.create(data.secondary()); + } + + @Override + public int getWidth(Font font) { + return Math.max(primary.getWidth(font), secondary.getWidth(font)); + } + + //? if >=1.21.2 { + @Override + public int getHeight(Font font) { + return componentHeight(primary, font) + GAP + componentHeight(secondary, font); + } + //?} else { + /*@Override + public int getHeight() { + return componentHeight(primary, null) + GAP + componentHeight(secondary, null); + } + *///?} + + //? if >=1.21.2 { + @Override + public boolean showTooltipWithItemInHand() { + return primary.showTooltipWithItemInHand() || secondary.showTooltipWithItemInHand(); + } + //?} + + //? if >=1.21.6 { + @Override + public void renderText(GuiGraphics graphics, Font font, int x, int y) { + int primaryHeight = componentHeight(primary, font); + primary.renderText(graphics, font, x, y); + secondary.renderText(graphics, font, x, y + primaryHeight + GAP); + } + //?} else { + /*@Override + public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + int primaryHeight = componentHeight(primary, font); + primary.renderText(font, x, y, matrix, buffer); + secondary.renderText(font, x, y + primaryHeight + GAP, matrix, buffer); + } + *///?} + + //? if >=1.21.2 { + @Override + public void renderImage(Font font, int x, int y, int width, int height, GuiGraphics graphics) { + int primaryHeight = componentHeight(primary, font); + primary.renderImage(font, x, y, width, height, graphics); + secondary.renderImage(font, x, y + primaryHeight + GAP, width, height, graphics); + } + //?} else { + /*@Override + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { + int primaryHeight = componentHeight(primary, font); + primary.renderImage(font, x, y, graphics); + secondary.renderImage(font, x, y + primaryHeight + GAP, graphics); + } + *///?} + + private static int componentHeight(ClientTooltipComponent component, Font font) { + //? if >=1.21.2 { + return component.getHeight(font); + //?} else { + /*return component.getHeight();*/ + //?} + } +} diff --git a/src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipData.java b/src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipData.java new file mode 100644 index 0000000..3248091 --- /dev/null +++ b/src/client/java/dev/dekin/iconsenhanced/client/CombinedTooltipData.java @@ -0,0 +1,23 @@ +package dev.dekin.iconsenhanced.client; + +import java.util.Objects; + +import net.minecraft.world.inventory.tooltip.TooltipComponent; + +public final class CombinedTooltipData implements TooltipComponent { + private final TooltipComponent primary; + private final TooltipComponent secondary; + + public CombinedTooltipData(TooltipComponent primary, TooltipComponent secondary) { + this.primary = Objects.requireNonNull(primary, "primary"); + this.secondary = Objects.requireNonNull(secondary, "secondary"); + } + + public TooltipComponent primary() { + return primary; + } + + public TooltipComponent secondary() { + return secondary; + } +} diff --git a/src/client/java/dev/dekin/iconsenhanced/client/EnchantTooltipComponent.java b/src/client/java/dev/dekin/iconsenhanced/client/EnchantTooltipComponent.java index a28a9c0..80f646d 100644 --- a/src/client/java/dev/dekin/iconsenhanced/client/EnchantTooltipComponent.java +++ b/src/client/java/dev/dekin/iconsenhanced/client/EnchantTooltipComponent.java @@ -3,13 +3,18 @@ package dev.dekin.iconsenhanced.client; import dev.dekin.iconsenhanced.common.IconAtlas; import dev.dekin.iconsenhanced.common.TooltipLayoutModel; import dev.dekin.iconsenhanced.common.TooltipLayoutModel.Row; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.network.chat.Component; -//? if >=1.21 { +import net.minecraft.network.chat.TextColor; +//? if >=1.21.6 { import net.minecraft.client.renderer.RenderPipelines; -//?} else { +//?} +//? if <1.21.6 { +/*import net.minecraft.client.renderer.RenderType; +*///?} +//? if <1.21.6 { /*import net.minecraft.client.renderer.MultiBufferSource; import org.joml.Matrix4f; *///?} @@ -19,7 +24,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { private static final int TEXT_PADDING = 4; private static final int BADGE_BG = 0xAA000000; private static final int BADGE_TEXT = 0xFFFFFFFF; - //? if <1.21 { + //? if <1.21.6 { /*private static final int FULL_BRIGHT = 0xF000F0; *///?} @@ -46,7 +51,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { return width; } - //? if >=1.21 { + //? if >=1.21.2 { @Override public int getHeight(Font font) { return computeHeight(font); @@ -73,14 +78,14 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { return height; } - //? if >=1.21 { + //? if >=1.21.2 { @Override public boolean showTooltipWithItemInHand() { return true; } //?} - //? if >=1.21 { + //? if >=1.21.6 { @Override public void renderText(GuiGraphics graphics, Font font, int x, int y) { int yOffset = 0; @@ -116,7 +121,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { } *///?} - //? if >=1.21 { + //? if >=1.21.2 { @Override public void renderImage(Font font, int x, int y, int width, int height, GuiGraphics graphics) { renderIcons(font, x, y, graphics); @@ -133,7 +138,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { int rowHeight = Math.max(iconSize, font.lineHeight); for (Row row : layout.rows()) { int iconY = y + yOffset + (rowHeight - iconSize) / 2; - drawIcon(graphics, x, iconY, row.iconKey); + drawIcon(graphics, x, iconY, row.iconKey, row.text); if (showLevelBadge) { drawBadge(graphics, font, x, iconY, row.level); } @@ -143,10 +148,11 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { } } - private void drawIcon(GuiGraphics graphics, int x, int y, String key) { + private void drawIcon(GuiGraphics graphics, int x, int y, String key, Component text) { IconAtlas.IconSprite sprite = IconAtlas.get(key); float scale = iconSize / (float) IconAtlas.ICON_SOURCE_SIZE; - //? if >=1.21 { + int color = resolveColor(text); + //? if >=1.21.6 { graphics.pose().pushMatrix(); graphics.pose().translate(x, y); graphics.pose().scale(scale, scale); @@ -155,8 +161,8 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { graphics.pose().translate(x, y, 0); graphics.pose().scale(scale, scale, 1.0f); *///?} - blit(graphics, 0, 0, sprite.u, sprite.v, sprite.size); - //? if >=1.21 { + blit(graphics, 0, 0, sprite.u, sprite.v, sprite.size, color); + //? if >=1.21.6 { graphics.pose().popMatrix(); //?} else { /*graphics.pose().popPose(); @@ -164,7 +170,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { } private void drawBadge(GuiGraphics graphics, Font font, int x, int y, int level) { - String text = levelToRoman(level); + String text = levelToString(level); if (text.isEmpty()) { return; } @@ -177,27 +183,44 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent { graphics.drawString(font, text, badgeX + 1, badgeY + 1, BADGE_TEXT, false); } - private static String levelToRoman(int level) { - return switch (level) { - case 1 -> "I"; - case 2 -> "II"; - case 3 -> "III"; - case 4 -> "IV"; - case 5 -> "V"; - case 6 -> "VI"; - case 7 -> "VII"; - case 8 -> "VIII"; - case 9 -> "IX"; - case 10 -> "X"; - default -> Integer.toString(level); - }; + private static String levelToString(int level) { + return Integer.toString(level); } - private static void blit(GuiGraphics graphics, int x, int y, int u, int v, int size) { - //? if >=1.21 { - graphics.blit(RenderPipelines.GUI_TEXTURED, IconAtlas.ATLAS, x, y, u, v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE); - //?} else { - /*graphics.blit(IconAtlas.ATLAS, x, y, 0, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE); + private static void blit(GuiGraphics graphics, int x, int y, int u, int v, int size, int color) { + //? if >=1.21.6 { + graphics.blit(RenderPipelines.GUI_TEXTURED, IconAtlas.ATLAS, x, y, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE, color); + //?} else if >=1.21.2 { + /*graphics.blit(RenderType::guiTextured, IconAtlas.ATLAS, x, y, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE, color); + *///?} else { + /*applyColor(graphics, color); + graphics.blit(IconAtlas.ATLAS, x, y, 0, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE); + resetColor(graphics); *///?} } + + private static int resolveColor(Component text) { + if (text == null) { + return 0xFFFFFFFF; + } + TextColor color = text.getStyle().getColor(); + if (color == null) { + return 0xFFFFFFFF; + } + return 0xFF000000 | color.getValue(); + } + + //? if <1.21.2 { + /*private static void applyColor(GuiGraphics graphics, int argb) { + float a = ((argb >>> 24) & 0xFF) / 255f; + float r = ((argb >>> 16) & 0xFF) / 255f; + float g = ((argb >>> 8) & 0xFF) / 255f; + float b = (argb & 0xFF) / 255f; + graphics.setColor(r, g, b, a); + } + + private static void resetColor(GuiGraphics graphics) { + graphics.setColor(1.0f, 1.0f, 1.0f, 1.0f); + } + *///?} } diff --git a/src/client/java/dev/dekin/iconsenhanced/client/TooltipAugmenter.java b/src/client/java/dev/dekin/iconsenhanced/client/TooltipAugmenter.java index 0ff9a88..b916f4a 100644 --- a/src/client/java/dev/dekin/iconsenhanced/client/TooltipAugmenter.java +++ b/src/client/java/dev/dekin/iconsenhanced/client/TooltipAugmenter.java @@ -3,7 +3,6 @@ package dev.dekin.iconsenhanced.client; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import dev.dekin.iconsenhanced.IconsEnhanced; @@ -21,6 +20,13 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +//? if >=1.21.6 { +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner; +//?} +//? if <1.21.6 { +/*import java.util.Optional; +*///?} import net.minecraft.network.chat.Component; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; @@ -31,18 +37,24 @@ public final class TooltipAugmenter { private static final EnchantSortLogic SORT_LOGIC = new EnchantSortLogic(); private static final ThreadLocal CAPTURE = ThreadLocal.withInitial(() -> Boolean.FALSE); private static final ThreadLocal CAPTURED_DATA = new ThreadLocal<>(); + private static final ThreadLocal SUPPRESS_VANILLA = ThreadLocal.withInitial(() -> Boolean.FALSE); + private static final ThreadLocal SAVED_HOVERED = new ThreadLocal<>(); + private static boolean LATE_REGISTERED = false; private TooltipAugmenter() { } public static void register() { - //? if >=1.21 { + //? if >=1.20.5 { ItemTooltipCallback.EVENT.register((stack, context, flag, lines) -> onTooltip(stack, lines)); //?} else { /*ItemTooltipCallback.EVENT.register((stack, context, lines) -> onTooltip(stack, lines)); *///?} TooltipComponentCallback.EVENT.register(data -> { + if (data instanceof CombinedTooltipData combined) { + return new CombinedTooltipComponent(combined); + } if (data instanceof EnchantTooltipData enchData) { return new EnchantTooltipComponent(enchData); } @@ -50,6 +62,44 @@ public final class TooltipAugmenter { }); } + public static void registerLate() { + if (LATE_REGISTERED) { + return; + } + LATE_REGISTERED = true; + //? if >=1.20.5 { + ItemTooltipCallback.EVENT.register((stack, context, flag, lines) -> suppressVanilla(lines)); + //?} else { + /*ItemTooltipCallback.EVENT.register((stack, context, lines) -> suppressVanilla(lines)); + *///?} + } + + public static void beforeRender(Screen screen, int mouseX, int mouseY) { + SUPPRESS_VANILLA.set(Boolean.FALSE); + SAVED_HOVERED.remove(); + + IconsEnhancedConfig config = ConfigManager.get(); + if (!config.tooltips.enabled || !config.tooltips.showIcons) { + return; + } + if (!(screen instanceof AbstractContainerScreen handled)) { + return; + } + + Slot hovered = findHoveredSlot(handled, mouseX, mouseY); + if (hovered == null || hovered.getItem().isEmpty()) { + return; + } + + SAVED_HOVERED.set(hovered); + SUPPRESS_VANILLA.set(Boolean.TRUE); + } + + public static void afterRender(Screen screen) { + SAVED_HOVERED.remove(); + SUPPRESS_VANILLA.remove(); + } + public static void renderOverlay(Screen screen, GuiGraphics graphics, int mouseX, int mouseY) { IconsEnhancedConfig config = ConfigManager.get(); if (!config.tooltips.enabled || !config.tooltips.showIcons) { @@ -59,7 +109,10 @@ public final class TooltipAugmenter { return; } - Slot hovered = findHoveredSlot(handled, mouseX, mouseY); + Slot hovered = SAVED_HOVERED.get(); + if (hovered == null) { + hovered = findHoveredSlot(handled, mouseX, mouseY); + } if (hovered == null) { return; } @@ -70,26 +123,47 @@ public final class TooltipAugmenter { Minecraft client = Minecraft.getInstance(); List lines; - EnchantTooltipData data; + EnchantTooltipData data = null; + TooltipComponent baseData = stack.getTooltipImage().orElse(null); try { CAPTURE.set(Boolean.TRUE); CAPTURED_DATA.remove(); lines = Screen.getTooltipFromItem(client, stack); - data = CAPTURED_DATA.get(); + if (config.tooltips.showIcons) { + data = CAPTURED_DATA.get(); + } } finally { CAPTURE.remove(); CAPTURED_DATA.remove(); } - if (data == null) { - return; + //? if >=1.21.6 { + graphics.nextStratum(); + List components = new ArrayList<>(lines.size() + (data == null ? 0 : 1)); + for (Component line : lines) { + components.add(ClientTooltipComponent.create(line.getVisualOrderText())); } - - Optional tooltipData = Optional.of(data); - //? if >=1.21 { - graphics.setTooltipForNextFrame(client.font, lines, tooltipData, mouseX, mouseY); + if (data != null) { + ClientTooltipComponent custom = TooltipComponentCallback.EVENT.invoker().getComponent(data); + if (custom != null) { + components.add(custom); + } + } + if (baseData != null && baseData != data) { + components.add(ClientTooltipComponent.create(baseData)); + } + graphics.renderTooltip(client.font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null); //?} else { - /*graphics.renderTooltip(client.font, lines, tooltipData, mouseX, mouseY); + /*TooltipComponent combined; + if (data == null) { + combined = baseData; + } else if (baseData == null || baseData == data) { + combined = data; + } else { + combined = new CombinedTooltipData(data, baseData); + } + Optional tooltipData = combined == null ? Optional.empty() : Optional.of(combined); + graphics.renderTooltip(client.font, lines, tooltipData, mouseX, mouseY); *///?} } @@ -99,6 +173,10 @@ public final class TooltipAugmenter { if (!config.tooltips.enabled) { return; } + if (!Boolean.TRUE.equals(CAPTURE.get()) && Boolean.TRUE.equals(SUPPRESS_VANILLA.get())) { + lines.clear(); + return; + } List entries = ADAPTER.getEnchantments(stack); if (entries.isEmpty()) { @@ -111,11 +189,20 @@ public final class TooltipAugmenter { } List sorted = SORT_LOGIC.sort(entries, config.tooltips); + //? if >=1.21.9 { + boolean shiftDown = Minecraft.getInstance().hasShiftDown(); + //?} else { + /*boolean shiftDown = Screen.hasShiftDown();*/ + //?} + boolean hasDescriptions = config.tooltips.showDescriptions && hasAnyDescriptions(sorted); if (Boolean.TRUE.equals(CAPTURE.get()) && config.tooltips.showIcons) { - EnchantTooltipData data = buildTooltipData(sorted, config.tooltips); + EnchantTooltipData data = buildTooltipData(sorted, config.tooltips, shiftDown); CAPTURED_DATA.set(data); block.remove(lines); + if (hasDescriptions && !shiftDown) { + lines.add(block.start, TooltipTextUtil.getShiftHint()); + } return; } @@ -124,43 +211,69 @@ public final class TooltipAugmenter { } List ordered = config.tooltips.reorderEnchantments ? sorted : entries; - List replacement = buildTextLines(ordered, config.tooltips.showDescriptions); + List replacement = buildTextLines(ordered, config.tooltips.showDescriptions, shiftDown); + if (hasDescriptions && !shiftDown) { + replacement.add(TooltipTextUtil.getShiftHint()); + } block.replace(lines, replacement); } catch (Exception e) { IconsEnhanced.LOGGER.warn("Tooltip augmentation failed.", e); } } - private static EnchantTooltipData buildTooltipData(List entries, IconsEnhancedConfig.Tooltips tooltips) { - List rows = new ArrayList<>(); - for (EnchEntry entry : entries) { - List desc = tooltips.showDescriptions - ? TooltipTextUtil.getDescriptionLines(entry.descKey) - : List.of(); - rows.add(new TooltipLayoutModel.Row(entry.displayName, desc, entry.iconKey, entry.level, entry.isCurse)); + private static void suppressVanilla(List lines) { + if (!Boolean.TRUE.equals(CAPTURE.get()) && Boolean.TRUE.equals(SUPPRESS_VANILLA.get())) { + lines.clear(); } - return new EnchantTooltipData(new TooltipLayoutModel(rows), tooltips.iconSize, tooltips.showLevelBadge); } - private static List buildTextLines(List entries, boolean showDescriptions) { + private static EnchantTooltipData buildTooltipData(List entries, IconsEnhancedConfig.Tooltips tooltips, boolean shiftDown) { + List rows = new ArrayList<>(); + boolean showDescriptions = tooltips.showDescriptions && shiftDown; + boolean numericLevels = true; + for (EnchEntry entry : entries) { + Component name = numericLevels + ? TooltipTextUtil.withNumericLevel(entry.baseName, entry.level) + : entry.displayName; + List desc = showDescriptions + ? TooltipTextUtil.getDescriptionLines(entry.descKey) + : List.of(); + rows.add(new TooltipLayoutModel.Row(name, desc, entry.iconKey, entry.level, entry.isCurse)); + } + boolean showBadge = tooltips.showLevelBadge && !numericLevels; + return new EnchantTooltipData(new TooltipLayoutModel(rows), tooltips.iconSize, showBadge); + } + + private static List buildTextLines(List entries, boolean showDescriptions, boolean shiftDown) { List lines = new ArrayList<>(); for (EnchEntry entry : entries) { lines.add(entry.displayName); - if (showDescriptions) { + if (showDescriptions && shiftDown) { lines.addAll(TooltipTextUtil.getDescriptionLines(entry.descKey)); } } return lines; } + private static boolean hasAnyDescriptions(List entries) { + for (EnchEntry entry : entries) { + if (TooltipTextUtil.hasDescription(entry.descKey)) { + return true; + } + } + return false; + } + private static Slot findHoveredSlot(AbstractContainerScreen screen, int mouseX, int mouseY) { AbstractContainerScreenAccessor accessor = (AbstractContainerScreenAccessor) screen; int left = accessor.iconsenhanced$getLeftPos(); int top = accessor.iconsenhanced$getTopPos(); + double relX = mouseX - left; + double relY = mouseY - top; for (Slot slot : screen.getMenu().slots) { - int sx = left + slot.x; - int sy = top + slot.y; - if (mouseX >= sx && mouseX < sx + 16 && mouseY >= sy && mouseY < sy + 16) { + int sx = slot.x; + int sy = slot.y; + if (relX >= sx - 1 && relX < sx + 17 && relY >= sy - 1 && relY < sy + 17) { return slot; } } diff --git a/src/client/java/dev/dekin/iconsenhanced/client/TooltipTextUtil.java b/src/client/java/dev/dekin/iconsenhanced/client/TooltipTextUtil.java index 038401b..bde483a 100644 --- a/src/client/java/dev/dekin/iconsenhanced/client/TooltipTextUtil.java +++ b/src/client/java/dev/dekin/iconsenhanced/client/TooltipTextUtil.java @@ -13,6 +13,7 @@ import net.minecraft.network.chat.Style; public final class TooltipTextUtil { private static final Map> CACHE = new HashMap<>(); private static final Style DESCRIPTION_STYLE = Style.EMPTY; + private static final Style HINT_STYLE = Style.EMPTY.withColor(0xAAAAAA); private TooltipTextUtil() { } @@ -27,6 +28,25 @@ public final class TooltipTextUtil { return CACHE.computeIfAbsent(key, TooltipTextUtil::splitLines); } + public static boolean hasDescription(String key) { + if (key == null || key.isBlank()) { + return false; + } + return I18n.exists(key); + } + + public static Component getShiftHint() { + return Component.translatable("iconsenhanced.tooltip.shift").setStyle(HINT_STYLE); + } + + public static Component withNumericLevel(Component baseName, int level) { + if (baseName == null) { + return Component.literal(Integer.toString(level)); + } + Component number = Component.literal(" " + level).setStyle(baseName.getStyle()); + return baseName.copy().append(number); + } + private static List splitLines(String key) { String text = I18n.get(key); if (text == null || text.isEmpty()) { diff --git a/src/client/java/dev/dekin/iconsenhanced/mixin/AbstractContainerScreenAccessor.java b/src/client/java/dev/dekin/iconsenhanced/mixin/AbstractContainerScreenAccessor.java index d06e0c1..9c60fbe 100644 --- a/src/client/java/dev/dekin/iconsenhanced/mixin/AbstractContainerScreenAccessor.java +++ b/src/client/java/dev/dekin/iconsenhanced/mixin/AbstractContainerScreenAccessor.java @@ -1,6 +1,7 @@ package dev.dekin.iconsenhanced.mixin; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.world.inventory.Slot; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @@ -11,4 +12,10 @@ public interface AbstractContainerScreenAccessor { @Accessor("topPos") int iconsenhanced$getTopPos(); + + @Accessor("hoveredSlot") + Slot iconsenhanced$getHoveredSlot(); + + @Accessor("hoveredSlot") + void iconsenhanced$setHoveredSlot(Slot slot); } diff --git a/src/main/java/dev/dekin/iconsenhanced/adapters/DefaultEnchantmentAdapter.java b/src/main/java/dev/dekin/iconsenhanced/adapters/DefaultEnchantmentAdapter.java index 432bad8..2b9f0cc 100644 --- a/src/main/java/dev/dekin/iconsenhanced/adapters/DefaultEnchantmentAdapter.java +++ b/src/main/java/dev/dekin/iconsenhanced/adapters/DefaultEnchantmentAdapter.java @@ -3,7 +3,7 @@ package dev.dekin.iconsenhanced.adapters; import java.util.ArrayList; import java.util.Collections; import java.util.List; -//? if <1.21 { +//? if <1.20.5 { /*import java.util.Map; *///?} @@ -12,17 +12,20 @@ import dev.dekin.iconsenhanced.common.EnchEntry; import dev.dekin.iconsenhanced.common.IconKeyResolver; import dev.dekin.iconsenhanced.common.IconKeyResolver.Visual; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.Enchantment; -//? if <1.21 { +//? if <1.20.5 { /*import net.minecraft.core.registries.BuiltInRegistries; *///?} -//? if >=1.21 { +//? if >=1.20.5 { import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.Holder; import net.minecraft.core.component.DataComponents; -import net.minecraft.tags.EnchantmentTags; import net.minecraft.world.item.enchantment.ItemEnchantments; +//? if >=1.21 { +import net.minecraft.tags.EnchantmentTags; +//?} //?} else { /*import net.minecraft.nbt.ListTag; import net.minecraft.world.item.EnchantedBookItem; @@ -38,7 +41,7 @@ public final class DefaultEnchantmentAdapter implements EnchantmentAdapter { List entries = new ArrayList<>(); - //? if >=1.21 { + //? if >=1.20.5 { appendEntries(entries, stack.getEnchantments()); ItemEnchantments stored = stack.get(DataComponents.STORED_ENCHANTMENTS); if (stored != null && !stored.isEmpty()) { @@ -59,7 +62,7 @@ public final class DefaultEnchantmentAdapter implements EnchantmentAdapter { return entries; } - //? if >=1.21 { + //? if >=1.20.5 { private static void appendEntries(List entries, ItemEnchantments enchantments) { if (enchantments == null || enchantments.isEmpty()) { return; @@ -67,14 +70,22 @@ public final class DefaultEnchantmentAdapter implements EnchantmentAdapter { for (Object2IntMap.Entry> entry : enchantments.entrySet()) { Holder holder = entry.getKey(); int level = entry.getIntValue(); - String id = holder.unwrapKey() - .map(key -> key.identifier().toString()) - .orElse(""); + String id = holderId(holder); + //? if >=1.21 { + Enchantment enchantment = holder.value(); boolean isCurse = holder.is(EnchantmentTags.CURSE); Visual visual = IconKeyResolver.resolve(id, isCurse); + Component baseName = colorize(enchantment.description(), visual.color); Component name = colorize(Enchantment.getFullname(holder, level), visual.color); + //?} else { + /*Enchantment enchantment = holder.value(); + boolean isCurse = enchantment.isCurse(); + Visual visual = IconKeyResolver.resolve(id, isCurse); + Component baseName = colorize(Component.translatable(enchantment.getDescriptionId()), visual.color); + Component name = colorize(enchantment.getFullname(level), visual.color); + *///?} String descKey = buildDescKey(id); - entries.add(new EnchEntry(id, level, name, isCurse, visual.iconKey, descKey)); + entries.add(new EnchEntry(id, level, name, baseName, isCurse, visual.iconKey, descKey)); } } //?} else { @@ -88,9 +99,10 @@ public final class DefaultEnchantmentAdapter implements EnchantmentAdapter { String id = BuiltInRegistries.ENCHANTMENT.getKey(enchantment).toString(); boolean isCurse = enchantment.isCurse(); Visual visual = IconKeyResolver.resolve(id, isCurse); + Component baseName = colorize(Component.translatable(enchantment.getDescriptionId()), visual.color); Component name = colorize(enchantment.getFullname(level), visual.color); String descKey = buildDescKey(id); - entries.add(new EnchEntry(id, level, name, isCurse, visual.iconKey, descKey)); + entries.add(new EnchEntry(id, level, name, baseName, isCurse, visual.iconKey, descKey)); } } *///?} @@ -114,4 +126,23 @@ public final class DefaultEnchantmentAdapter implements EnchantmentAdapter { } return name.copy().withStyle(style -> style.withColor(color)); } + + //? if >=1.20.5 { + private static String holderId(Holder holder) { + //? if >=1.21.11 { + java.util.Optional keyOpt = holder.unwrapKey(); + if (keyOpt.isPresent()) { + Object raw = keyOpt.get(); + if (raw instanceof ResourceKey key) { + return key.identifier().toString(); + } + } + return ""; + //?} else { + /*return holder.unwrapKey() + .map(key -> key.location().toString()) + .orElse(""); + *///?} + } + //?} } diff --git a/src/main/java/dev/dekin/iconsenhanced/common/EnchEntry.java b/src/main/java/dev/dekin/iconsenhanced/common/EnchEntry.java index 594a574..9cc95ab 100644 --- a/src/main/java/dev/dekin/iconsenhanced/common/EnchEntry.java +++ b/src/main/java/dev/dekin/iconsenhanced/common/EnchEntry.java @@ -9,18 +9,22 @@ public final class EnchEntry { public final int level; public final Component displayName; public final String displayNameString; + public final Component baseName; + public final String baseNameString; public final boolean isCurse; public final String iconKey; public final String descKey; - public EnchEntry(String id, int level, Component displayName, boolean isCurse, String iconKey, String descKey) { + public EnchEntry(String id, int level, Component displayName, Component baseName, boolean isCurse, String iconKey, String descKey) { this.id = id == null ? "" : id; IdParts parts = IdParts.parse(this.id); this.namespace = parts.namespace; this.path = parts.path; this.level = level; this.displayName = displayName; - this.displayNameString = displayName.getString(); + this.displayNameString = displayName == null ? "" : displayName.getString(); + this.baseName = baseName == null ? displayName : baseName; + this.baseNameString = this.baseName == null ? "" : this.baseName.getString(); this.isCurse = isCurse; this.iconKey = iconKey; this.descKey = descKey; diff --git a/src/main/java/dev/dekin/iconsenhanced/common/EnchantSortLogic.java b/src/main/java/dev/dekin/iconsenhanced/common/EnchantSortLogic.java index f5f3bb7..b4e361b 100644 --- a/src/main/java/dev/dekin/iconsenhanced/common/EnchantSortLogic.java +++ b/src/main/java/dev/dekin/iconsenhanced/common/EnchantSortLogic.java @@ -17,9 +17,9 @@ public final class EnchantSortLogic { private static Comparator buildComparator(IconsEnhancedConfig.Tooltips tooltips) { Comparator base = switch (SortMode.fromString(tooltips.sortMode)) { - case BY_NAME -> Comparator.comparing(entry -> entry.displayNameString.toLowerCase(Locale.ROOT)); + case BY_NAME -> Comparator.comparing(entry -> entry.baseNameString.toLowerCase(Locale.ROOT)); case BY_LEVEL_DESC -> Comparator.comparingInt(entry -> entry.level).reversed() - .thenComparing(entry -> entry.displayNameString.toLowerCase(Locale.ROOT)); + .thenComparing(entry -> entry.baseNameString.toLowerCase(Locale.ROOT)); case CUSTOM_PRIORITY_LIST -> customPriorityComparator(tooltips.customPriorityList); case BY_VANILLA_LIKE -> Comparator .comparing((EnchEntry entry) -> entry.namespace) @@ -39,7 +39,7 @@ public final class EnchantSortLogic { } return Comparator .comparingInt((EnchEntry entry) -> priority.getOrDefault(entry.id, Integer.MAX_VALUE)) - .thenComparing(entry -> entry.displayNameString.toLowerCase(Locale.ROOT)); + .thenComparing(entry -> entry.baseNameString.toLowerCase(Locale.ROOT)); } public enum SortMode { diff --git a/src/main/java/dev/dekin/iconsenhanced/common/IconAtlas.java b/src/main/java/dev/dekin/iconsenhanced/common/IconAtlas.java index a259e6e..2579b5a 100644 --- a/src/main/java/dev/dekin/iconsenhanced/common/IconAtlas.java +++ b/src/main/java/dev/dekin/iconsenhanced/common/IconAtlas.java @@ -4,16 +4,18 @@ import java.util.HashMap; import java.util.Map; import dev.dekin.iconsenhanced.IconsEnhanced; -//? if >=1.21 { +//? if >=1.21.11 { import net.minecraft.resources.Identifier; //?} else { /*import net.minecraft.resources.ResourceLocation; *///?} public final class IconAtlas { - //? if >=1.21 { + //? if >=1.21.11 { public static final Identifier ATLAS = Identifier.fromNamespaceAndPath(IconsEnhanced.MOD_ID, "textures/gui/enchant_icons.png"); - //?} else { + //?} else if >=1.21 { + /*public static final ResourceLocation ATLAS = ResourceLocation.fromNamespaceAndPath(IconsEnhanced.MOD_ID, "textures/gui/enchant_icons.png"); + *///?} else { /*public static final ResourceLocation ATLAS = new ResourceLocation(IconsEnhanced.MOD_ID, "textures/gui/enchant_icons.png"); *///?} public static final int ICON_SOURCE_SIZE = 16; diff --git a/src/main/resources/assets/iconsenhanced/lang/de_de.json b/src/main/resources/assets/iconsenhanced/lang/de_de.json new file mode 100644 index 0000000..eb53e8a --- /dev/null +++ b/src/main/resources/assets/iconsenhanced/lang/de_de.json @@ -0,0 +1,45 @@ +{ + "iconsenhanced.tooltip.shift": "Halte Shift für Details.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Erhöht die Abbaugeschwindigkeit unter Wasser.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Erhöht den Schaden gegen Arthropoden und verlangsamt sie.", + "iconsenhanced.desc.minecraft.binding_curse": "Verflucht: kann nicht entfernt werden.", + "iconsenhanced.desc.minecraft.blast_protection": "Verringert Explosionsschaden und Rückstoß.", + "iconsenhanced.desc.minecraft.breach": "Angriffe mit dem Streitkolben ignorieren einen Teil der Rüstung.", + "iconsenhanced.desc.minecraft.channeling": "Beschwört Blitz während eines Gewitters.", + "iconsenhanced.desc.minecraft.density": "Erhöht den Aufprallschaden des Streitkolbens.", + "iconsenhanced.desc.minecraft.depth_strider": "Erhöht die Bewegungsgeschwindigkeit unter Wasser.", + "iconsenhanced.desc.minecraft.efficiency": "Erhöht die Abbaugeschwindigkeit.", + "iconsenhanced.desc.minecraft.feather_falling": "Verringert Fallschaden.", + "iconsenhanced.desc.minecraft.fire_aspect": "Setzt Ziele in Brand.", + "iconsenhanced.desc.minecraft.fire_protection": "Verringert Schaden durch Feuer und Lava.", + "iconsenhanced.desc.minecraft.flame": "Pfeile setzen Ziele in Brand.", + "iconsenhanced.desc.minecraft.fortune": "Erhöht die Menge an Blockdrops.", + "iconsenhanced.desc.minecraft.frost_walker": "Gefriert Wasser zu Eis.", + "iconsenhanced.desc.minecraft.impaling": "Erhöht Schaden gegen Wasserwesen.", + "iconsenhanced.desc.minecraft.infinity": "Pfeile werden nicht verbraucht.", + "iconsenhanced.desc.minecraft.knockback": "Erhöht Rückstoß.", + "iconsenhanced.desc.minecraft.looting": "Erhöht die Beute von Kreaturen.", + "iconsenhanced.desc.minecraft.loyalty": "Der Dreizack kehrt nach dem Wurf zurück.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Erhöht die Chance auf Schätze beim Angeln.", + "iconsenhanced.desc.minecraft.lure": "Erhöht die Bissrate.", + "iconsenhanced.desc.minecraft.mending": "Repariert Gegenstände mit Erfahrung.", + "iconsenhanced.desc.minecraft.multishot": "Schießt 3 Pfeile gleichzeitig.", + "iconsenhanced.desc.minecraft.piercing": "Pfeile durchbohren Ziele.", + "iconsenhanced.desc.minecraft.power": "Erhöht den Schaden des Bogens.", + "iconsenhanced.desc.minecraft.projectile_protection": "Verringert Projektilschaden.", + "iconsenhanced.desc.minecraft.protection": "Verringert den meisten Schaden.", + "iconsenhanced.desc.minecraft.punch": "Erhöht Rückstoß der Pfeile.", + "iconsenhanced.desc.minecraft.quick_charge": "Verringert die Ladezeit der Armbrust.", + "iconsenhanced.desc.minecraft.respiration": "Verlängert die Zeit unter Wasser zu atmen.", + "iconsenhanced.desc.minecraft.riptide": "Schleudert dich im Wasser oder Regen vorwärts.", + "iconsenhanced.desc.minecraft.sharpness": "Erhöht Nahkampfschaden.", + "iconsenhanced.desc.minecraft.silk_touch": "Abgebaute Blöcke fallen wie sie sind.", + "iconsenhanced.desc.minecraft.smite": "Erhöht Schaden gegen Untote.", + "iconsenhanced.desc.minecraft.soul_speed": "Erhöht die Geschwindigkeit auf Seelensand und Seelenerde.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Erhöht den Schaden des Schwungangriffs.", + "iconsenhanced.desc.minecraft.swift_sneak": "Erhöht die Geschwindigkeit beim Schleichen.", + "iconsenhanced.desc.minecraft.thorns": "Reflektiert Schaden auf Angreifer.", + "iconsenhanced.desc.minecraft.unbreaking": "Gegenstände verlieren Haltbarkeit langsamer.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Verflucht: verschwindet beim Tod.", + "iconsenhanced.desc.minecraft.wind_burst": "Erzeugt eine Windböe nach einem Aufprall." +} diff --git a/src/main/resources/assets/iconsenhanced/lang/en_us.json b/src/main/resources/assets/iconsenhanced/lang/en_us.json index db99b81..8145dce 100644 --- a/src/main/resources/assets/iconsenhanced/lang/en_us.json +++ b/src/main/resources/assets/iconsenhanced/lang/en_us.json @@ -1,11 +1,45 @@ { - "iconsenhanced.desc.minecraft.sharpness": "Increases melee damage.", - "iconsenhanced.desc.minecraft.protection": "Reduces incoming damage.", - "iconsenhanced.desc.minecraft.unbreaking": "Items lose durability slower.", - "iconsenhanced.desc.minecraft.mending": "Repairs items with experience.", + "iconsenhanced.tooltip.shift": "Hold Shift for details.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Increases underwater mining speed.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Increases damage to arthropods and slows them.", + "iconsenhanced.desc.minecraft.binding_curse": "Cursed: cannot be removed.", + "iconsenhanced.desc.minecraft.blast_protection": "Reduces explosion damage and knockback.", + "iconsenhanced.desc.minecraft.breach": "Mace attacks ignore some armor.", + "iconsenhanced.desc.minecraft.channeling": "Summons lightning during thunderstorms.", + "iconsenhanced.desc.minecraft.density": "Increases mace smash damage.", + "iconsenhanced.desc.minecraft.depth_strider": "Increases underwater movement speed.", "iconsenhanced.desc.minecraft.efficiency": "Increases mining speed.", + "iconsenhanced.desc.minecraft.feather_falling": "Reduces fall damage.", + "iconsenhanced.desc.minecraft.fire_aspect": "Sets targets on fire.", + "iconsenhanced.desc.minecraft.fire_protection": "Reduces fire and lava damage.", + "iconsenhanced.desc.minecraft.flame": "Arrows ignite targets.", + "iconsenhanced.desc.minecraft.fortune": "Increases block drop quantity.", + "iconsenhanced.desc.minecraft.frost_walker": "Freezes water into ice.", + "iconsenhanced.desc.minecraft.impaling": "Increases damage to aquatic mobs.", + "iconsenhanced.desc.minecraft.infinity": "Arrows can be shot without consuming them.", + "iconsenhanced.desc.minecraft.knockback": "Increases knockback dealt.", + "iconsenhanced.desc.minecraft.looting": "Increases mob loot drops.", + "iconsenhanced.desc.minecraft.loyalty": "Trident returns after throwing.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Increases chance of treasure fishing.", + "iconsenhanced.desc.minecraft.lure": "Increases bite rate when fishing.", + "iconsenhanced.desc.minecraft.mending": "Repairs items with experience.", + "iconsenhanced.desc.minecraft.multishot": "Shoots 3 arrows at once.", + "iconsenhanced.desc.minecraft.piercing": "Arrows pierce through targets.", "iconsenhanced.desc.minecraft.power": "Increases bow damage.", + "iconsenhanced.desc.minecraft.projectile_protection": "Reduces projectile damage.", + "iconsenhanced.desc.minecraft.protection": "Reduces most damage.", + "iconsenhanced.desc.minecraft.punch": "Increases arrow knockback.", + "iconsenhanced.desc.minecraft.quick_charge": "Reduces crossbow charge time.", + "iconsenhanced.desc.minecraft.respiration": "Extends underwater breathing time.", + "iconsenhanced.desc.minecraft.riptide": "Launches you in water or rain.", + "iconsenhanced.desc.minecraft.sharpness": "Increases melee damage.", + "iconsenhanced.desc.minecraft.silk_touch": "Mined blocks drop themselves.", + "iconsenhanced.desc.minecraft.smite": "Increases damage to undead.", + "iconsenhanced.desc.minecraft.soul_speed": "Increases speed on soul sand and soul soil.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Increases sweeping attack damage.", + "iconsenhanced.desc.minecraft.swift_sneak": "Increases sneaking speed.", "iconsenhanced.desc.minecraft.thorns": "Reflects damage to attackers.", - "iconsenhanced.desc.minecraft.binding_curse": "Cursed: stays equipped.", - "iconsenhanced.desc.minecraft.vanishing_curse": "Cursed: disappears on death." + "iconsenhanced.desc.minecraft.unbreaking": "Items lose durability slower.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Cursed: disappears on death.", + "iconsenhanced.desc.minecraft.wind_burst": "Creates a wind burst after smashing." } diff --git a/src/main/resources/assets/iconsenhanced/lang/es_es.json b/src/main/resources/assets/iconsenhanced/lang/es_es.json index 6812a6a..3e5bc78 100644 --- a/src/main/resources/assets/iconsenhanced/lang/es_es.json +++ b/src/main/resources/assets/iconsenhanced/lang/es_es.json @@ -1,11 +1,45 @@ { - "iconsenhanced.desc.minecraft.sharpness": "Aumenta el dano cuerpo a cuerpo.", - "iconsenhanced.desc.minecraft.protection": "Reduce el dano recibido.", - "iconsenhanced.desc.minecraft.unbreaking": "Los objetos pierden durabilidad mas lento.", - "iconsenhanced.desc.minecraft.mending": "Repara objetos con experiencia.", + "iconsenhanced.tooltip.shift": "Manten Shift para ver detalles.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Aumenta la velocidad de minado bajo el agua.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Aumenta el dano a artropodos y los ralentiza.", + "iconsenhanced.desc.minecraft.binding_curse": "Maldito: no se puede quitar.", + "iconsenhanced.desc.minecraft.blast_protection": "Reduce el dano y empuje de explosiones.", + "iconsenhanced.desc.minecraft.breach": "Los golpes del mazo ignoran armadura.", + "iconsenhanced.desc.minecraft.channeling": "Invoca rayos en tormenta.", + "iconsenhanced.desc.minecraft.density": "Aumenta el dano del golpe aplastante.", + "iconsenhanced.desc.minecraft.depth_strider": "Aumenta la velocidad bajo el agua.", "iconsenhanced.desc.minecraft.efficiency": "Aumenta la velocidad de mineria.", + "iconsenhanced.desc.minecraft.feather_falling": "Reduce el dano de caida.", + "iconsenhanced.desc.minecraft.fire_aspect": "Prende fuego a los objetivos.", + "iconsenhanced.desc.minecraft.fire_protection": "Reduce el dano de fuego y lava.", + "iconsenhanced.desc.minecraft.flame": "Las flechas prenden fuego.", + "iconsenhanced.desc.minecraft.fortune": "Aumenta la cantidad de drops.", + "iconsenhanced.desc.minecraft.frost_walker": "Congela el agua en hielo.", + "iconsenhanced.desc.minecraft.impaling": "Aumenta el dano a mobs acuaticos.", + "iconsenhanced.desc.minecraft.infinity": "Dispara flechas sin consumir.", + "iconsenhanced.desc.minecraft.knockback": "Aumenta el empuje.", + "iconsenhanced.desc.minecraft.looting": "Aumenta el botin de mobs.", + "iconsenhanced.desc.minecraft.loyalty": "El tridente vuelve al lanzarlo.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Aumenta la suerte al pescar.", + "iconsenhanced.desc.minecraft.lure": "Aumenta la velocidad de picada.", + "iconsenhanced.desc.minecraft.mending": "Repara objetos con experiencia.", + "iconsenhanced.desc.minecraft.multishot": "Dispara 3 flechas a la vez.", + "iconsenhanced.desc.minecraft.piercing": "Las flechas atraviesan objetivos.", "iconsenhanced.desc.minecraft.power": "Aumenta el dano del arco.", + "iconsenhanced.desc.minecraft.projectile_protection": "Reduce el dano de proyectiles.", + "iconsenhanced.desc.minecraft.protection": "Reduce la mayoria del dano.", + "iconsenhanced.desc.minecraft.punch": "Aumenta el empuje de las flechas.", + "iconsenhanced.desc.minecraft.quick_charge": "Reduce el tiempo de carga.", + "iconsenhanced.desc.minecraft.respiration": "Aumenta el tiempo de respiracion bajo el agua.", + "iconsenhanced.desc.minecraft.riptide": "Te lanza en agua o lluvia.", + "iconsenhanced.desc.minecraft.sharpness": "Aumenta el dano cuerpo a cuerpo.", + "iconsenhanced.desc.minecraft.silk_touch": "Los bloques se sueltan tal cual.", + "iconsenhanced.desc.minecraft.smite": "Aumenta el dano a no muertos.", + "iconsenhanced.desc.minecraft.soul_speed": "Aumenta la velocidad en arena de almas y suelo de almas.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Aumenta el dano del barrido.", + "iconsenhanced.desc.minecraft.swift_sneak": "Aumenta la velocidad al agacharse.", "iconsenhanced.desc.minecraft.thorns": "Refleja dano a atacantes.", - "iconsenhanced.desc.minecraft.binding_curse": "Maldito: queda equipado.", - "iconsenhanced.desc.minecraft.vanishing_curse": "Maldito: desaparece al morir." + "iconsenhanced.desc.minecraft.unbreaking": "Los objetos pierden durabilidad mas lento.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Maldito: desaparece al morir.", + "iconsenhanced.desc.minecraft.wind_burst": "Crea una rafaga tras aplastar." } diff --git a/src/main/resources/assets/iconsenhanced/lang/fr_fr.json b/src/main/resources/assets/iconsenhanced/lang/fr_fr.json new file mode 100644 index 0000000..2a4175e --- /dev/null +++ b/src/main/resources/assets/iconsenhanced/lang/fr_fr.json @@ -0,0 +1,45 @@ +{ + "iconsenhanced.tooltip.shift": "Maintenez Maj pour les détails.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Augmente la vitesse de minage sous l'eau.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Augmente les dégâts aux arthropodes et les ralentit.", + "iconsenhanced.desc.minecraft.binding_curse": "Maudit : ne peut pas être retiré.", + "iconsenhanced.desc.minecraft.blast_protection": "Réduit les dégâts et le recul des explosions.", + "iconsenhanced.desc.minecraft.breach": "Les attaques de masse ignorent une partie de l'armure.", + "iconsenhanced.desc.minecraft.channeling": "Invoque la foudre pendant les orages.", + "iconsenhanced.desc.minecraft.density": "Augmente les dégâts de l'impact de la masse.", + "iconsenhanced.desc.minecraft.depth_strider": "Augmente la vitesse de déplacement sous l'eau.", + "iconsenhanced.desc.minecraft.efficiency": "Augmente la vitesse de minage.", + "iconsenhanced.desc.minecraft.feather_falling": "Réduit les dégâts de chute.", + "iconsenhanced.desc.minecraft.fire_aspect": "Enflamme les cibles.", + "iconsenhanced.desc.minecraft.fire_protection": "Réduit les dégâts de feu et de lave.", + "iconsenhanced.desc.minecraft.flame": "Les flèches enflamment les cibles.", + "iconsenhanced.desc.minecraft.fortune": "Augmente la quantité de butin des blocs.", + "iconsenhanced.desc.minecraft.frost_walker": "Gèle l'eau en glace.", + "iconsenhanced.desc.minecraft.impaling": "Augmente les dégâts contre les créatures aquatiques.", + "iconsenhanced.desc.minecraft.infinity": "Tire des flèches sans en consommer.", + "iconsenhanced.desc.minecraft.knockback": "Augmente le recul infligé.", + "iconsenhanced.desc.minecraft.looting": "Augmente le butin des créatures.", + "iconsenhanced.desc.minecraft.loyalty": "Le trident revient après le lancer.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Augmente les chances de trésors à la pêche.", + "iconsenhanced.desc.minecraft.lure": "Augmente la vitesse de morsure.", + "iconsenhanced.desc.minecraft.mending": "Répare les objets avec l'expérience.", + "iconsenhanced.desc.minecraft.multishot": "Tire 3 flèches à la fois.", + "iconsenhanced.desc.minecraft.piercing": "Les flèches percent les cibles.", + "iconsenhanced.desc.minecraft.power": "Augmente les dégâts de l'arc.", + "iconsenhanced.desc.minecraft.projectile_protection": "Réduit les dégâts de projectiles.", + "iconsenhanced.desc.minecraft.protection": "Réduit la plupart des dégâts.", + "iconsenhanced.desc.minecraft.punch": "Augmente le recul des flèches.", + "iconsenhanced.desc.minecraft.quick_charge": "Réduit le temps de rechargement de l'arbalète.", + "iconsenhanced.desc.minecraft.respiration": "Prolonge la respiration sous l'eau.", + "iconsenhanced.desc.minecraft.riptide": "Vous propulse dans l'eau ou la pluie.", + "iconsenhanced.desc.minecraft.sharpness": "Augmente les dégâts au corps à corps.", + "iconsenhanced.desc.minecraft.silk_touch": "Les blocs minés se lâchent tels quels.", + "iconsenhanced.desc.minecraft.smite": "Augmente les dégâts contre les morts-vivants.", + "iconsenhanced.desc.minecraft.soul_speed": "Augmente la vitesse sur le sable des âmes et la terre des âmes.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Augmente les dégâts de balayage.", + "iconsenhanced.desc.minecraft.swift_sneak": "Augmente la vitesse en se faufilant.", + "iconsenhanced.desc.minecraft.thorns": "Renvoie des dégâts aux attaquants.", + "iconsenhanced.desc.minecraft.unbreaking": "Les objets perdent leur durabilité plus lentement.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Maudit : disparaît à la mort.", + "iconsenhanced.desc.minecraft.wind_burst": "Crée une rafale après un impact." +} diff --git a/src/main/resources/assets/iconsenhanced/lang/it_it.json b/src/main/resources/assets/iconsenhanced/lang/it_it.json new file mode 100644 index 0000000..8ec1a33 --- /dev/null +++ b/src/main/resources/assets/iconsenhanced/lang/it_it.json @@ -0,0 +1,45 @@ +{ + "iconsenhanced.tooltip.shift": "Tieni premuto Shift per i dettagli.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Aumenta la velocità di minare sott'acqua.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Aumenta i danni agli artropodi e li rallenta.", + "iconsenhanced.desc.minecraft.binding_curse": "Maledetto: non può essere rimosso.", + "iconsenhanced.desc.minecraft.blast_protection": "Riduce i danni e il contraccolpo delle esplosioni.", + "iconsenhanced.desc.minecraft.breach": "Gli attacchi della mazza ignorano parte dell'armatura.", + "iconsenhanced.desc.minecraft.channeling": "Evoca fulmini durante i temporali.", + "iconsenhanced.desc.minecraft.density": "Aumenta i danni dell'impatto della mazza.", + "iconsenhanced.desc.minecraft.depth_strider": "Aumenta la velocità di movimento sott'acqua.", + "iconsenhanced.desc.minecraft.efficiency": "Aumenta la velocità di minare.", + "iconsenhanced.desc.minecraft.feather_falling": "Riduce i danni da caduta.", + "iconsenhanced.desc.minecraft.fire_aspect": "Incendia i bersagli.", + "iconsenhanced.desc.minecraft.fire_protection": "Riduce i danni da fuoco e lava.", + "iconsenhanced.desc.minecraft.flame": "Le frecce incendiano i bersagli.", + "iconsenhanced.desc.minecraft.fortune": "Aumenta la quantità di drop dei blocchi.", + "iconsenhanced.desc.minecraft.frost_walker": "Gela l'acqua in ghiaccio.", + "iconsenhanced.desc.minecraft.impaling": "Aumenta i danni contro le creature acquatiche.", + "iconsenhanced.desc.minecraft.infinity": "Spara frecce senza consumarle.", + "iconsenhanced.desc.minecraft.knockback": "Aumenta il contraccolpo.", + "iconsenhanced.desc.minecraft.looting": "Aumenta il bottino delle creature.", + "iconsenhanced.desc.minecraft.loyalty": "Il tridente ritorna dopo il lancio.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Aumenta le probabilità di tesori pescando.", + "iconsenhanced.desc.minecraft.lure": "Aumenta la velocità di abboccata.", + "iconsenhanced.desc.minecraft.mending": "Ripara gli oggetti con l'esperienza.", + "iconsenhanced.desc.minecraft.multishot": "Spara 3 frecce in una volta.", + "iconsenhanced.desc.minecraft.piercing": "Le frecce perforano i bersagli.", + "iconsenhanced.desc.minecraft.power": "Aumenta i danni dell'arco.", + "iconsenhanced.desc.minecraft.projectile_protection": "Riduce i danni da proiettili.", + "iconsenhanced.desc.minecraft.protection": "Riduce la maggior parte dei danni.", + "iconsenhanced.desc.minecraft.punch": "Aumenta il contraccolpo delle frecce.", + "iconsenhanced.desc.minecraft.quick_charge": "Riduce il tempo di ricarica della balestra.", + "iconsenhanced.desc.minecraft.respiration": "Aumenta il tempo di respirazione sott'acqua.", + "iconsenhanced.desc.minecraft.riptide": "Ti lancia in acqua o sotto la pioggia.", + "iconsenhanced.desc.minecraft.sharpness": "Aumenta i danni in mischia.", + "iconsenhanced.desc.minecraft.silk_touch": "I blocchi minati cadono intatti.", + "iconsenhanced.desc.minecraft.smite": "Aumenta i danni contro i non morti.", + "iconsenhanced.desc.minecraft.soul_speed": "Aumenta la velocità su sabbia delle anime e terra delle anime.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Aumenta i danni dell'attacco in spazzata.", + "iconsenhanced.desc.minecraft.swift_sneak": "Aumenta la velocità mentre ti accovacci.", + "iconsenhanced.desc.minecraft.thorns": "Riflette danni agli attaccanti.", + "iconsenhanced.desc.minecraft.unbreaking": "Gli oggetti perdono durabilità più lentamente.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Maledetto: scompare alla morte.", + "iconsenhanced.desc.minecraft.wind_burst": "Crea una raffica dopo l'impatto." +} diff --git a/src/main/resources/assets/iconsenhanced/lang/pt_br.json b/src/main/resources/assets/iconsenhanced/lang/pt_br.json new file mode 100644 index 0000000..c0b659f --- /dev/null +++ b/src/main/resources/assets/iconsenhanced/lang/pt_br.json @@ -0,0 +1,45 @@ +{ + "iconsenhanced.tooltip.shift": "Segure Shift para ver detalhes.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Aumenta a velocidade de mineração debaixo d'água.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Aumenta o dano contra artrópodes e os desacelera.", + "iconsenhanced.desc.minecraft.binding_curse": "Amaldiçoado: não pode ser removido.", + "iconsenhanced.desc.minecraft.blast_protection": "Reduz o dano e o empurrão de explosões.", + "iconsenhanced.desc.minecraft.breach": "Ataques da maça ignoram parte da armadura.", + "iconsenhanced.desc.minecraft.channeling": "Invoca relâmpagos durante tempestades.", + "iconsenhanced.desc.minecraft.density": "Aumenta o dano do impacto da maça.", + "iconsenhanced.desc.minecraft.depth_strider": "Aumenta a velocidade de movimento debaixo d'água.", + "iconsenhanced.desc.minecraft.efficiency": "Aumenta a velocidade de mineração.", + "iconsenhanced.desc.minecraft.feather_falling": "Reduz o dano de queda.", + "iconsenhanced.desc.minecraft.fire_aspect": "Incendeia os alvos.", + "iconsenhanced.desc.minecraft.fire_protection": "Reduz o dano de fogo e lava.", + "iconsenhanced.desc.minecraft.flame": "Flechas incendeiam os alvos.", + "iconsenhanced.desc.minecraft.fortune": "Aumenta a quantidade de drops dos blocos.", + "iconsenhanced.desc.minecraft.frost_walker": "Congela água em gelo.", + "iconsenhanced.desc.minecraft.impaling": "Aumenta o dano contra criaturas aquáticas.", + "iconsenhanced.desc.minecraft.infinity": "Dispara flechas sem consumir.", + "iconsenhanced.desc.minecraft.knockback": "Aumenta o empurrão.", + "iconsenhanced.desc.minecraft.looting": "Aumenta o saque de criaturas.", + "iconsenhanced.desc.minecraft.loyalty": "O tridente volta após ser lançado.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Aumenta a chance de tesouros na pesca.", + "iconsenhanced.desc.minecraft.lure": "Aumenta a velocidade de fisgada.", + "iconsenhanced.desc.minecraft.mending": "Repara itens com experiência.", + "iconsenhanced.desc.minecraft.multishot": "Dispara 3 flechas de uma vez.", + "iconsenhanced.desc.minecraft.piercing": "Flechas atravessam alvos.", + "iconsenhanced.desc.minecraft.power": "Aumenta o dano do arco.", + "iconsenhanced.desc.minecraft.projectile_protection": "Reduz o dano de projéteis.", + "iconsenhanced.desc.minecraft.protection": "Reduz a maioria dos danos.", + "iconsenhanced.desc.minecraft.punch": "Aumenta o empurrão das flechas.", + "iconsenhanced.desc.minecraft.quick_charge": "Reduz o tempo de recarga da besta.", + "iconsenhanced.desc.minecraft.respiration": "Aumenta o tempo de respiração debaixo d'água.", + "iconsenhanced.desc.minecraft.riptide": "Impulsiona você na água ou na chuva.", + "iconsenhanced.desc.minecraft.sharpness": "Aumenta o dano corpo a corpo.", + "iconsenhanced.desc.minecraft.silk_touch": "Blocos minerados caem intactos.", + "iconsenhanced.desc.minecraft.smite": "Aumenta o dano contra mortos-vivos.", + "iconsenhanced.desc.minecraft.soul_speed": "Aumenta a velocidade na areia das almas e na terra das almas.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Aumenta o dano do ataque em varrida.", + "iconsenhanced.desc.minecraft.swift_sneak": "Aumenta a velocidade ao se agachar.", + "iconsenhanced.desc.minecraft.thorns": "Reflete dano aos atacantes.", + "iconsenhanced.desc.minecraft.unbreaking": "Itens perdem durabilidade mais lentamente.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Amaldiçoado: desaparece ao morrer.", + "iconsenhanced.desc.minecraft.wind_burst": "Cria uma rajada após o impacto." +} diff --git a/src/main/resources/assets/iconsenhanced/lang/ru_ru.json b/src/main/resources/assets/iconsenhanced/lang/ru_ru.json new file mode 100644 index 0000000..92bca19 --- /dev/null +++ b/src/main/resources/assets/iconsenhanced/lang/ru_ru.json @@ -0,0 +1,45 @@ +{ + "iconsenhanced.tooltip.shift": "Удерживайте Shift для подробностей.", + "iconsenhanced.desc.minecraft.aqua_affinity": "Увеличивает скорость добычи под водой.", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "Увеличивает урон по членистоногим и замедляет их.", + "iconsenhanced.desc.minecraft.binding_curse": "Проклятие: нельзя снять.", + "iconsenhanced.desc.minecraft.blast_protection": "Снижает урон и отдачу от взрывов.", + "iconsenhanced.desc.minecraft.breach": "Удары булавы игнорируют часть брони.", + "iconsenhanced.desc.minecraft.channeling": "Вызывает молнии во время грозы.", + "iconsenhanced.desc.minecraft.density": "Увеличивает урон ударом булавы.", + "iconsenhanced.desc.minecraft.depth_strider": "Увеличивает скорость под водой.", + "iconsenhanced.desc.minecraft.efficiency": "Увеличивает скорость добычи.", + "iconsenhanced.desc.minecraft.feather_falling": "Снижает урон от падения.", + "iconsenhanced.desc.minecraft.fire_aspect": "Поджигает цели.", + "iconsenhanced.desc.minecraft.fire_protection": "Снижает урон от огня и лавы.", + "iconsenhanced.desc.minecraft.flame": "Стрелы поджигают цели.", + "iconsenhanced.desc.minecraft.fortune": "Увеличивает количество добычи из блоков.", + "iconsenhanced.desc.minecraft.frost_walker": "Замораживает воду в лед.", + "iconsenhanced.desc.minecraft.impaling": "Увеличивает урон по водным существам.", + "iconsenhanced.desc.minecraft.infinity": "Стрелы не расходуются.", + "iconsenhanced.desc.minecraft.knockback": "Увеличивает отдачу.", + "iconsenhanced.desc.minecraft.looting": "Увеличивает добычу с существ.", + "iconsenhanced.desc.minecraft.loyalty": "Трезубец возвращается после броска.", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "Повышает шанс сокровищ при рыбалке.", + "iconsenhanced.desc.minecraft.lure": "Увеличивает скорость клева.", + "iconsenhanced.desc.minecraft.mending": "Чинит предметы опытом.", + "iconsenhanced.desc.minecraft.multishot": "Выпускает 3 стрелы одновременно.", + "iconsenhanced.desc.minecraft.piercing": "Стрелы пронзают цели.", + "iconsenhanced.desc.minecraft.power": "Увеличивает урон лука.", + "iconsenhanced.desc.minecraft.projectile_protection": "Снижает урон от снарядов.", + "iconsenhanced.desc.minecraft.protection": "Снижает большую часть урона.", + "iconsenhanced.desc.minecraft.punch": "Увеличивает отдачу стрел.", + "iconsenhanced.desc.minecraft.quick_charge": "Сокращает время перезарядки арбалета.", + "iconsenhanced.desc.minecraft.respiration": "Увеличивает время дыхания под водой.", + "iconsenhanced.desc.minecraft.riptide": "Отбрасывает вас в воде или под дождем.", + "iconsenhanced.desc.minecraft.sharpness": "Увеличивает урон в ближнем бою.", + "iconsenhanced.desc.minecraft.silk_touch": "Блоки выпадают сами.", + "iconsenhanced.desc.minecraft.smite": "Увеличивает урон по нежити.", + "iconsenhanced.desc.minecraft.soul_speed": "Увеличивает скорость по песку душ и земле душ.", + "iconsenhanced.desc.minecraft.sweeping_edge": "Увеличивает урон от размашистой атаки.", + "iconsenhanced.desc.minecraft.swift_sneak": "Увеличивает скорость приседания.", + "iconsenhanced.desc.minecraft.thorns": "Отражает урон атакующим.", + "iconsenhanced.desc.minecraft.unbreaking": "Снижает расход прочности.", + "iconsenhanced.desc.minecraft.vanishing_curse": "Проклятие: исчезает после смерти.", + "iconsenhanced.desc.minecraft.wind_burst": "Создает порыв ветра после удара." +} diff --git a/src/main/resources/assets/iconsenhanced/lang/zh_cn.json b/src/main/resources/assets/iconsenhanced/lang/zh_cn.json new file mode 100644 index 0000000..0ba04a5 --- /dev/null +++ b/src/main/resources/assets/iconsenhanced/lang/zh_cn.json @@ -0,0 +1,45 @@ +{ + "iconsenhanced.tooltip.shift": "按住Shift查看详情。", + "iconsenhanced.desc.minecraft.aqua_affinity": "提高水下挖掘速度。", + "iconsenhanced.desc.minecraft.bane_of_arthropods": "提高对节肢生物的伤害并使其减速。", + "iconsenhanced.desc.minecraft.binding_curse": "诅咒:无法移除。", + "iconsenhanced.desc.minecraft.blast_protection": "减少爆炸伤害和击退。", + "iconsenhanced.desc.minecraft.breach": "重锤攻击无视部分护甲。", + "iconsenhanced.desc.minecraft.channeling": "雷雨时召唤闪电。", + "iconsenhanced.desc.minecraft.density": "提高重锤重击伤害。", + "iconsenhanced.desc.minecraft.depth_strider": "提高水下移动速度。", + "iconsenhanced.desc.minecraft.efficiency": "提高挖掘速度。", + "iconsenhanced.desc.minecraft.feather_falling": "减少摔落伤害。", + "iconsenhanced.desc.minecraft.fire_aspect": "点燃目标。", + "iconsenhanced.desc.minecraft.fire_protection": "减少火焰和岩浆伤害。", + "iconsenhanced.desc.minecraft.flame": "箭矢点燃目标。", + "iconsenhanced.desc.minecraft.fortune": "提高方块掉落数量。", + "iconsenhanced.desc.minecraft.frost_walker": "将水冻结成冰。", + "iconsenhanced.desc.minecraft.impaling": "提高对水生生物的伤害。", + "iconsenhanced.desc.minecraft.infinity": "射箭不消耗箭矢。", + "iconsenhanced.desc.minecraft.knockback": "提高击退效果。", + "iconsenhanced.desc.minecraft.looting": "提高生物掉落。", + "iconsenhanced.desc.minecraft.loyalty": "投掷后会返回的三叉戟。", + "iconsenhanced.desc.minecraft.luck_of_the_sea": "提高钓鱼宝藏几率。", + "iconsenhanced.desc.minecraft.lure": "提高鱼咬钩速度。", + "iconsenhanced.desc.minecraft.mending": "用经验修复物品。", + "iconsenhanced.desc.minecraft.multishot": "一次射出3支箭。", + "iconsenhanced.desc.minecraft.piercing": "箭矢可穿透目标。", + "iconsenhanced.desc.minecraft.power": "提高弓的伤害。", + "iconsenhanced.desc.minecraft.projectile_protection": "减少投射物伤害。", + "iconsenhanced.desc.minecraft.protection": "减少大部分伤害。", + "iconsenhanced.desc.minecraft.punch": "提高箭矢击退。", + "iconsenhanced.desc.minecraft.quick_charge": "减少弩的装填时间。", + "iconsenhanced.desc.minecraft.respiration": "延长水下呼吸时间。", + "iconsenhanced.desc.minecraft.riptide": "在水中或雨中推进自己。", + "iconsenhanced.desc.minecraft.sharpness": "提高近战伤害。", + "iconsenhanced.desc.minecraft.silk_touch": "挖掘的方块会原样掉落。", + "iconsenhanced.desc.minecraft.smite": "提高对亡灵的伤害。", + "iconsenhanced.desc.minecraft.soul_speed": "提高在灵魂沙和灵魂土上的速度。", + "iconsenhanced.desc.minecraft.sweeping_edge": "提高横扫攻击伤害。", + "iconsenhanced.desc.minecraft.swift_sneak": "提高潜行速度。", + "iconsenhanced.desc.minecraft.thorns": "反弹伤害给攻击者。", + "iconsenhanced.desc.minecraft.unbreaking": "降低耐久消耗。", + "iconsenhanced.desc.minecraft.vanishing_curse": "诅咒:死亡时消失。", + "iconsenhanced.desc.minecraft.wind_burst": "重击后产生风爆。" +} diff --git a/stonecutter.gradle b/stonecutter.gradle index abb5a80..3bfd608 100644 --- a/stonecutter.gradle +++ b/stonecutter.gradle @@ -6,10 +6,23 @@ stonecutter.active "1.21.11" tasks.register("chiseledBuild") { group = "build" - dependsOn(stonecutter.tree.nodes.collect { it.project.tasks.named("remapJar") }) } tasks.register("chiseledClean") { group = "build" - dependsOn(stonecutter.tree.nodes.collect { it.project.tasks.named("clean") }) +} + +gradle.projectsEvaluated { + def remapTasks = rootProject.subprojects + .collect { it.tasks.findByName("remapJar") } + .findAll { it != null } + def cleanTasks = rootProject.subprojects + .collect { it.tasks.findByName("clean") } + .findAll { it != null } + tasks.named("chiseledBuild") { + dependsOn(remapTasks) + } + tasks.named("chiseledClean") { + dependsOn(cleanTasks) + } }