config val fix
This commit is contained in:
		@@ -5,9 +5,12 @@ import com.tterrag.registrate.util.DataIngredient;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
 | 
			
		||||
import dev.xkmc.l2core.serial.advancements.RewardBuilder;
 | 
			
		||||
import dev.xkmc.l2core.serial.recipe.ConditionalRecipeWrapper;
 | 
			
		||||
import net.minecraft.Util;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.data.recipes.RecipeBuilder;
 | 
			
		||||
import net.minecraft.nbt.CompoundTag;
 | 
			
		||||
import net.minecraft.data.recipes.RecipeCategory;
 | 
			
		||||
import net.minecraft.data.recipes.ShapedRecipeBuilder;
 | 
			
		||||
import net.minecraft.data.recipes.ShapelessRecipeBuilder;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab;
 | 
			
		||||
@@ -15,8 +18,14 @@ import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootPool;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.LootTable;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.entries.LootItem;
 | 
			
		||||
import net.minecraft.world.level.storage.loot.functions.SetComponentsFunction;
 | 
			
		||||
import net.neoforged.neoforge.client.model.generators.ModelFile;
 | 
			
		||||
import vazkii.patchouli.common.item.ItemModBook;
 | 
			
		||||
import vazkii.patchouli.common.item.PatchouliDataComponents;
 | 
			
		||||
import vazkii.patchouli.common.item.PatchouliItems;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
public class PatchouliHelper {
 | 
			
