This commit is contained in:
lcy0x1
2024-06-25 10:04:11 +08:00
parent 71cff815cd
commit f1028dcb31
85 changed files with 211 additions and 1383 deletions

View File

@@ -1,31 +0,0 @@
package dev.xkmc.l2core.events;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
import net.minecraft.util.profiling.ProfilerFiller;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Map;
import java.util.function.Consumer;
@ParametersAreNonnullByDefault
public class BaseJsonReloadListener extends SimpleJsonResourceReloadListener {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
private final Consumer<Map<ResourceLocation, JsonElement>> consumer;
public BaseJsonReloadListener(String path, Consumer<Map<ResourceLocation, JsonElement>> consumer) {
super(GSON, path);
this.consumer = consumer;
}
@Override
protected void apply(Map<ResourceLocation, JsonElement> map, ResourceManager manager, ProfilerFiller profiler) {
consumer.accept(map);
}
}

View File

@@ -2,10 +2,9 @@ package dev.xkmc.l2core.events;
import dev.xkmc.l2core.base.effects.EffectToClient;
import dev.xkmc.l2core.init.L2Core;
import dev.xkmc.l2core.init.L2TagGen;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.LivingEntity;
import net.neoforged.bus.api.SubscribeEvent;
@@ -16,20 +15,19 @@ import net.neoforged.neoforge.event.entity.player.PlayerEvent;
@EventBusSubscriber(modid = L2Core.MODID, bus = EventBusSubscriber.Bus.GAME)
public class EffectSyncEvents {
public static final TagKey<MobEffect> SYNCED = TagKey.create(Registries.MOB_EFFECT, L2Core.loc("synced"));
private static boolean isTracked(Holder<MobEffect> eff) {
return eff.is(SYNCED);
return eff.is(L2TagGen.TRACKED_EFFECTS);
}
@SubscribeEvent
public static void onPotionAddedEvent(MobEffectEvent.Added event) {
if (isTracked(event.getEffectInstance().getEffect())) {
var ins = event.getEffectInstance();
if (ins == null) return;
if (isTracked(ins.getEffect())) {
onEffectAppear(event.getEffectInstance().getEffect(), event.getEntity(), event.getEffectInstance().getAmplifier());
}
}
@SubscribeEvent
public static void onPotionRemoveEvent(MobEffectEvent.Remove event) {
if (event.getEffectInstance() != null && isTracked(event.getEffectInstance().getEffect())) {
@@ -37,7 +35,6 @@ public class EffectSyncEvents {
}
}
@SubscribeEvent
public static void onPotionExpiryEvent(MobEffectEvent.Expired event) {
if (event.getEffectInstance() != null && isTracked(event.getEffectInstance().getEffect())) {

View File

@@ -3,6 +3,7 @@ package dev.xkmc.l2core.init;
import dev.xkmc.l2core.base.effects.EffectToClient;
import dev.xkmc.l2core.capability.conditionals.TokenToClient;
import dev.xkmc.l2core.capability.player.PlayerCapToClient;
import dev.xkmc.l2core.init.reg.registrate.L2Registrate;
import dev.xkmc.l2serial.network.PacketHandler;
import dev.xkmc.l2serial.serialization.custom_handler.Handlers;
import net.minecraft.resources.ResourceLocation;
@@ -24,7 +25,7 @@ public class L2Core {
public static final String MODID = "l2core";
public static final Logger LOGGER = LogManager.getLogger();
// TODO public static final L2Registrate REGISTRATE = new L2Registrate(MODID);
public static final L2Registrate REGISTRATE = new L2Registrate(MODID);
public static final PacketHandler PACKET_HANDLER = new PacketHandler(MODID, 1,
e -> e.create(EffectToClient.class, PLAY_TO_CLIENT),
@@ -36,6 +37,7 @@ public class L2Core {
Handlers.register();
L2LibReg.register(bus);
REGISTRATE.addDataGenerator(L2TagGen.EFF_TAGS, L2TagGen::onEffectTagGen);
}
@SubscribeEvent

View File

@@ -0,0 +1,32 @@
package dev.xkmc.l2core.init;
import com.tterrag.registrate.providers.ProviderType;
import com.tterrag.registrate.providers.RegistrateTagsProvider;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.effect.MobEffect;
public class L2TagGen {
public static final ProviderType<RegistrateTagsProvider.IntrinsicImpl<MobEffect>> EFF_TAGS =
ProviderType.register("tags/mob_effect",
type -> (p, e) -> new RegistrateTagsProvider.IntrinsicImpl<>(p, type, "mob_effects",
e.getGenerator().getPackOutput(), Registries.MOB_EFFECT, e.getLookupProvider(),
ench -> ResourceKey.create(Registries.MOB_EFFECT, BuiltInRegistries.MOB_EFFECT.getKey(ench)),
e.getExistingFileHelper()));
public static final TagKey<MobEffect> TRACKED_EFFECTS = effectTag(ResourceLocation.fromNamespaceAndPath(L2Core.MODID, "tracked_effects"));
public static void onEffectTagGen(RegistrateTagsProvider.IntrinsicImpl<MobEffect> pvd) {
pvd.addTag(TRACKED_EFFECTS);
}
public static TagKey<MobEffect> effectTag(ResourceLocation id) {
return TagKey.create(Registries.MOB_EFFECT, id);
}
}

View File

@@ -0,0 +1,17 @@
package dev.xkmc.l2core.init.reg.registrate;
import com.tterrag.registrate.util.entry.RegistryEntry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.effect.MobEffect;
public record EffectEntry<T extends MobEffect>(RegistryEntry<MobEffect, T> val) {
ResourceKey<MobEffect> key() {
return val.getKey();
}
T get() {
return val.get();
}
}

View File

@@ -1,92 +1,151 @@
package dev.xkmc.l2core.init.reg.registrate;
import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.AbstractBuilder;
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.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.l2serial.serialization.custom_handler.CodecHandler;
import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.item.CreativeModeTab;
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.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeType;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.neoforge.data.loading.DatagenModLoader;
import net.neoforged.neoforge.registries.NewRegistryEvent;
import net.neoforged.neoforge.registries.RegistryBuilder;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.function.Supplier;
@SuppressWarnings("unused")
public class L2Registrate extends AbstractRegistrate<L2Registrate> {
public final NonNullSupplier<Boolean> doDataGen = NonNullSupplier.lazy(DatagenModLoader::isRunningDataGen);
public L2Registrate(String modid) {
super(modid);
registerEventListeners(FMLJavaModLoadingContext.get().getModEventBus());
var bus = ModLoadingContext.get().getActiveContainer().getEventBus();
if (bus != null) registerEventListeners(bus);
else L2Core.LOGGER.error("Failed to register mod {}", modid);
}
public <T extends NamedEntry<T>, P extends T> GenericBuilder<T, P> generic(RegistryInstance<T> cls, String id, NonNullSupplier<P> sup) {
public ResourceLocation loc(String id) {
return ResourceLocation.fromNamespaceAndPath(getModid(), id);
}
public <T, P extends T> GenericBuilder<T, P> generic(RegistryInstance<T> cls, String id, NonNullSupplier<P> sup) {
return entry(id, cb -> new GenericBuilder<>(this, id, cb, cls.key(), sup));
}
public <T extends Recipe<?>> RegistryEntry<RecipeType<T>> recipe(String id) {
return simple(id, ForgeRegistries.Keys.RECIPE_TYPES, () -> new RecipeType<>() {
});
}
@Deprecated
@Override
public <T extends Enchantment> EnchantmentBuilder<T, L2Registrate> enchantment(String name, EnchantmentCategory type, EnchantmentBuilder.EnchantmentFactory<T> factory) {
return super.enchantment(name, type, factory);
}
public <T extends Enchantment> EnchantmentBuilder<T, L2Registrate> enchantment(String name, EnchantmentCategory type, EnchantmentBuilder.EnchantmentFactory<T> factory, String desc) {
addRawLang("enchantment." + getModid() + "." + name + ".desc", desc);
return super.enchantment(name, type, factory);
public <T extends Recipe<?>> RecipeTypeEntry<T> recipe(String id) {
return new RecipeTypeEntry<>(simple(id, Registries.RECIPE_TYPE, () -> new RecipeType<>() {
@Override
public String toString() {
return getModid() + ":" + id;
}
}));
}
public <T extends MobEffect> NoConfigBuilder<MobEffect, T, L2Registrate> effect(String name, NonNullSupplier<T> sup, String desc) {
addRawLang("effect." + getModid() + "." + name + ".description", desc);
return entry(name, cb -> new NoConfigBuilder<>(this, this, name, cb, ForgeRegistries.Keys.MOB_EFFECTS, sup));
addRawLang("effect." + getModid() + "." + name + ".desc", desc);
return entry(name, cb -> new NoConfigBuilder<>(this, this, name, cb, Registries.MOB_EFFECT, sup));
}
@SuppressWarnings({"unchecked", "unsafe"})
public <E extends NamedEntry<E>> RegistryInstance<E> newRegistry(String id, Class<?> cls, Consumer<RegistryBuilder<E>> cons) {
ResourceKey<Registry<E>> key = makeRegistry(id, () -> {
var ans = new RegistryBuilder<E>();
ans.onCreate((r, s) -> new RLClassHandler<>((Class<E>) cls, () -> r));
cons.accept(ans);
return ans;
});
return new RegistryInstance<>(Suppliers.memoize(() -> RegistryManager.ACTIVE.getRegistry(key)), key);
private <T extends Potion> SimpleEntry<Potion> genPotion(String name, NonNullSupplier<T> sup) {
RegistryEntry<Potion, T> ans = entry(name, (cb) -> new NoConfigBuilder<>(this, this, name, cb,
Registries.POTION, sup)).register();
if (doDataGen.get()) {
List<Item> list = List.of(Items.POTION, Items.SPLASH_POTION, Items.LINGERING_POTION, Items.TIPPED_ARROW);
for (Item item : list) {
String pref = item.getDescriptionId();
String[] prefs = pref.split("\\.");
String str = item.getDescriptionId() + ".effect." + name;
String pref_name = RegistrateLangProvider.toEnglishName(prefs[prefs.length - 1]);
if (item == Items.TIPPED_ARROW) pref_name = "Arrow";
addRawLang(str, pref_name + " of " + RegistrateLangProvider.toEnglishName(name));
}
}
return new SimpleEntry<>(ans);
}
public <E extends NamedEntry<E>> RegistryInstance<E> newRegistry(String id, Class<?> cls) {
@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));
var ans = new RegistryBuilder<>(key);
cons.accept(ans);
var reg = ans.create();
new CodecHandler<>(Wrappers.cast(cls), reg.byNameCodec(), ByteBufCodecs.fromCodecWithRegistries(reg.byNameCodec()));
OneTimeEventReceiver.addModListener(this, NewRegistryEvent.class, (e) -> e.register(reg));
return new RegistryInstance<>(reg, key);
}
public <E> RegistryInstance<E> newRegistry(String id, Class<?> cls) {
return newRegistry(id, cls, e -> {
});
}
public synchronized RegistryEntry<CreativeModeTab> buildModCreativeTab(String name, String def, Consumer<CreativeModeTab.Builder> config) {
ResourceLocation id = new ResourceLocation(getModid(), name);
public synchronized SimpleEntry<CreativeModeTab> buildModCreativeTab(String name, String def, Consumer<CreativeModeTab.Builder> config) {
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(getModid(), name);
defaultCreativeTab(ResourceKey.create(Registries.CREATIVE_MODE_TAB, id));
return buildCreativeTabImpl(name, this.addLang("itemGroup", id, def), config);
return buildCreativeTabImpl(name, addLang("itemGroup", id, def), config);
}
public synchronized RegistryEntry<CreativeModeTab> buildL2CreativeTab(String name, String def, Consumer<CreativeModeTab.Builder> config) {
ResourceLocation id = new ResourceLocation(L2Library.MODID, name);
public synchronized SimpleEntry<CreativeModeTab> buildL2CreativeTab(String name, String def, Consumer<CreativeModeTab.Builder> config) {
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(L2Core.MODID, name);
defaultCreativeTab(ResourceKey.create(Registries.CREATIVE_MODE_TAB, id));
TabSorter sorter = new TabSorter(getModid() + ":" + name, id);
return L2Library.REGISTRATE.buildCreativeTabImpl(name, this.addLang("itemGroup", id, def), b -> {
return L2Core.REGISTRATE.buildCreativeTabImpl(name, addLang("itemGroup", id, def), b -> {
config.accept(b);
sorter.sort(b);
});
}
private synchronized RegistryEntry<CreativeModeTab> buildCreativeTabImpl(String name, Component comp, Consumer<CreativeModeTab.Builder> config) {
return this.generic(self(), name, Registries.CREATIVE_MODE_TAB, () -> {
private synchronized SimpleEntry<CreativeModeTab> buildCreativeTabImpl(String name, Component comp, Consumer<CreativeModeTab.Builder> config) {
return new SimpleEntry<>(this.generic(self(), name, Registries.CREATIVE_MODE_TAB, () -> {
var builder = CreativeModeTab.builder().title(comp)
.withTabsBefore(CreativeModeTabs.SPAWN_EGGS);
config.accept(builder);
return builder.build();
}).register();
}).register());
}
public record RegistryInstance<E extends NamedEntry<E>>(Supplier<IForgeRegistry<E>> supplier,
ResourceKey<Registry<E>> key) implements Supplier<IForgeRegistry<E>> {
public record RegistryInstance<E>(
Registry<E> reg,
ResourceKey<Registry<E>> key
) implements Supplier<Registry<E>> {
@Override
public IForgeRegistry<E> get() {
return supplier().get();
public Registry<E> get() {
return reg;
}
}
public static class GenericBuilder<T extends NamedEntry<T>, P extends T> extends AbstractBuilder<T, P, L2Registrate, GenericBuilder<T, P>> {
public static class GenericBuilder<T, P extends T> extends AbstractBuilder<T, P, L2Registrate, GenericBuilder<T, P>> {
private final NonNullSupplier<P> sup;
@@ -101,7 +160,9 @@ public class L2Registrate extends AbstractRegistrate<L2Registrate> {
}
public GenericBuilder<T, P> defaultLang() {
return lang(NamedEntry::getDescriptionId, RegistrateLangProvider.toEnglishName(this.getName()));
var reg = getRegistryKey().location();
String id = reg.getPath() + "." + getOwner().getModid() + "." + getName();
return lang(e -> id, RegistrateLangProvider.toEnglishName(this.getName()));
}
}

View File

@@ -1,21 +1,26 @@
package dev.xkmc.l2core.init.reg.registrate;
/*TODO
import dev.xkmc.l2serial.util.Wrappers;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
public class NamedEntry<T extends NamedEntry<T>> {
private final L2Registrate.RegistryInstance<T> registry;
private String desc = null;
private ResourceLocation id = null;
public NamedEntry(L2Registrate.RegistryInstance<T> registry) {
this.registry = registry;
}
public @NotNull String getDescriptionId() {
public String getDescriptionId() {
if (desc != null)
return desc;
ResourceLocation rl = getRegistryName();
ResourceLocation reg = registry.get().getRegistryName();
ResourceLocation reg = registry.key().location();
desc = reg.getPath() + "." + rl.getNamespace() + "." + rl.getPath();
return desc;
}
@@ -25,7 +30,12 @@ public class NamedEntry<T extends NamedEntry<T>> {
}
public ResourceLocation getRegistryName() {
return Objects.requireNonNull(registry.get().getKey(getThis()));
if (id != null) return id;
id = registry.get().getKey(getThis());
if (id == null) {
throw new IllegalStateException("Entry %s is not registered".formatted(getClass().getSimpleName()));
}
return id;
}
public String getID() {
@@ -37,4 +47,3 @@ public class NamedEntry<T extends NamedEntry<T>> {
}
}
*/

View File

@@ -0,0 +1,18 @@
package dev.xkmc.l2core.init.reg.registrate;
import com.tterrag.registrate.util.entry.RegistryEntry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeType;
public record RecipeTypeEntry<T extends Recipe<?>>(RegistryEntry<RecipeType<?>, RecipeType<T>> val) {
ResourceKey<RecipeType<?>> key() {
return val.getKey();
}
RecipeType<T> get() {
return val.get();
}
}

View File

@@ -0,0 +1,16 @@
package dev.xkmc.l2core.init.reg.registrate;
import com.tterrag.registrate.util.entry.RegistryEntry;
import net.minecraft.resources.ResourceKey;
public record SimpleEntry<T>(RegistryEntry<T, ? extends T> val) {
ResourceKey<T> key() {
return val.getKey();
}
T get() {
return val.get();
}
}

View File

@@ -2,7 +2,6 @@ package dev.xkmc.l2core.serial.recipe;
import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.data.recipes.RecipeOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
@@ -12,7 +11,7 @@ import net.minecraft.world.item.crafting.ShapelessRecipe;
import net.neoforged.neoforge.common.conditions.ICondition;
import org.jetbrains.annotations.Nullable;
public record NBTRecipeWrapper(RecipeOutput pvd, ItemStack stack) implements RecipeOutput {
public record DataRecipeWrapper(RecipeOutput pvd, ItemStack stack) implements RecipeOutput {
@Override
public Advancement.Builder advancement() {