From 4fcfeb25b73f2dc58254cfbd84bb3bb798a4191f Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:11:06 +0700 Subject: [PATCH] Minor changes --- LICENSE | 2 +- README.md | 4 +-- .../me/melontini/andromeda/base/Module.java | 14 +++++++- .../andromeda/base/ModuleManager.java | 4 +-- .../melontini/andromeda/common/Andromeda.java | 28 ++++++--------- .../common/client/AndromedaClient.java | 33 ++++++++--------- .../andromeda/common/config/DataConfigs.java | 2 +- .../common/config/ScopedConfigs.java | 8 ++--- .../mixin/init/MinecraftClientMixin.java | 3 +- .../common/registries/AndromedaItemGroup.java | 3 +- .../andromeda/common/registries/Common.java | 9 ++++- .../common/registries/ResourceRegistry.java | 35 ------------------- .../andromeda/common/util/AndromedaTexts.java | 14 -------- .../blocks/bed/safe/mixin/BedBlockMixin.java | 4 +-- .../blocks/incubator/IncubatorBlock.java | 4 +-- .../modules/misc/unknown/RoseOfTheValley.java | 5 +-- 16 files changed, 64 insertions(+), 108 deletions(-) delete mode 100644 src/main/java/me/melontini/andromeda/common/registries/ResourceRegistry.java delete mode 100644 src/main/java/me/melontini/andromeda/common/util/AndromedaTexts.java diff --git a/LICENSE b/LICENSE index 5073f53e..629415b8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2023 melontini +Copyright (c) 2024 melontini Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 2a9edb99..251c0e75 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ## Andromeda [![Modrinth](https://img.shields.io/modrinth/dt/TseYlb0f?logo=modrinth&color=mint)](https://modrinth.com/mod/andromeda) -[![CodeFactor](https://www.codefactor.io/repository/github/melontini/andromeda/badge)](https://www.codefactor.io/repository/github/melontini/andromeda) -![GitHub](https://img.shields.io/github/license/melontini/andromeda) +[![CodeFactor](https://www.codefactor.io/repository/github/constellation-mc/andromeda/badge)](https://www.codefactor.io/repository/github/melontini/andromeda) +![GitHub](https://img.shields.io/github/license/constellation-mc/andromeda) ### A galaxy is a collection of things and systems. So is this mod. diff --git a/src/main/java/me/melontini/andromeda/base/Module.java b/src/main/java/me/melontini/andromeda/base/Module.java index e3c80081..b85cedeb 100644 --- a/src/main/java/me/melontini/andromeda/base/Module.java +++ b/src/main/java/me/melontini/andromeda/base/Module.java @@ -120,7 +120,19 @@ public abstract class Module { public Scope scope = Scope.GLOBAL; public enum Scope { - GLOBAL, WORLD, DIMENSION + GLOBAL, WORLD, DIMENSION; + + public boolean isWorld() { + return this == WORLD; + } + + public boolean isGlobal() { + return this == GLOBAL; + } + + public boolean isDimension() { + return this == DIMENSION; + } } } diff --git a/src/main/java/me/melontini/andromeda/base/ModuleManager.java b/src/main/java/me/melontini/andromeda/base/ModuleManager.java index c08d817a..43413351 100644 --- a/src/main/java/me/melontini/andromeda/base/ModuleManager.java +++ b/src/main/java/me/melontini/andromeda/base/ModuleManager.java @@ -91,7 +91,7 @@ public class ModuleManager { modules.forEach(m -> { if (Debug.Keys.FORCE_DIMENSION_SCOPE.isPresent()) m.config().scope = Module.BaseConfig.Scope.DIMENSION; - if (m.meta().environment().isClient() && m.config().scope != Module.BaseConfig.Scope.GLOBAL) { + if (m.meta().environment().isClient() && !m.config().scope.isGlobal()) { if (!Debug.Keys.FORCE_DIMENSION_SCOPE.isPresent()) LOGGER.error("{} Module '{}' has an invalid scope ({}), must be {}", m.meta().environment(), m.meta().id(), m.config().scope, Module.BaseConfig.Scope.GLOBAL); @@ -99,7 +99,7 @@ public class ModuleManager { return; } - if (m.getClass().isAnnotationPresent(Unscoped.class) && m.config().scope != Module.BaseConfig.Scope.GLOBAL) { + if (m.getClass().isAnnotationPresent(Unscoped.class) && !m.config().scope.isGlobal()) { if (!Debug.Keys.FORCE_DIMENSION_SCOPE.isPresent()) LOGGER.error("{} Module '{}' has an invalid scope ({}), must be {}", "Unscoped", m.meta().id(), m.config().scope, Module.BaseConfig.Scope.GLOBAL); diff --git a/src/main/java/me/melontini/andromeda/common/Andromeda.java b/src/main/java/me/melontini/andromeda/common/Andromeda.java index 79b7a47d..2930c8d2 100644 --- a/src/main/java/me/melontini/andromeda/common/Andromeda.java +++ b/src/main/java/me/melontini/andromeda/common/Andromeda.java @@ -33,11 +33,11 @@ public class Andromeda { public static void init() { INSTANCE = new Andromeda(); - INSTANCE.onInitialize(); + INSTANCE.onInitialize(ModuleManager.get()); Support.share("andromeda:main", INSTANCE); } - private void onInitialize() { + private void onInitialize(ModuleManager manager) { Common.bootstrap(); ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new DataConfigs()); @@ -46,10 +46,10 @@ public class Andromeda { }); ServerLifecycleEvents.SERVER_STARTED.register(server -> { - var list = ModuleManager.get().loaded().stream().filter(module -> module.config().scope == Module.BaseConfig.Scope.DIMENSION).toList(); - server.getWorlds().forEach(world -> ModuleManager.get().cleanConfigs(server.session.getWorldDirectory(world.getRegistryKey()).resolve("world_config/andromeda"), list)); - ModuleManager.get().cleanConfigs(server.session.getDirectory(WorldSavePath.ROOT).resolve("config/andromeda"), - ModuleManager.get().loaded().stream().filter(module -> module.config().scope == Module.BaseConfig.Scope.WORLD).toList()); + var list = manager.loaded().stream().filter(module -> module.config().scope.isDimension()).toList(); + server.getWorlds().forEach(world -> manager.cleanConfigs(server.session.getWorldDirectory(world.getRegistryKey()).resolve("world_config/andromeda"), list)); + manager.cleanConfigs(server.session.getDirectory(WorldSavePath.ROOT).resolve("config/andromeda"), + manager.loaded().stream().filter(module -> module.config().scope.isWorld()).toList()); }); ServerLifecycleEvents.END_DATA_PACK_RELOAD.register((server, resourceManager, success) -> { @@ -60,8 +60,9 @@ public class Andromeda { ServerLoginNetworking.registerGlobalReceiver(VERIFY_MODULES, (server, handler, understood, buf, synchronizer, responseSender) -> { if (Debug.Keys.SKIP_SERVER_MODULE_CHECK.isPresent()) return; - Set modules = ModuleManager.get().loaded().stream().map(Module::meta) - .filter(m -> m.environment().isBoth()).map(Module.Metadata::id).collect(Collectors.toSet()); + Set modules = manager.loaded().stream() + .map(Module::meta).filter(m -> m.environment().isBoth()) + .map(Module.Metadata::id).collect(Collectors.toSet()); if (!understood) { if (!modules.isEmpty()) handler.disconnect(TextUtil.translatable("andromeda.disconnected.module_mismatch", @@ -76,15 +77,8 @@ public class Andromeda { } synchronizer.waitFor(server.submit(() -> { - Set disable = new HashSet<>(); - for (String clientModule : clientModules) { - if (!modules.contains(clientModule)) disable.add(clientModule); - } - - Set enable = new HashSet<>(); - for (String module : modules) { - if (!clientModules.contains(module)) enable.add(module); - } + Set disable = clientModules.stream().filter(s -> !modules.contains(s)).collect(Collectors.toSet()); + Set enable = modules.stream().filter(s -> !clientModules.contains(s)).collect(Collectors.toSet()); if (!disable.isEmpty() || !enable.isEmpty()) { handler.disconnect(TextUtil.translatable("andromeda.disconnected.module_mismatch", diff --git a/src/main/java/me/melontini/andromeda/common/client/AndromedaClient.java b/src/main/java/me/melontini/andromeda/common/client/AndromedaClient.java index 5d3c0059..c6affe58 100644 --- a/src/main/java/me/melontini/andromeda/common/client/AndromedaClient.java +++ b/src/main/java/me/melontini/andromeda/common/client/AndromedaClient.java @@ -27,7 +27,7 @@ import net.minecraft.util.Util; import net.minecraft.util.math.RotationAxis; import org.joml.Matrix4f; -import java.lang.reflect.Field; +import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; @@ -41,19 +41,19 @@ import static me.melontini.andromeda.common.registries.Common.id; public class AndromedaClient { private static AndromedaClient INSTANCE; - private static boolean animate = true; + private boolean animate = true; public static void init() { INSTANCE = new AndromedaClient(); - INSTANCE.onInitializeClient(); + INSTANCE.onInitializeClient(ModuleManager.get()); FabricLoader.getInstance().getObjectShare().put("andromeda:client", INSTANCE); } - public void onInitializeClient() { + public void onInitializeClient(ModuleManager manager) { Support.run("cloth-config", () -> AutoConfigScreen::register); if (!AndromedaConfig.get().sideOnlyMode) ClientSideNetworking.register(); else { - ModuleManager.get().all().stream().map(Promise::get).forEach(module -> { + manager.all().stream().map(Promise::get).forEach(module -> { switch (module.meta().environment()) { case ANY, CLIENT -> { } @@ -78,29 +78,24 @@ public class AndromedaClient { }); } - private static void printMissingTooltips() { + private void printMissingTooltips(ModuleManager manager) { Set missing = new LinkedHashSet<>(); - for (Promise module : ModuleManager.get().all()) { + for (Promise module : manager.all()) { String m = "config.andromeda.%s.@Tooltip".formatted(module.meta().dotted()); if (!I18n.hasTranslation(m)) missing.add(m); - for (Field field : ModuleManager.get().getConfigClass(module.getClass()).getFields()) { - if ("enabled".equals(field.getName()) || field.isAnnotationPresent(ConfigEntry.Gui.Excluded.class)) - continue; - - String f = "config.andromeda.%s.option.%s.@Tooltip".formatted(module.meta().dotted(), field.getName()); - if (!I18n.hasTranslation(f)) missing.add(f); - } + Arrays.stream(manager.getConfigClass(module.getClass()).getFields()) + .filter(f -> !"enabled".equals(f.getName()) && !f.isAnnotationPresent(ConfigEntry.Gui.Excluded.class)) + .map(field -> "config.andromeda.%s.option.%s.@Tooltip".formatted(module.meta().dotted(), field.getName())) + .filter(I18n::hasTranslation).forEach(missing::add); } StringBuilder b = new StringBuilder(); - for (String s : missing) { - b.append('\t').append(s).append('\n'); - } + missing.forEach(s -> b.append('\t').append(s).append('\n')); LOGGER.info("Missing tooltips:\n{}", b); } - public void lateInit() { - if (Debug.Keys.PRINT_MISSING_TOOLTIPS.isPresent()) printMissingTooltips(); + public void lateInit(ModuleManager manager) { + if (Debug.Keys.PRINT_MISSING_TOOLTIPS.isPresent()) printMissingTooltips(manager); } @Override diff --git a/src/main/java/me/melontini/andromeda/common/config/DataConfigs.java b/src/main/java/me/melontini/andromeda/common/config/DataConfigs.java index ffc6132f..4e0707db 100644 --- a/src/main/java/me/melontini/andromeda/common/config/DataConfigs.java +++ b/src/main/java/me/melontini/andromeda/common/config/DataConfigs.java @@ -49,7 +49,7 @@ public class DataConfigs extends JsonDataLoader implements IdentifiableResourceR var m = ModuleManager.get().getModule(id.getPath()).orElseThrow(() -> new IllegalStateException("Invalid module path '%s'! The module must be enabled!".formatted(id.getPath()))); var cls = ModuleManager.get().getConfigClass(m.getClass()); - if (m.config().scope == Module.BaseConfig.Scope.WORLD) { + if (m.config().scope.isWorld()) { if (!object.has(DEFAULT.toString()) || object.size() > 1) throw new IllegalStateException("'%s' modules only support '%s' as their dimension!".formatted(Module.BaseConfig.Scope.WORLD, DEFAULT)); diff --git a/src/main/java/me/melontini/andromeda/common/config/ScopedConfigs.java b/src/main/java/me/melontini/andromeda/common/config/ScopedConfigs.java index 8aa386f4..1daa67ed 100644 --- a/src/main/java/me/melontini/andromeda/common/config/ScopedConfigs.java +++ b/src/main/java/me/melontini/andromeda/common/config/ScopedConfigs.java @@ -49,9 +49,7 @@ public class ScopedConfigs { @SneakyThrows private static Module.BaseConfig loadScoped(Path root, Module module) { var manager = module.manager(); - if (Files.exists(manager.resolve(root))) { - return manager.load(root); - } + if (Files.exists(manager.resolve(root))) return manager.load(root); return manager.load(FabricLoader.getInstance().getConfigDir()); } @@ -61,9 +59,7 @@ public class ScopedConfigs { module.manager().save(p, Utilities.cast(config)); - if (module.config().scope == Module.BaseConfig.Scope.DIMENSION) { - DataConfigs.applyDataPacks(config, module, world.getRegistryKey().getValue()); - } + if (!module.config().scope.isDimension()) DataConfigs.applyDataPacks(config, module, world.getRegistryKey().getValue()); attachment.addConfig(module, config); } diff --git a/src/main/java/me/melontini/andromeda/common/mixin/init/MinecraftClientMixin.java b/src/main/java/me/melontini/andromeda/common/mixin/init/MinecraftClientMixin.java index 0329962b..59d0e976 100644 --- a/src/main/java/me/melontini/andromeda/common/mixin/init/MinecraftClientMixin.java +++ b/src/main/java/me/melontini/andromeda/common/mixin/init/MinecraftClientMixin.java @@ -1,5 +1,6 @@ package me.melontini.andromeda.common.mixin.init; +import me.melontini.andromeda.base.ModuleManager; import me.melontini.andromeda.base.util.Environment; import me.melontini.andromeda.base.util.annotations.SpecialEnvironment; import me.melontini.andromeda.common.client.AndromedaClient; @@ -15,6 +16,6 @@ abstract class MinecraftClientMixin { @Inject(method = "method_29338", at = @At("TAIL")) private void andromeda$init(CallbackInfo ci) { - AndromedaClient.get().lateInit(); + AndromedaClient.get().lateInit(ModuleManager.get()); } } diff --git a/src/main/java/me/melontini/andromeda/common/registries/AndromedaItemGroup.java b/src/main/java/me/melontini/andromeda/common/registries/AndromedaItemGroup.java index de7ae129..10d97fe0 100644 --- a/src/main/java/me/melontini/andromeda/common/registries/AndromedaItemGroup.java +++ b/src/main/java/me/melontini/andromeda/common/registries/AndromedaItemGroup.java @@ -1,7 +1,6 @@ package me.melontini.andromeda.common.registries; import me.melontini.andromeda.base.Module; -import me.melontini.andromeda.common.util.AndromedaTexts; import me.melontini.dark_matter.api.base.util.MathStuff; import me.melontini.dark_matter.api.content.ContentBuilder; import me.melontini.dark_matter.api.content.interfaces.DarkMatterEntries; @@ -70,7 +69,7 @@ public class AndromedaItemGroup { appendStacks(entries, itemStacks); }); }) - .displayName(AndromedaTexts.ITEM_GROUP_NAME).optional().orElseThrow(); + .displayName(TextUtil.translatable("itemGroup.andromeda.items")).optional().orElseThrow(); public static void init() { diff --git a/src/main/java/me/melontini/andromeda/common/registries/Common.java b/src/main/java/me/melontini/andromeda/common/registries/Common.java index 6f6367a5..2a65e49f 100644 --- a/src/main/java/me/melontini/andromeda/common/registries/Common.java +++ b/src/main/java/me/melontini/andromeda/common/registries/Common.java @@ -1,6 +1,10 @@ package me.melontini.andromeda.common.registries; +import com.google.gson.JsonElement; +import me.melontini.andromeda.common.conflicts.CommonRegistries; +import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions; import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; import static me.melontini.andromeda.util.CommonValues.MODID; @@ -12,6 +16,9 @@ public class Common { public static void bootstrap() { AndromedaItemGroup.init(); - ResourceRegistry.init(); + + ResourceConditions.register(id("items_registered"), object -> JsonHelper.getArray(object, "values") + .asList().stream().filter(JsonElement::isJsonPrimitive) + .allMatch(e -> CommonRegistries.items().containsId(Identifier.tryParse(e.getAsString())))); } } diff --git a/src/main/java/me/melontini/andromeda/common/registries/ResourceRegistry.java b/src/main/java/me/melontini/andromeda/common/registries/ResourceRegistry.java deleted file mode 100644 index 7d284afb..00000000 --- a/src/main/java/me/melontini/andromeda/common/registries/ResourceRegistry.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.melontini.andromeda.common.registries; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import me.melontini.andromeda.common.conflicts.CommonRegistries; -import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions; -import net.minecraft.registry.Registry; -import net.minecraft.util.Identifier; -import net.minecraft.util.InvalidIdentifierException; -import net.minecraft.util.JsonHelper; - -import static me.melontini.andromeda.common.registries.Common.id; - -public class ResourceRegistry { - - public static void init() { - ResourceConditions.register(id("items_registered"), object -> { - JsonArray array = JsonHelper.getArray(object, "values"); - - for (JsonElement element : array) { - if (element.isJsonPrimitive()) { - if (!CommonRegistries.items().containsId(Identifier.tryParse(element.getAsString()))) return false; - } - } - - return true; - }); - } - - public static T parseFromId(String id, Registry registry) { - Identifier identifier = Identifier.tryParse(id); - if (!registry.containsId(identifier)) throw new InvalidIdentifierException(String.format("(Andromeda) invalid identifier provided! id: %s, registry: %s", identifier, registry)); - return registry.get(identifier); - } -} diff --git a/src/main/java/me/melontini/andromeda/common/util/AndromedaTexts.java b/src/main/java/me/melontini/andromeda/common/util/AndromedaTexts.java deleted file mode 100644 index 9873b3f3..00000000 --- a/src/main/java/me/melontini/andromeda/common/util/AndromedaTexts.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.melontini.andromeda.common.util; - -import me.melontini.dark_matter.api.minecraft.util.TextUtil; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -public class AndromedaTexts { - public static final Text ITEM_GROUP_NAME = TextUtil.translatable("itemGroup.andromeda.items"); - public static final Text FLETCHING_SCREEN = TextUtil.translatable("gui.andromeda.fletching"); - public static final Text SAFE_BEDS = TextUtil.translatable("action.andromeda.safebeds"); - public static final Text INCUBATOR_SECRET = TextUtil.translatable("tooltip.andromeda.incubator[1]").formatted(Formatting.GRAY); - public static final Text ITEM_IN_FRAME = TextUtil.translatable("tooltip.andromeda.frameitem").formatted(Formatting.GRAY); - public static final Text ROSE_OF_THE_VALLEY_TOOLTIP = TextUtil.translatable("tooltip.andromeda.rose_of_the_valley").formatted(Formatting.GRAY); -} diff --git a/src/main/java/me/melontini/andromeda/modules/blocks/bed/safe/mixin/BedBlockMixin.java b/src/main/java/me/melontini/andromeda/modules/blocks/bed/safe/mixin/BedBlockMixin.java index 54f91728..ae0a5c2a 100644 --- a/src/main/java/me/melontini/andromeda/modules/blocks/bed/safe/mixin/BedBlockMixin.java +++ b/src/main/java/me/melontini/andromeda/modules/blocks/bed/safe/mixin/BedBlockMixin.java @@ -1,7 +1,7 @@ package me.melontini.andromeda.modules.blocks.bed.safe.mixin; -import me.melontini.andromeda.common.util.AndromedaTexts; import me.melontini.andromeda.modules.blocks.bed.safe.Safe; +import me.melontini.dark_matter.api.minecraft.util.TextUtil; import net.minecraft.block.BedBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -31,7 +31,7 @@ abstract class BedBlockMixin extends Block { if (world.isClient()) return; if (!isBedWorking(world) && world.am$get(Safe.class).enabled) { - player.sendMessage(AndromedaTexts.SAFE_BEDS, true); + player.sendMessage(TextUtil.translatable("action.andromeda.safebeds"), true); cir.setReturnValue(ActionResult.SUCCESS); } } diff --git a/src/main/java/me/melontini/andromeda/modules/blocks/incubator/IncubatorBlock.java b/src/main/java/me/melontini/andromeda/modules/blocks/incubator/IncubatorBlock.java index 48eb3e47..78ba8df4 100644 --- a/src/main/java/me/melontini/andromeda/modules/blocks/incubator/IncubatorBlock.java +++ b/src/main/java/me/melontini/andromeda/modules/blocks/incubator/IncubatorBlock.java @@ -1,10 +1,10 @@ package me.melontini.andromeda.modules.blocks.incubator; import me.melontini.andromeda.base.ModuleManager; -import me.melontini.andromeda.common.util.AndromedaTexts; import me.melontini.andromeda.modules.blocks.incubator.data.EggProcessingData; import me.melontini.andromeda.modules.misc.unknown.Unknown; import me.melontini.andromeda.util.exceptions.AndromedaException; +import me.melontini.dark_matter.api.minecraft.util.TextUtil; import net.minecraft.block.*; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityTicker; @@ -63,7 +63,7 @@ public class IncubatorBlock extends BlockWithEntity implements InventoryProvider @Override public void appendTooltip(ItemStack stack, @Nullable BlockView world, List tooltip, TooltipContext options) { if (ModuleManager.get().getModule(Unknown.class).isPresent()) - tooltip.add(AndromedaTexts.INCUBATOR_SECRET); + tooltip.add(TextUtil.translatable("tooltip.andromeda.incubator[1]").formatted(Formatting.GRAY)); } @Override diff --git a/src/main/java/me/melontini/andromeda/modules/misc/unknown/RoseOfTheValley.java b/src/main/java/me/melontini/andromeda/modules/misc/unknown/RoseOfTheValley.java index 6e96ed4a..07bd19ff 100644 --- a/src/main/java/me/melontini/andromeda/modules/misc/unknown/RoseOfTheValley.java +++ b/src/main/java/me/melontini/andromeda/modules/misc/unknown/RoseOfTheValley.java @@ -1,7 +1,7 @@ package me.melontini.andromeda.modules.misc.unknown; -import me.melontini.andromeda.common.util.AndromedaTexts; import me.melontini.dark_matter.api.glitter.ScreenParticleHelper; +import me.melontini.dark_matter.api.minecraft.util.TextUtil; import net.minecraft.block.Block; import net.minecraft.client.MinecraftClient; import net.minecraft.client.item.TooltipContext; @@ -10,6 +10,7 @@ import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.particle.ParticleTypes; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; @@ -23,7 +24,7 @@ public class RoseOfTheValley extends BlockItem { @Override public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip, TooltipContext context) { - tooltip.add(AndromedaTexts.ROSE_OF_THE_VALLEY_TOOLTIP); + tooltip.add(TextUtil.translatable("tooltip.andromeda.rose_of_the_valley").formatted(Formatting.GRAY)); } public static void handleClick(ItemStack stack, ItemStack otherStack, PlayerEntity player) { -- 2.51.2