		||||
@@ -24,14 +33,13 @@ public class PatchouliHelper {
 | 
			
		||||
	public static final ProviderType<PatchouliProvider> PATCHOULI = ProviderType.registerServerData("patchouli", PatchouliProvider::new);
 | 
			
		||||
 | 
			
		||||
	public static ItemStack getBook(ResourceLocation book) {
 | 
			
		||||
		return ItemStack.EMPTY; // TODO ItemModBook.forBook(book);
 | 
			
		||||
		return ItemModBook.forBook(book);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static LootTable.Builder getBookLoot(ResourceLocation book) {
 | 
			
		||||
		CompoundTag tag = new CompoundTag();
 | 
			
		||||
		tag.putString("patchouli:book", book.toString());
 | 
			
		||||
		return LootTable.lootTable().withPool(
 | 
			
		||||
				LootPool.lootPool()//TODO .add(LootItem.lootTableItem(PatchouliItems.BOOK).apply(SetNbtFunction.setTag(tag)))
 | 
			
		||||
				LootPool.lootPool().add(LootItem.lootTableItem(PatchouliItems.BOOK)
 | 
			
		||||
						.apply(SetComponentsFunction.setComponent(PatchouliDataComponents.BOOK, book)))
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -59,15 +67,13 @@ public class PatchouliHelper {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* TODO
 | 
			
		||||
	public PatchouliHelper buildShapelessRecipe(Consumer<ShapelessPatchouliBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		return buildRecipe(() -> Util.make(new ShapelessPatchouliBuilder(book), cons), unlock);
 | 
			
		||||
	public PatchouliHelper buildShapelessRecipe(Consumer<ShapelessRecipeBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		return buildRecipe(() -> Util.make(new ShapelessRecipeBuilder(RecipeCategory.MISC, getBook(book)), cons), unlock);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public PatchouliHelper buildShapedRecipe(Consumer<ShapedPatchouliBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		return buildRecipe(() -> Util.make(new ShapedPatchouliBuilder(book), cons), unlock);
 | 
			
		||||
	public PatchouliHelper buildShapedRecipe(Consumer<ShapedRecipeBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		return buildRecipe(() -> Util.make(new ShapedRecipeBuilder(RecipeCategory.MISC, getBook(book)), cons), unlock);
 | 
			
		||||
	}
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	private PatchouliHelper buildRecipe(Supplier<RecipeBuilder> cons, Supplier<Item> unlock) {
 | 
			
		||||
		reg.addDataGenerator(ProviderType.RECIPE, pvd -> {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										107
									
								
								src/main/java/dev/xkmc/l2core/events/ClientEventHandler.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/main/java/dev/xkmc/l2core/events/ClientEventHandler.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
package dev.xkmc.l2core.events;
 | 
			
		||||
 | 
			
		||||
import com.mojang.datafixers.util.Either;
 | 
			
		||||
import dev.xkmc.l2core.init.L2Core;
 | 
			
		||||
import dev.xkmc.l2core.init.L2CoreConfig;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.CustomDescEnchantment;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.EnchColor;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.LegacyEnchantment;
 | 
			
		||||
import net.minecraft.client.gui.screens.Screen;
 | 
			
		||||
import net.minecraft.client.resources.language.I18n;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.contents.PlainTextContents;
 | 
			
		||||
import net.minecraft.network.chat.contents.TranslatableContents;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.Items;
 | 
			
		||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
 | 
			
		||||
import net.neoforged.api.distmarker.Dist;
 | 
			
		||||
import net.neoforged.bus.api.EventPriority;
 | 
			
		||||
import net.neoforged.bus.api.SubscribeEvent;
 | 
			
		||||
import net.neoforged.fml.common.EventBusSubscriber;
 | 
			
		||||
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Stream;
 | 
			
		||||
 | 
			
		||||
@EventBusSubscriber(value = Dist.CLIENT, modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME)
 | 
			
		||||
public class ClientEventHandler {
 | 
			
		||||
 | 
			
		||||
	public enum EnchDesc {
 | 
			
		||||
		DISABLE, SHIFT_ONLY, ALWAYS
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SubscribeEvent(priority = EventPriority.LOW)
 | 
			
		||||
	public static void modifyItemTooltip(ItemTooltipEvent event) {
 | 
			
		||||
		var config = L2CoreConfig.CLIENT.addEnchantmentDescription.get();
 | 
			
		||||
		boolean skip = config == EnchDesc.DISABLE || config == EnchDesc.SHIFT_ONLY && !Screen.hasShiftDown();
 | 
			
		||||
		var list = event.getToolTip();
 | 
			
		||||
		int n = list.size();
 | 
			
		||||
		ItemStack stack = event.getItemStack();
 | 
			
		||||
		if (!stack.isEnchanted() && !stack.is(Items.ENCHANTED_BOOK)) return;
 | 
			
		||||
		var map = EnchantmentHelper.getEnchantmentsForCrafting(stack);
 | 
			
		||||
		String prefix = "enchantment.";
 | 
			
		||||
		String suffix = ".desc";
 | 
			
		||||
		boolean alt = Screen.hasAltDown();
 | 
			
		||||
		boolean flag = false;
 | 
			
		||||
		boolean book = event.getItemStack().is(Items.ENCHANTED_BOOK);
 | 
			
		||||
		var registries = event.getContext().registries();
 | 
			
		||||
		if (registries == null) return;
 | 
			
		||||
		var reg = registries.lookup(Registries.ENCHANTMENT);
 | 
			
		||||
		if (reg.isEmpty()) return;
 | 
			
		||||
		List<Either<Component, List<Component>>> compound = new ArrayList<>();
 | 
			
		||||
		for (var e : list) {
 | 
			
		||||
			compound.add(Either.left(e));
 | 
			
		||||
		}
 | 
			
		||||
		for (int i = 0; i < n; i++) {
 | 
			
		||||
			Component comp = list.get(i);
 | 
			
		||||
			Component lit;
 | 
			
		||||
			if (comp.getContents() instanceof PlainTextContents.LiteralContents txt && comp.getSiblings().size() == 1) {
 | 
			
		||||
				comp = comp.getSiblings().getFirst();
 | 
			
		||||
				lit = Component.literal(txt.text());
 | 
			
		||||
			} else lit = Component.empty();
 | 
			
		||||
			if (!(comp.getContents() instanceof TranslatableContents tr)) continue;
 | 
			
		||||
			if (!tr.getKey().startsWith(prefix)) continue;
 | 
			
		||||
			if (tr.getKey().endsWith(suffix)) {
 | 
			
		||||
				compound.set(i, Either.right(List.of()));
 | 
			
		||||
				flag = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			String id = tr.getKey().substring(prefix.length());
 | 
			
		||||
			var rl = ResourceLocation.tryBySeparator(id, '.');
 | 
			
		||||
			if (rl == null) continue;
 | 
			
		||||
			var ench = reg.get().get(ResourceKey.create(Registries.ENCHANTMENT, rl));
 | 
			
		||||
			if (ench.isEmpty()) continue;
 | 
			
		||||
			var color = LegacyEnchantment.firstOf(ench.get(), L2LibReg.COLOR);
 | 
			
		||||
			if (color != null) {
 | 
			
		||||
				comp = comp.copy().withStyle(color.base());
 | 
			
		||||
				compound.set(i, Either.left(comp));
 | 
			
		||||
				flag = true;
 | 
			
		||||
			} else color = EnchColor.DEFAULT;
 | 
			
		||||
			if (skip) continue;
 | 
			
		||||
			var legacy = LegacyEnchantment.findFirst(ench.get(), CustomDescEnchantment.class);
 | 
			
		||||
			if (legacy.isEmpty()) {
 | 
			
		||||
				if (I18n.exists(tr.getKey() + ".desc")) {
 | 
			
		||||
					compound.set(i, Either.right(List.of(comp, Component.translatable(tr.getKey() + ".desc")
 | 
			
		||||
							.withStyle(color.desc()))));
 | 
			
		||||
					flag = true;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				int lv = map.getLevel(ench.get());
 | 
			
		||||
				var es = legacy.get().descFull(lv, tr.getKey() + ".desc", alt, book, color);
 | 
			
		||||
				compound.set(i, Either.right(Stream.concat(Stream.of(comp), es.stream().map(e -> (Component) lit.copy().append(e))).toList()));
 | 
			
		||||
				flag = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (flag) {
 | 
			
		||||
			list.clear();
 | 
			
		||||
			list.addAll(compound.stream().flatMap(e -> e.map(Stream::of, Collection::stream)).toList());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -9,10 +9,7 @@ import dev.xkmc.l2serial.network.PacketHandler;
 | 
			
		||||
import dev.xkmc.l2serial.serialization.custom_handler.Handlers;
 | 
			
		||||
import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.neoforged.bus.api.IEventBus;
 | 
			
		||||
import net.neoforged.bus.api.SubscribeEvent;
 | 
			
		||||
import net.neoforged.fml.common.EventBusSubscriber;
 | 
			
		||||
import net.neoforged.fml.common.Mod;
 | 
			
		||||
import net.neoforged.neoforge.data.event.GatherDataEvent;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
 | 
			
		||||
@@ -36,6 +33,7 @@ public class L2Core {
 | 
			
		||||
 | 
			
		||||
	public L2Core(IEventBus bus) {
 | 
			
		||||
		L2LibReg.register();
 | 
			
		||||
		L2CoreConfig.init();
 | 
			
		||||
		Handlers.register();
 | 
			
		||||
		REGISTRATE.addDataGenerator(L2TagGen.EFF_TAGS, L2TagGen::onEffectTagGen);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/main/java/dev/xkmc/l2core/init/L2CoreConfig.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/main/java/dev/xkmc/l2core/init/L2CoreConfig.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
package dev.xkmc.l2core.init;
 | 
			
		||||
 | 
			
		||||
import dev.xkmc.l2core.events.ClientEventHandler;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
public class L2CoreConfig {
 | 
			
		||||
 | 
			
		||||
	public static class Client extends ConfigInit {
 | 
			
		||||
 | 
			
		||||
		public final ModConfigSpec.IntValue overlayZVal;
 | 
			
		||||
		public final ModConfigSpec.EnumValue<ClientEventHandler.EnchDesc> addEnchantmentDescription;
 | 
			
		||||
 | 
			
		||||
		Client(Builder builder) {
 | 
			
		||||
			markL2();
 | 
			
		||||
			overlayZVal = builder.text("The height of item character overlay")
 | 
			
		||||
					.defineInRange("overlayZVal", 250, -1000000, 1000000);
 | 
			
		||||
			addEnchantmentDescription = builder.text("Add Enchantment Descriptions")
 | 
			
		||||
					.defineEnum("addEnchantmentDescription", ClientEventHandler.EnchDesc.ALWAYS);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static final Client CLIENT = L2Core.REGISTRATE.registerClient(Client::new);
 | 
			
		||||
 | 
			
		||||
	public static void init() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package dev.xkmc.l2core.init;
 | 
			
		||||
 | 
			
		||||
import com.tterrag.registrate.providers.ProviderType;
 | 
			
		||||
import dev.xkmc.l2core.base.effects.ClientEffectCap;
 | 
			
		||||
import dev.xkmc.l2core.base.menu.base.MenuLayoutConfig;
 | 
			
		||||
import dev.xkmc.l2core.capability.conditionals.ConditionalData;
 | 
			
		||||
@@ -8,6 +7,7 @@ import dev.xkmc.l2core.capability.conditionals.PlayerFlagData;
 | 
			
		||||
import dev.xkmc.l2core.capability.player.PlayerCapabilityNetworkHandler;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.datapack.DatapackReg;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.EECVal;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.EnchColor;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.EnchReg;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.ench.LegacyEnchantment;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
 | 
			
		||||
@@ -69,8 +69,9 @@ public class L2LibReg {
 | 
			
		||||
	// enchantment
 | 
			
		||||
	public static final L2Registrate.RegistryInstance<LegacyEnchantment> ENCH =
 | 
			
		||||
			L2Core.REGISTRATE.newRegistry("legacy_enchantment", LegacyEnchantment.class, e -> e.sync(true));
 | 
			
		||||
	public static final EECVal.Special<LegacyEnchantment> LEGACY =
 | 
			
		||||
			EnchReg.of(REG, L2Core.REGISTRATE).special("legacy", ENCH.reg().byNameCodec());
 | 
			
		||||
	private static final EnchReg ENCH_REG = EnchReg.of(REG, L2Core.REGISTRATE);
 | 
			
		||||
	public static final EECVal.Special<EnchColor> COLOR = ENCH_REG.special("color", EnchColor.CODEC);
 | 
			
		||||
	public static final EECVal.Special<LegacyEnchantment> LEGACY = ENCH_REG.special("legacy", ENCH.reg().byNameCodec());
 | 
			
		||||
 | 
			
		||||
	public static void register() {
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.ench;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.ChatFormatting;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.MutableComponent;
 | 
			
		||||
import net.minecraft.world.effect.MobEffect;
 | 
			
		||||
import net.minecraft.world.effect.MobEffectInstance;
 | 
			
		||||
import net.minecraft.world.effect.MobEffectUtil;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public interface CustomDescEnchantment {
 | 
			
		||||
 | 
			
		||||
	default List<Component> descFull(int lv, String key, boolean alt, boolean book, EnchColor color) {
 | 
			
		||||
		return List.of(Component.translatable(key).withStyle(color.desc()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent perc(double val) {
 | 
			
		||||
		return Component.literal(Math.round(val * 100) + "%").withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent perc(int lv, double val, boolean alt) {
 | 
			
		||||
		return (alt ? Component.literal("[Lv]x" + (int) Math.round(val * 100) + "%") :
 | 
			
		||||
				Component.literal((int) Math.round(lv * val * 100) + "%"))
 | 
			
		||||
				.withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent percSmall(int lv, double val, boolean alt) {
 | 
			
		||||
		return (alt ? Component.literal("[Lv]x" + (int) Math.round(val * 10000) / 100d + "%") :
 | 
			
		||||
				Component.literal((int) Math.round(lv * val * 10000) / 100d + "%"))
 | 
			
		||||
				.withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent num(int val) {
 | 
			
		||||
		return Component.literal("" + val).withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent num(int lv, int val, boolean alt) {
 | 
			
		||||
		return (alt ? val == 1 ? Component.literal("[Lv]") : Component.literal("[Lv]x" + val) :
 | 
			
		||||
				Component.literal(lv * val + ""))
 | 
			
		||||
				.withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent numSmall(double val) {
 | 
			
		||||
		return Component.literal("" + val).withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent numSmall(int lv, double val, boolean alt) {
 | 
			
		||||
		return (alt ? val == 1 ? Component.literal("[Lv]") : Component.literal("[Lv]x" + val) :
 | 
			
		||||
				Component.literal(lv * val + ""))
 | 
			
		||||
				.withStyle(ChatFormatting.DARK_AQUA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Component ench(String key, MutableComponent... perc) {
 | 
			
		||||
		return Component.translatable(key, (Object[]) perc).withStyle(ChatFormatting.GRAY);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent eff(MobEffectInstance ins) {
 | 
			
		||||
		return eff(ins, true, true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent eff(MobEffectInstance ins, boolean showLevel, boolean showDuration) {
 | 
			
		||||
		MutableComponent desc = Component.translatable(ins.getDescriptionId());
 | 
			
		||||
		if (showLevel && ins.getAmplifier() > 0) {
 | 
			
		||||
			desc = Component.translatable("potion.withAmplifier", desc,
 | 
			
		||||
					Component.translatable("potion.potency." + ins.getAmplifier()));
 | 
			
		||||
		}
 | 
			
		||||
		if (showDuration && !ins.endsWithin(19)) {
 | 
			
		||||
			desc = Component.translatable("potion.withDuration", desc, MobEffectUtil.formatDuration(ins, 1, 20));
 | 
			
		||||
		}
 | 
			
		||||
		return desc.withStyle(ins.getEffect().value().getCategory().getTooltipFormatting());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static MutableComponent eff(MobEffect eff) {
 | 
			
		||||
		return eff.getDisplayName().copy().withStyle(eff.getCategory().getTooltipFormatting());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/main/java/dev/xkmc/l2core/init/reg/ench/EnchColor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/main/java/dev/xkmc/l2core/init/reg/ench/EnchColor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.ench;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.Codec;
 | 
			
		||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
 | 
			
		||||
import net.minecraft.ChatFormatting;
 | 
			
		||||
 | 
			
		||||
public record EnchColor(ChatFormatting base, ChatFormatting desc) {
 | 
			
		||||
 | 
			
		||||
	public static final EnchColor DEFAULT = new EnchColor(ChatFormatting.GRAY, ChatFormatting.DARK_GRAY);
 | 
			
		||||
 | 
			
		||||
	public static final Codec<EnchColor> CODEC = RecordCodecBuilder.create(i -> i.group(
 | 
			
		||||
			ChatFormatting.CODEC.fieldOf("base").forGetter(e -> e.base),
 | 
			
		||||
			ChatFormatting.CODEC.fieldOf("desc").forGetter(e -> e.desc)
 | 
			
		||||
	).apply(i, EnchColor::new));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.ench;
 | 
			
		||||
 | 
			
		||||
import com.tterrag.registrate.providers.RegistrateProvider;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.DataGenOnly;
 | 
			
		||||
import net.minecraft.core.Holder;
 | 
			
		||||
import net.minecraft.core.component.DataComponents;
 | 
			
		||||
@@ -169,6 +170,15 @@ public interface EnchVal {
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public <T> Builder special(EECVal.Special<T> type, T val) {
 | 
			
		||||
			this.effects.add(e -> e.withSpecialEffect(type.get(), List.of(val)));
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Builder color(EnchColor color) {
 | 
			
		||||
			return special(L2LibReg.COLOR, color);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Enchantment build(BootstrapContext<Enchantment> ctx, ResourceLocation id) {
 | 
			
		||||
			var items = ctx.registryLookup(Registries.ITEM).orElseThrow();
 | 
			
		||||
			var enchs = ctx.lookup(Registries.ENCHANTMENT);
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,14 @@ import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class LegacyEnchantment {
 | 
			
		||||
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static <T> T firstOf(Holder<Enchantment> ench, EECVal.Special<T> comp) {
 | 
			
		||||
		for (var e : ench.value().getEffects(comp.get())) {
 | 
			
		||||
			return Wrappers.cast(e);
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static <T> T firstOf(Holder<Enchantment> ench, Class<T> cls) {
 | 
			
		||||
		for (var e : ench.value().getEffects(L2LibReg.LEGACY.get())) {
 | 
			
		||||
@@ -62,8 +70,4 @@ public class LegacyEnchantment {
 | 
			
		||||
		return map;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<Component> descFull(int lv, String key, boolean alt, boolean book) {
 | 
			
		||||
		return List.of(Component.translatable(key).withStyle(ChatFormatting.DARK_GRAY));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,10 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
 | 
			
		||||
		return ConfigInit.register(this, ModConfig.Type.CLIENT, factory);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <T extends ConfigInit> T registerUnsynced(Function<ConfigInit.Builder, T> factory) {
 | 
			
		||||
		return ConfigInit.register(this, ModConfig.Type.COMMON, factory);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <T extends ConfigInit> T registerSynced(Function<ConfigInit.Builder, T> factory) {
 | 
			
		||||
		return ConfigInit.register(this, ModConfig.Type.SERVER, factory);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,14 @@
 | 
			
		||||
package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import dev.xkmc.l2core.init.L2Core;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import dev.xkmc.l2serial.util.Wrappers;
 | 
			
		||||
import net.neoforged.fml.config.ConfigTracker;
 | 
			
		||||
import net.neoforged.fml.config.IConfigSpec;
 | 
			
		||||
import net.neoforged.fml.config.ModConfig;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@@ -14,26 +17,36 @@ public class AbstractConfigParser {
 | 
			
		||||
 | 
			
		||||
	private static Map<String, ModConfig> getMap() {
 | 
			
		||||
		try {
 | 
			
		||||
			return Wrappers.cast(ConfigTracker.class.getDeclaredField("fileMap").get(ConfigTracker.INSTANCE));
 | 
			
		||||
			var field = ConfigTracker.class.getDeclaredField("fileMap");
 | 
			
		||||
			field.setAccessible(true);
 | 
			
		||||
			return Wrappers.cast(field.get(ConfigTracker.INSTANCE));
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			L2Core.LOGGER.throwing(e);
 | 
			
		||||
			return Map.of();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Optional<Object> parse(String path, List<String> line) {
 | 
			
		||||
	@Nullable
 | 
			
		||||
	private static IConfigSpec getSpec(String path) {
 | 
			
		||||
		var init = ConfigInit.get(path);
 | 
			
		||||
		if (init != null) return init.getSpec();
 | 
			
		||||
		var map = getMap();
 | 
			
		||||
		var file = map.get(path);
 | 
			
		||||
		if (file == null) {
 | 
			
		||||
			L2Core.LOGGER.warn("File {} is not a config file", path);
 | 
			
		||||
			return Optional.empty();
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		var spec = file.getSpec();
 | 
			
		||||
		if (!(spec instanceof ModConfigSpec modSpec) || !modSpec.isLoaded()){
 | 
			
		||||
		return file.getSpec();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Optional<Object> parse(String path, List<String> line) {
 | 
			
		||||
		var spec = getSpec(path);
 | 
			
		||||
		if (!(spec instanceof ModConfigSpec modSpec) || !modSpec.isLoaded()) {
 | 
			
		||||
			L2Core.LOGGER.warn("File {} is not a loaded config file", path);
 | 
			
		||||
			return Optional.empty();
 | 
			
		||||
		}
 | 
			
		||||
		return Optional.ofNullable(modSpec.getValues().get(line));
 | 
			
		||||
		return Optional.<ModConfigSpec.ConfigValue<?>>ofNullable(modSpec.getValues().get(line))
 | 
			
		||||
				.map(ModConfigSpec.ConfigValue::get);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.datafixers.util.Either;
 | 
			
		||||
import com.mojang.serialization.Codec;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.BooleanSupplier;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record BooleanConfigValue(String path, List<String> line) implements BooleanSupplier {
 | 
			
		||||
 | 
			
		||||
	public static BooleanConfigValue of(String file, ModConfigSpec.ConfigValue<Double> config) {
 | 
			
		||||
		return new BooleanConfigValue(file, config.getPath());
 | 
			
		||||
	public static <T extends ConfigInit> BooleanConfigValue of(T file, Function<T, ModConfigSpec.ConfigValue<Boolean>> config) {
 | 
			
		||||
		return new BooleanConfigValue(file.getPath(), config.apply(file).getPath());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static BooleanConfigValue of(String data) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.MapCodec;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
import net.neoforged.neoforge.common.conditions.ICondition;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record BooleanValueCondition(String path, ArrayList<String> line, boolean expected) implements ICondition {
 | 
			
		||||
 | 
			
		||||
	public static BooleanValueCondition of(String file, ModConfigSpec.ConfigValue<Boolean> config, boolean value) {
 | 
			
		||||
		return new BooleanValueCondition(file, new ArrayList<>(config.getPath()), value);
 | 
			
		||||
	public static <T extends ConfigInit> BooleanValueCondition of(T file, Function<T, ModConfigSpec.ConfigValue<Boolean>> config, boolean value) {
 | 
			
		||||
		return new BooleanValueCondition(file.getPath(), new ArrayList<>(config.apply(file).getPath()), value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.datafixers.util.Either;
 | 
			
		||||
import com.mojang.serialization.Codec;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.DoubleSupplier;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record DoubleConfigValue(String path, List<String> line) implements DoubleSupplier {
 | 
			
		||||
 | 
			
		||||
	public static DoubleConfigValue of(String file, ModConfigSpec.ConfigValue<Double> config) {
 | 
			
		||||
		return new DoubleConfigValue(file, config.getPath());
 | 
			
		||||
	public static <T extends ConfigInit> DoubleConfigValue of(T file, Function<T, ModConfigSpec.ConfigValue<Double>> config) {
 | 
			
		||||
		return new DoubleConfigValue(file.getPath(), config.apply(file).getPath());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static DoubleConfigValue of(String data) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.MapCodec;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
import net.neoforged.neoforge.common.conditions.ICondition;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record DoubleValueCondition(String path, ArrayList<String> line, double low, double high) implements ICondition {
 | 
			
		||||
 | 
			
		||||
	public static DoubleValueCondition of(String file, ModConfigSpec.ConfigValue<Double> config, double low, double high) {
 | 
			
		||||
		return new DoubleValueCondition(file, new ArrayList<>(config.getPath()), low, high);
 | 
			
		||||
	public static <T extends ConfigInit> DoubleValueCondition of(T file, Function<T, ModConfigSpec.ConfigValue<Double>> config, double low, double high) {
 | 
			
		||||
		return new DoubleValueCondition(file.getPath(), new ArrayList<>(config.apply(file).getPath()), low, high);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.datafixers.util.Either;
 | 
			
		||||
import com.mojang.serialization.Codec;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
import java.util.function.IntSupplier;
 | 
			
		||||
 | 
			
		||||
public record IntConfigValue(String path, List<String> line) implements IntSupplier {
 | 
			
		||||
 | 
			
		||||
	public static IntConfigValue of(String file, ModConfigSpec.ConfigValue<Integer> config) {
 | 
			
		||||
		return new IntConfigValue(file, config.getPath());
 | 
			
		||||
	public static <T extends ConfigInit> IntConfigValue of(T file, Function<T, ModConfigSpec.ConfigValue<Integer>> config) {
 | 
			
		||||
		return new IntConfigValue(file.getPath(), config.apply(file).getPath());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static IntConfigValue of(String data) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.MapCodec;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
import net.neoforged.neoforge.common.conditions.ICondition;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record IntValueCondition(String path, ArrayList<String> line, int low, int high) implements ICondition {
 | 
			
		||||
 | 
			
		||||
	public static IntValueCondition of(String file, ModConfigSpec.ConfigValue<Integer> config, int low, int high) {
 | 
			
		||||
		return new IntValueCondition(file, new ArrayList<>(config.getPath()), low, high);
 | 
			
		||||
	public static <T extends ConfigInit> IntValueCondition of(T file, Function<T, ModConfigSpec.ConfigValue<Double>> config, int low, int high) {
 | 
			
		||||
		return new IntValueCondition(file.getPath(), new ArrayList<>(config.apply(file).getPath()), low, high);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,18 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.MapCodec;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
import net.neoforged.neoforge.common.conditions.ICondition;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record ListStringValueCondition(String path, ArrayList<String> line, String key) implements ICondition {
 | 
			
		||||
 | 
			
		||||
	public static ListStringValueCondition of(String file, ModConfigSpec.ConfigValue<List<String>> config, String key) {
 | 
			
		||||
		return new ListStringValueCondition(file, new ArrayList<>(config.getPath()), key);
 | 
			
		||||
	public static <T extends ConfigInit> ListStringValueCondition of(T file, Function<T, ModConfigSpec.ConfigValue<Double>> config, String key) {
 | 
			
		||||
		return new ListStringValueCondition(file.getPath(), new ArrayList<>(config.apply(file).getPath()), key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,17 @@ package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.MapCodec;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.ConfigInit;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
import net.neoforged.neoforge.common.conditions.ICondition;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public record StringValueCondition(String path, ArrayList<String> line, String key) implements ICondition {
 | 
			
		||||
 | 
			
		||||
	public static StringValueCondition of(String file, ModConfigSpec.ConfigValue<String> config, String key) {
 | 
			
		||||
		return new StringValueCondition(file, new ArrayList<>(config.getPath()), key);
 | 
			
		||||
	public static <T extends ConfigInit> StringValueCondition of(T file, Function<T, ModConfigSpec.ConfigValue<Double>> config, String key) {
 | 
			
		||||
		return new StringValueCondition(file.getPath(), new ArrayList<>(config.apply(file).getPath()), key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
 
 | 
			
		||||
@@ -12,15 +12,35 @@ import net.neoforged.neoforge.client.gui.ConfigurationScreen;
 | 
			
		||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
public class ConfigInit {
 | 
			
		||||
 | 
			
		||||
	private static final ConcurrentHashMap<String, ConfigInit> MAP = new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static ConfigInit get(String path) {
 | 
			
		||||
		return MAP.get(path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String folder = null;
 | 
			
		||||
	private String path = "";
 | 
			
		||||
 | 
			
		||||
	public ModConfig.Type getType() {
 | 
			
		||||
		return type;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public IConfigSpec getSpec() {
 | 
			
		||||
		return spec;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private ModConfig.Type type;
 | 
			
		||||
	private IConfigSpec spec;
 | 
			
		||||
 | 
			
		||||
	public String getPath() {
 | 
			
		||||
		return path;
 | 
			
		||||
	}
 | 
			
		||||
@@ -52,6 +72,9 @@ public class ConfigInit {
 | 
			
		||||
		String path = val.folder + mod.getModId() + "-" + type.extension() + ".toml";
 | 
			
		||||
		mod.registerConfig(type, spec, path);
 | 
			
		||||
		val.path = path;
 | 
			
		||||
		val.type = type;
 | 
			
		||||
		val.spec = spec;
 | 
			
		||||
		MAP.put(path, val);
 | 
			
		||||
		RegistrateDistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> initClient(mod));
 | 
			
		||||
		reg.initConfigTitle(mod);
 | 
			
		||||
		String typeName = RegistrateLangProvider.toEnglishName(type.extension());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
  "l2core.title": "莱特兰·核心"
 | 
			
		||||
  "l2core.title": "莱特兰·核心",
 | 
			
		||||
  "l2core.configuration.addEnchantmentDescription": "附魔描述显示",
 | 
			
		||||
  "l2core.configuration.addEnchantmentDescription.tooltip": "包含莱特兰自身的依赖等级/配置的特殊附魔描述显示。\n其他附魔描述模组可能无法正常显示本模组部分附魔的描述。\n- DISABLE:关闭附魔描述\n- SHIFT_ONLY:只在按SHIFT时显示附魔描述\n- ALWAYS:永远显示附魔描述",
 | 
			
		||||
  "l2core.configuration.overlayZVal": "物品文字渲染高度",
 | 
			
		||||
  "l2core.configuration.overlayZVal.tooltip": "默认值:250",
 | 
			
		||||
  "l2core.configuration.section.l2configs.l2core.client.toml": "莱特兰核心 - 客户端配置",
 | 
			
		||||
  "l2core.configuration.section.l2configs.l2core.client.toml.title": "莱特兰核心 - 客户端配置",
 | 
			
		||||
  "l2core.configuration.title": "莱特兰核心 - 配置"
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user