enchantment improvements
This commit is contained in:
		@@ -19,7 +19,7 @@ import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
public class PatchouliHelper {
 | 
			
		||||
 | 
			
		||||
	public static final ProviderType<PatchouliProvider> PATCHOULI = ProviderType.register("patchouli", (p, e) -> new PatchouliProvider(p, e.getLookupProvider(), e.getGenerator()));
 | 
			
		||||
	public static final ProviderType<PatchouliProvider> PATCHOULI = ProviderType.register("patchouli", PatchouliProvider::new);
 | 
			
		||||
 | 
			
		||||
	public static ItemStack getBook(ResourceLocation book) {
 | 
			
		||||
		return ItemStack.EMPTY; // TODO ItemModBook.forBook(book);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import com.tterrag.registrate.providers.RegistrateProvider;
 | 
			
		||||
import dev.xkmc.l2core.serial.config.RecordDataProvider;
 | 
			
		||||
import net.minecraft.core.HolderLookup;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.data.PackOutput;
 | 
			
		||||
import net.neoforged.fml.LogicalSide;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
@@ -16,8 +17,8 @@ public class PatchouliProvider extends RecordDataProvider implements RegistrateP
 | 
			
		||||
 | 
			
		||||
	private BiConsumer<String, Record> map;
 | 
			
		||||
 | 
			
		||||
	public PatchouliProvider(AbstractRegistrate<?> owner, CompletableFuture<HolderLookup.Provider> pvd, DataGenerator gen) {
 | 
			
		||||
		super(gen, pvd, "Patchouli Provider");
 | 
			
		||||
	public PatchouliProvider(AbstractRegistrate<?> owner, PackOutput output, CompletableFuture<HolderLookup.Provider> pvd) {
 | 
			
		||||
		super(output, pvd, "Patchouli Provider");
 | 
			
		||||
		this.owner = owner;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
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;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,16 +10,19 @@ import net.minecraft.resources.ResourceLocation;
 | 
			
		||||
import net.minecraft.tags.TagKey;
 | 
			
		||||
import net.minecraft.world.effect.MobEffect;
 | 
			
		||||
import net.minecraft.world.entity.ai.attributes.Attribute;
 | 
			
		||||
import net.minecraft.world.item.enchantment.Enchantment;
 | 
			
		||||
 | 
			
		||||
public class L2TagGen {
 | 
			
		||||
 | 
			
		||||
	public static <T> ProviderType<RegistrateTagsProvider.IntrinsicImpl<T>> getProvider(ResourceKey<Registry<T>> id, Registry<T> reg) {
 | 
			
		||||
		String name = id.location().getPath();
 | 
			
		||||
		return ProviderType.register("tags/" + name,
 | 
			
		||||
				type -> (p, e) -> new RegistrateTagsProvider.IntrinsicImpl<>(p, type, name,
 | 
			
		||||
						e.getGenerator().getPackOutput(), id, e.getLookupProvider(),
 | 
			
		||||
						ench -> reg.getResourceKey(ench).get(),
 | 
			
		||||
						e.getExistingFileHelper()));
 | 
			
		||||
		return ProviderType.registerIntrinsicTag("tags/" + name, name, id,
 | 
			
		||||
				ench -> reg.getResourceKey(ench).orElseThrow());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> ProviderType<RegistrateTagsProvider.Impl<T>> getProvider(ResourceKey<Registry<T>> id) {
 | 
			
		||||
		String name = id.location().getPath();
 | 
			
		||||
		return ProviderType.registerDynamicTag("tags/" + name, name, id);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static final ProviderType<RegistrateTagsProvider.IntrinsicImpl<MobEffect>> EFF_TAGS =
 | 
			
		||||
@@ -28,6 +31,9 @@ public class L2TagGen {
 | 
			
		||||
	public static final ProviderType<RegistrateTagsProvider.IntrinsicImpl<Attribute>> ATTR_TAGS =
 | 
			
		||||
			getProvider(Registries.ATTRIBUTE, BuiltInRegistries.ATTRIBUTE);
 | 
			
		||||
 | 
			
		||||
	public static final ProviderType<RegistrateTagsProvider.Impl<Enchantment>> ENCH_TAGS =
 | 
			
		||||
			getProvider(Registries.ENCHANTMENT);
 | 
			
		||||
 | 
			
		||||
	public static final TagKey<MobEffect> TRACKED_EFFECTS = effectTag(ResourceLocation.fromNamespaceAndPath(L2Core.MODID, "tracked_effects"));
 | 
			
		||||
 | 
			
		||||
	public static void onEffectTagGen(RegistrateTagsProvider.IntrinsicImpl<MobEffect> pvd) {
 | 
			
		||||
 
 | 
			
		||||
@@ -106,14 +106,14 @@ public interface EECVal<T> extends Val<DataComponentType<List<ConditionalEffect<
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	interface Special<T> extends Val<DataComponentType<T>> {
 | 
			
		||||
	interface Special<T> extends Val<DataComponentType<List<T>>> {
 | 
			
		||||
 | 
			
		||||
		record Impl<T>(
 | 
			
		||||
				DeferredHolder<DataComponentType<?>, DataComponentType<T>> val
 | 
			
		||||
				DeferredHolder<DataComponentType<?>, DataComponentType<List<T>>> val
 | 
			
		||||
		) implements Special<T> {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public DataComponentType<T> get() {
 | 
			
		||||
			public DataComponentType<List<T>> get() {
 | 
			
		||||
				return val.get();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.ench;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.core.Holder;
 | 
			
		||||
import net.minecraft.world.item.enchantment.Enchantment;
 | 
			
		||||
 | 
			
		||||
public record EnchHolder<T>(Holder<Enchantment> holder, T val, int lv) {
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +1,18 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.ench;
 | 
			
		||||
 | 
			
		||||
import com.mojang.serialization.Codec;
 | 
			
		||||
import com.tterrag.registrate.providers.ProviderType;
 | 
			
		||||
import com.tterrag.registrate.providers.RegistrateTagsProvider;
 | 
			
		||||
import cpw.mods.util.Lazy;
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.init.L2TagGen;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.simple.Reg;
 | 
			
		||||
import net.minecraft.core.HolderLookup;
 | 
			
		||||
import net.minecraft.core.component.DataComponentType;
 | 
			
		||||
import net.minecraft.core.registries.BuiltInRegistries;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.data.tags.TagsProvider;
 | 
			
		||||
import net.minecraft.data.worldgen.BootstrapContext;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.tags.TagKey;
 | 
			
		||||
import net.minecraft.util.Unit;
 | 
			
		||||
import net.minecraft.world.item.enchantment.ConditionalEffect;
 | 
			
		||||
import net.minecraft.world.item.enchantment.Enchantment;
 | 
			
		||||
@@ -24,8 +25,10 @@ import net.neoforged.neoforge.registries.DeferredRegister;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
import java.util.function.UnaryOperator;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("unused")
 | 
			
		||||
public class EnchReg {
 | 
			
		||||
 | 
			
		||||
	public static EnchReg of(Reg reg, L2Registrate pvd) {
 | 
			
		||||
@@ -33,13 +36,19 @@ public class EnchReg {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private final DeferredRegister<DataComponentType<?>> reg;
 | 
			
		||||
	private final DeferredRegister<LegacyEnchantment> legacy;
 | 
			
		||||
	private final L2Registrate pvd;
 | 
			
		||||
 | 
			
		||||
	private final List<EnchVal.Impl> list = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
	private EnchReg(Reg reg, L2Registrate pvd) {
 | 
			
		||||
		this.reg = reg.make(BuiltInRegistries.ENCHANTMENT_EFFECT_COMPONENT_TYPE);
 | 
			
		||||
		this.legacy = reg.make(L2LibReg.ENCH.get());
 | 
			
		||||
		this.pvd = pvd;
 | 
			
		||||
		pvd.addDataGenerator(L2TagGen.ENCH_TAGS, this::doTagGen);
 | 
			
		||||
		var init = pvd.getDataGenInitializer();
 | 
			
		||||
		init.add(Registries.ENCHANTMENT, this::build);
 | 
			
		||||
		init.addDependency(ProviderType.DYNAMIC, L2TagGen.ENCH_TAGS);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private <T> DeferredHolder<DataComponentType<?>, DataComponentType<T>> reg(String id, Codec<T> codec) {
 | 
			
		||||
@@ -51,7 +60,7 @@ public class EnchReg {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <T> EECVal.Special<T> special(String id, Codec<T> codec) {
 | 
			
		||||
		return new EECVal.Special.Impl<>(reg(id, codec));
 | 
			
		||||
		return new EECVal.Special.Impl<>(reg(id, codec.listOf()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <T> EECVal<T> eff(String id, Codec<T> codec, LootContextParamSet loot) {
 | 
			
		||||
@@ -65,33 +74,42 @@ public class EnchReg {
 | 
			
		||||
		).listOf()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public EnchVal ench(String id, String name, String desc, UnaryOperator<EnchVal.Builder> cons) {
 | 
			
		||||
	private <T extends EnchVal.Impl> T enchBase(String id, String name, String desc, Function<ResourceKey<Enchantment>, T> factory) {
 | 
			
		||||
		var key = ResourceKey.create(Registries.ENCHANTMENT, pvd.loc(id));
 | 
			
		||||
		pvd.addRawLang("enchantment." + pvd.getModid() + "." + id, name);
 | 
			
		||||
		pvd.addRawLang("enchantment." + pvd.getModid() + "." + id + ".desc", desc);
 | 
			
		||||
		var ans = new EnchVal.Simple(key, Lazy.of(() -> cons.apply(new EnchVal.Builder(key.location()))));
 | 
			
		||||
		var ans = factory.apply(key);
 | 
			
		||||
		list.add(ans);
 | 
			
		||||
		return ans;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public EnchVal ench(String id, String name, String desc, UnaryOperator<EnchVal.Builder> cons) {
 | 
			
		||||
		return enchBase(id, name, desc, key -> new EnchVal.Simple(key,
 | 
			
		||||
				Lazy.of(() -> cons.apply(new EnchVal.Builder(key.location())))));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public EnchVal.Flag enchFlag(String id, String name, String desc, UnaryOperator<EnchVal.Builder> cons) {
 | 
			
		||||
		var key = ResourceKey.create(Registries.ENCHANTMENT, pvd.loc(id));
 | 
			
		||||
		pvd.addRawLang("enchantment." + pvd.getModid() + "." + id, name);
 | 
			
		||||
		pvd.addRawLang("enchantment." + pvd.getModid() + "." + id + ".desc", desc);
 | 
			
		||||
		var unit = unit(id);
 | 
			
		||||
		var ans = new EnchVal.FlagImpl(unit, key, Lazy.of(() -> cons.apply(new EnchVal.Builder(key.location()).effect(e -> e.withEffect(unit.get())))));
 | 
			
		||||
		list.add(ans);
 | 
			
		||||
		return ans;
 | 
			
		||||
		return enchBase(id, name, desc, key -> new EnchVal.FlagImpl(unit, key,
 | 
			
		||||
				Lazy.of(() -> cons.apply(new EnchVal.Builder(key.location()).effect(e ->
 | 
			
		||||
						e.withEffect(unit.get()))))));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public EnchVal enchLegacy(String id, String name, String desc, UnaryOperator<EnchVal.Builder> cons, Supplier<LegacyEnchantment> factory) {
 | 
			
		||||
		var unit = legacy.register(id, factory);
 | 
			
		||||
		return enchBase(id, name, desc, key -> new EnchVal.Simple(key,
 | 
			
		||||
				Lazy.of(() -> cons.apply(new EnchVal.Builder(key.location()).effect(e ->
 | 
			
		||||
						e.withSpecialEffect(L2LibReg.LEGACY.get(), List.of(unit.get())))))));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void build(BootstrapContext<Enchantment> ctx) {
 | 
			
		||||
		for (var e : list) ctx.register(e.id(), e.builder().get().build(ctx, e.id().location()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void doTagGen(Function<TagKey<Enchantment>, TagsProvider.TagAppender<Enchantment>> func, HolderLookup.Provider pvd) {
 | 
			
		||||
	public void doTagGen(RegistrateTagsProvider<Enchantment> pvd) {
 | 
			
		||||
		for (var e : list) {
 | 
			
		||||
			for (var t : e.builder().get().tags) {
 | 
			
		||||
				func.apply(t).add(e.id());
 | 
			
		||||
				pvd.addTag(t).add(e.id());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,69 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.ench;
 | 
			
		||||
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2serial.util.Wrappers;
 | 
			
		||||
import net.minecraft.ChatFormatting;
 | 
			
		||||
import net.minecraft.core.Holder;
 | 
			
		||||
import net.minecraft.core.component.DataComponents;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.world.entity.EquipmentSlot;
 | 
			
		||||
import net.minecraft.world.entity.LivingEntity;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.enchantment.Enchantment;
 | 
			
		||||
import net.minecraft.world.item.enchantment.ItemEnchantments;
 | 
			
		||||
import net.neoforged.neoforge.common.CommonHooks;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class LegacyEnchantment {
 | 
			
		||||
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static <T> T firstOf(Holder<Enchantment> ench, Class<T> cls) {
 | 
			
		||||
		for (var e : ench.value().getEffects(L2LibReg.LEGACY.get())) {
 | 
			
		||||
			if (cls.isInstance(e)) {
 | 
			
		||||
				return Wrappers.cast(e);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> Optional<T> findFirst(Holder<Enchantment> ench, Class<T> cls) {
 | 
			
		||||
		return Optional.ofNullable(firstOf(ench, cls));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> List<EnchHolder<T>> findAll(ItemStack stack, Class<T> cls, boolean intrinsic) {
 | 
			
		||||
		var reg = CommonHooks.resolveLookup(Registries.ENCHANTMENT);
 | 
			
		||||
		if (reg == null) return List.of();
 | 
			
		||||
		List<EnchHolder<T>> ans = new ArrayList<>();
 | 
			
		||||
		ItemEnchantments enchs = intrinsic ?
 | 
			
		||||
				stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY) :
 | 
			
		||||
				stack.getAllEnchantments(reg);
 | 
			
		||||
		for (var e : enchs.entrySet()) {
 | 
			
		||||
			var t = firstOf(e.getKey(), cls);
 | 
			
		||||
			if (t != null) ans.add(new EnchHolder<>(e.getKey(), t, e.getIntValue()));
 | 
			
		||||
		}
 | 
			
		||||
		return ans;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> Map<T, Integer> accumulateOnEntity(LivingEntity le, Class<T> cls, boolean intrinsic) {
 | 
			
		||||
		LinkedHashMap<T, Integer> map = new LinkedHashMap<>();
 | 
			
		||||
		for (EquipmentSlot slot : EquipmentSlot.values()) {
 | 
			
		||||
			ItemStack stack = le.getItemBySlot(slot);
 | 
			
		||||
			if (stack.isEmpty() || !stack.isEnchanted()) continue;
 | 
			
		||||
			var list = findAll(stack, cls, intrinsic);
 | 
			
		||||
			for (var e : list) {
 | 
			
		||||
				if (e.holder().value().matchingSlot(slot)) {
 | 
			
		||||
					map.compute(e.val(), (k, v) -> (v == null ? 0 : v) + e.lv());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return map;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<Component> descFull(int lv, String key, boolean alt, boolean book) {
 | 
			
		||||
		return List.of(Component.translatable(key).withStyle(ChatFormatting.DARK_GRAY));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,13 +6,19 @@ import com.tterrag.registrate.builders.BuilderCallback;
 | 
			
		||||
import com.tterrag.registrate.builders.NoConfigBuilder;
 | 
			
		||||
import com.tterrag.registrate.providers.RegistrateLangProvider;
 | 
			
		||||
import com.tterrag.registrate.util.OneTimeEventReceiver;
 | 
			
		||||
import com.tterrag.registrate.util.RegistrateDistExecutor;
 | 
			
		||||
import com.tterrag.registrate.util.entry.RegistryEntry;
 | 
			
		||||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
 | 
			
		||||
import com.tterrag.registrate.util.nullness.NonnullType;
 | 
			
		||||
import dev.xkmc.l2core.init.L2Core;
 | 
			
		||||
import dev.xkmc.l2core.init.reg.simple.Val;
 | 
			
		||||
import dev.xkmc.l2serial.serialization.custom_handler.CodecHandler;
 | 
			
		||||
import dev.xkmc.l2serial.util.Wrappers;
 | 
			
		||||
import net.minecraft.client.particle.ParticleEngine;
 | 
			
		||||
import net.minecraft.client.particle.ParticleProvider;
 | 
			
		||||
import net.minecraft.core.Registry;
 | 
			
		||||
import net.minecraft.core.particles.ParticleOptions;
 | 
			
		||||
import net.minecraft.core.particles.ParticleType;
 | 
			
		||||
import net.minecraft.core.registries.BuiltInRegistries;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.network.chat.Component;
 | 
			
		||||
@@ -25,7 +31,9 @@ import net.minecraft.world.item.CreativeModeTabs;
 | 
			
		||||
import net.minecraft.world.item.Item;
 | 
			
		||||
import net.minecraft.world.item.Items;
 | 
			
		||||
import net.minecraft.world.item.alchemy.Potion;
 | 
			
		||||
import net.neoforged.api.distmarker.Dist;
 | 
			
		||||
import net.neoforged.fml.ModLoadingContext;
 | 
			
		||||
import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent;
 | 
			
		||||
import net.neoforged.neoforge.data.loading.DatagenModLoader;
 | 
			
		||||
import net.neoforged.neoforge.registries.NewRegistryEvent;
 | 
			
		||||
import net.neoforged.neoforge.registries.RegistryBuilder;
 | 
			
		||||
@@ -81,6 +89,16 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
 | 
			
		||||
		return new SimpleEntry<>(ans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <T extends ParticleOptions, R extends ParticleType<T>> Val<R>
 | 
			
		||||
	particle(String name, NonNullSupplier<R> sup, NonNullSupplier<? extends ParticleSupplier<T>> pvd) {
 | 
			
		||||
		RegistryEntry<ParticleType<?>, R> ans = entry(name, (cb) -> new NoConfigBuilder<>(this, this, name, cb,
 | 
			
		||||
				Registries.PARTICLE_TYPE, sup)).register();
 | 
			
		||||
		RegistrateDistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
 | 
			
		||||
				OneTimeEventReceiver.addModListener(this, RegisterParticleProvidersEvent.class,
 | 
			
		||||
						event -> pvd.get().register(event, ans.get())));
 | 
			
		||||
		return new Val.Registrate<>(ans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings({"unsafe"})
 | 
			
		||||
	public <E> RegistryInstance<E> newRegistry(String id, Class<?> cls, Consumer<RegistryBuilder<E>> cons) {
 | 
			
		||||
		ResourceKey<Registry<E>> key = ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(getModid(), id));
 | 
			
		||||
@@ -215,4 +233,22 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public interface ParticleSupplier<T extends ParticleOptions> {
 | 
			
		||||
 | 
			
		||||
		static <T extends ParticleOptions> ParticleSupplier<T> provider(ParticleProvider<T> pvd) {
 | 
			
		||||
			return (event, type) -> event.registerSpecial(type, pvd);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static <T extends ParticleOptions> ParticleSupplier<T> sprite(ParticleProvider.Sprite<T> pvd) {
 | 
			
		||||
			return (event, type) -> event.registerSprite(type, pvd);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static <T extends ParticleOptions> ParticleSupplier<T> spriteSet(ParticleEngine.SpriteParticleRegistration<T> pvd) {
 | 
			
		||||
			return (event, type) -> event.registerSpriteSet(type, pvd);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void register(RegisterParticleProvidersEvent event, ParticleType<T> type);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -11,6 +11,7 @@ import net.minecraft.network.chat.Component;
 | 
			
		||||
import net.minecraft.network.chat.ComponentSerialization;
 | 
			
		||||
import net.minecraft.network.codec.ByteBufCodecs;
 | 
			
		||||
import net.minecraft.network.codec.StreamCodec;
 | 
			
		||||
import net.minecraft.util.Unit;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.neoforged.neoforge.registries.DeferredHolder;
 | 
			
		||||
import net.neoforged.neoforge.registries.DeferredRegister;
 | 
			
		||||
@@ -34,6 +35,10 @@ public record DCReg(DeferredRegister<DataComponentType<?>> reg) {
 | 
			
		||||
		return reg(id, cdc, cdc.toNetwork(), cache);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public DCVal<Unit> unit(String id) {
 | 
			
		||||
		return reg(id, Unit.CODEC, StreamCodec.unit(Unit.INSTANCE), false);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public DCVal<Integer> intVal(String id) {
 | 
			
		||||
		return reg(id, Codec.INT, ByteBufCodecs.INT, false);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,15 +19,15 @@ public record SR<T>(DeferredRegister<T> reg) {
 | 
			
		||||
		return new SR<>(parent.make(reg));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <H extends T> Val<H> reg(String id, Supplier<H> sup) {
 | 
			
		||||
	public <H extends T> ValImpl<T, H> reg(String id, Supplier<H> sup) {
 | 
			
		||||
		return new ValImpl<>(reg.register(id, sup));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public <H extends T> Val<H> reg(String id, Function<ResourceLocation, H> sup) {
 | 
			
		||||
	public <H extends T> ValImpl<T, H> reg(String id, Function<ResourceLocation, H> sup) {
 | 
			
		||||
		return new ValImpl<>(reg.register(id, sup));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private record ValImpl<R, T extends R>(DeferredHolder<R, T> val) implements Val<T> {
 | 
			
		||||
	public record ValImpl<R, T extends R>(DeferredHolder<R, T> val) implements Val<T> {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public T get() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,20 @@
 | 
			
		||||
package dev.xkmc.l2core.init.reg.simple;
 | 
			
		||||
 | 
			
		||||
import com.tterrag.registrate.util.entry.RegistryEntry;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
public interface Val<T> extends Supplier<T> {
 | 
			
		||||
 | 
			
		||||
	T get();
 | 
			
		||||
 | 
			
		||||
	record Registrate<H, T extends H>(RegistryEntry<H, T> entry) implements Val<T> {
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public T get() {
 | 
			
		||||
			return entry.get();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
package dev.xkmc.l2core.mixin;
 | 
			
		||||
 | 
			
		||||
import net.neoforged.fml.config.ConfigTracker;
 | 
			
		||||
import net.neoforged.fml.config.ModConfig;
 | 
			
		||||
import org.spongepowered.asm.mixin.Mixin;
 | 
			
		||||
import org.spongepowered.asm.mixin.gen.Accessor;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
 | 
			
		||||
@Mixin(ConfigTracker.class)
 | 
			
		||||
public interface ConfigTrackerAccessor {
 | 
			
		||||
 | 
			
		||||
	@Accessor
 | 
			
		||||
	public ConcurrentHashMap<String, ModConfig> getFileMap();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -6,6 +6,7 @@ import net.minecraft.core.HolderLookup;
 | 
			
		||||
import net.minecraft.data.CachedOutput;
 | 
			
		||||
import net.minecraft.data.DataGenerator;
 | 
			
		||||
import net.minecraft.data.DataProvider;
 | 
			
		||||
import net.minecraft.data.PackOutput;
 | 
			
		||||
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -16,13 +17,13 @@ import java.util.concurrent.CompletableFuture;
 | 
			
		||||
import java.util.function.BiConsumer;
 | 
			
		||||
 | 
			
		||||
public abstract class RecordDataProvider implements DataProvider {
 | 
			
		||||
	private final DataGenerator generator;
 | 
			
		||||
	private final PackOutput output;
 | 
			
		||||
	private final CompletableFuture<HolderLookup.Provider> pvd;
 | 
			
		||||
	private final String name;
 | 
			
		||||
	private final Map<String, Record> map = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
	public RecordDataProvider(DataGenerator generator, CompletableFuture<HolderLookup.Provider> pvd, String name) {
 | 
			
		||||
		this.generator = generator;
 | 
			
		||||
	public RecordDataProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> pvd, String name) {
 | 
			
		||||
		this.output = output;
 | 
			
		||||
		this.pvd = pvd;
 | 
			
		||||
		this.name = name;
 | 
			
		||||
	}
 | 
			
		||||
@@ -31,7 +32,7 @@ public abstract class RecordDataProvider implements DataProvider {
 | 
			
		||||
 | 
			
		||||
	public CompletableFuture<?> run(CachedOutput cache) {
 | 
			
		||||
		return pvd.thenCompose(pvd -> {
 | 
			
		||||
			Path folder = this.generator.getPackOutput().getOutputFolder();
 | 
			
		||||
			Path folder = output.getOutputFolder();
 | 
			
		||||
			this.add(this.map::put);
 | 
			
		||||
			List<CompletableFuture<?>> list = new ArrayList<>();
 | 
			
		||||
			this.map.forEach((k, v) -> {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
package dev.xkmc.l2core.serial.configval;
 | 
			
		||||
 | 
			
		||||
import dev.xkmc.l2core.mixin.ConfigTrackerAccessor;
 | 
			
		||||
import net.neoforged.fml.config.ConfigTracker;
 | 
			
		||||
import net.neoforged.neoforge.common.ModConfigSpec;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@@ -8,8 +10,11 @@ import java.util.Optional;
 | 
			
		||||
public class AbstractConfigParser {
 | 
			
		||||
 | 
			
		||||
	public static Optional<Object> parse(String path, List<String> line) {
 | 
			
		||||
		return Optional.ofNullable(ConfigTracker.INSTANCE.fileMap().get(path))
 | 
			
		||||
				.map(file -> file.getConfigData().get(line));
 | 
			
		||||
		var file = ((ConfigTrackerAccessor) ConfigTracker.INSTANCE).getFileMap().get(path);
 | 
			
		||||
		if (file == null) return Optional.empty();
 | 
			
		||||
		var spec = file.getSpec();
 | 
			
		||||
		if (!(spec instanceof ModConfigSpec modSpec) || !modSpec.isLoaded()) return Optional.empty();
 | 
			
		||||
		return Optional.ofNullable(modSpec.getValues().get(line));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,11 @@
 | 
			
		||||
package dev.xkmc.l2core.serial.ingredients;
 | 
			
		||||
 | 
			
		||||
import dev.xkmc.l2core.init.L2LibReg;
 | 
			
		||||
import dev.xkmc.l2core.util.DataGenOnly;
 | 
			
		||||
import net.minecraft.core.Holder;
 | 
			
		||||
import net.minecraft.core.HolderLookup;
 | 
			
		||||
import net.minecraft.core.registries.Registries;
 | 
			
		||||
import net.minecraft.resources.ResourceKey;
 | 
			
		||||
import net.minecraft.world.item.EnchantedBookItem;
 | 
			
		||||
import net.minecraft.world.item.ItemStack;
 | 
			
		||||
import net.minecraft.world.item.crafting.Ingredient;
 | 
			
		||||
@@ -20,6 +24,12 @@ public record EnchantmentIngredient(Holder<Enchantment> enchantment, int minLeve
 | 
			
		||||
		return new EnchantmentIngredient(ench, min).toVanilla();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@DataGenOnly
 | 
			
		||||
	public static Ingredient of(HolderLookup.Provider pvd, ResourceKey<Enchantment> ench, int min) {
 | 
			
		||||
		var holder = pvd.lookup(Registries.ENCHANTMENT).orElseThrow().getOrThrow(ench);
 | 
			
		||||
		return of(holder, min);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public Stream<ItemStack> getItems() {
 | 
			
		||||
		var ench = enchantment.value();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								src/main/java/dev/xkmc/l2core/util/TeleportTool.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/main/java/dev/xkmc/l2core/util/TeleportTool.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
package dev.xkmc.l2core.util;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.core.BlockPos;
 | 
			
		||||
import net.minecraft.server.level.ServerLevel;
 | 
			
		||||
import net.minecraft.server.level.ServerPlayer;
 | 
			
		||||
import net.minecraft.util.Mth;
 | 
			
		||||
import net.minecraft.world.entity.Entity;
 | 
			
		||||
import net.minecraft.world.entity.LivingEntity;
 | 
			
		||||
import net.minecraft.world.entity.PathfinderMob;
 | 
			
		||||
import net.minecraft.world.level.Level;
 | 
			
		||||
import net.minecraft.world.level.portal.DimensionTransition;
 | 
			
		||||
import net.neoforged.neoforge.event.EventHooks;
 | 
			
		||||
import net.neoforged.neoforge.event.entity.EntityTeleportEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class TeleportTool {
 | 
			
		||||
 | 
			
		||||
	public static void teleportHome(ServerLevel world, ServerPlayer player) {
 | 
			
		||||
		DimensionTransition respawn = player.findRespawnPositionAndUseSpawnBlock(true, DimensionTransition.DO_NOTHING);
 | 
			
		||||
		if (world == respawn.newLevel()) {
 | 
			
		||||
			player.moveTo(respawn.pos(), respawn.yRot(), respawn.xRot());
 | 
			
		||||
		} else {
 | 
			
		||||
			var pos = respawn.pos();
 | 
			
		||||
			performTeleport(player, respawn.newLevel(), pos.x, pos.y, pos.z, respawn.yRot(), respawn.xRot());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static void performTeleport(Entity e, ServerLevel level, double x, double y, double z, float yaw, float pitch) {
 | 
			
		||||
		EntityTeleportEvent.TeleportCommand event = EventHooks.onEntityTeleportCommand(e, x, y, z);
 | 
			
		||||
		if (event.isCanceled()) return;
 | 
			
		||||
		x = event.getTargetX();
 | 
			
		||||
		y = event.getTargetY();
 | 
			
		||||
		z = event.getTargetZ();
 | 
			
		||||
		BlockPos blockpos = BlockPos.containing(x, y, z);
 | 
			
		||||
		if (!Level.isInSpawnableBounds(blockpos)) return;
 | 
			
		||||
		float yr = Mth.wrapDegrees(yaw);
 | 
			
		||||
		float xr = Mth.wrapDegrees(pitch);
 | 
			
		||||
		if (e.teleportTo(level, x, y, z, Set.of(), yr, xr)) {
 | 
			
		||||
			if (e instanceof LivingEntity le) {
 | 
			
		||||
				if (!le.isFallFlying()) {
 | 
			
		||||
					e.setDeltaMovement(e.getDeltaMovement().multiply(1.0, 0.0, 1.0));
 | 
			
		||||
					e.setOnGround(true);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (e instanceof PathfinderMob mob) {
 | 
			
		||||
				mob.getNavigation().stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
  "package": "dev.xkmc.l2core.mixin",
 | 
			
		||||
  "compatibilityLevel": "JAVA_21",
 | 
			
		||||
  "mixins": [
 | 
			
		||||
	"ConfigTrackerAccessor"
 | 
			
		||||
  ],
 | 
			
		||||
  "client": [
 | 
			
		||||
  ],
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user