diff --git a/gradle.properties b/gradle.properties index 300dea9..b6d3036 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ loader_version_range=[2,) mod_id=l2core mod_name=L2Core mod_license=LGPL-2.1 -mod_version=3.0.5-pre1 +mod_version=3.0.5-pre6 mod_group_id=dev.xkmc mod_authors=lcy0x1 mod_description=Core Library mod for all L2 mods diff --git a/src/main/java/dev/xkmc/l2core/init/reg/datapack/EnchReg.java b/src/main/java/dev/xkmc/l2core/init/reg/datapack/EnchReg.java new file mode 100644 index 0000000..4c219fd --- /dev/null +++ b/src/main/java/dev/xkmc/l2core/init/reg/datapack/EnchReg.java @@ -0,0 +1,86 @@ +package dev.xkmc.l2core.init.reg.datapack; + +import com.mojang.serialization.Codec; +import cpw.mods.util.Lazy; +import dev.xkmc.l2core.init.reg.registrate.L2Registrate; +import dev.xkmc.l2core.init.reg.simple.DCReg; +import dev.xkmc.l2core.init.reg.simple.DCVal; +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.Enchantment; +import net.minecraft.world.item.enchantment.effects.EnchantmentValueEffect; +import net.neoforged.neoforge.registries.DeferredRegister; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.function.UnaryOperator; + +public class EnchReg { + + public static EnchReg of(Reg reg, L2Registrate pvd) { + return new EnchReg(reg, pvd); + } + + private final DeferredRegister> reg; + private final L2Registrate pvd; + + private final List list = new ArrayList<>(); + + private EnchReg(Reg reg, L2Registrate pvd) { + this.reg = reg.make(BuiltInRegistries.ENCHANTMENT_EFFECT_COMPONENT_TYPE); + this.pvd = pvd; + } + + public DCVal reg(String id, Codec codec) { + return new DCReg.DCValImpl<>(reg.register(id, () -> DataComponentType.builder().persistent(codec).build())); + } + + public DCVal unit(String id) { + return reg(id, Unit.CODEC); + } + + public DCVal val(String id) { + return reg(id, EnchantmentValueEffect.CODEC); + } + + public EnchVal ench(String id, String name, String desc, UnaryOperator 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 ans = new EnchVal.Simple(key, Lazy.of(() -> cons.apply(new EnchVal.Builder()))); + list.add(ans); + return ans; + } + + public EnchVal.Flag enchFlag(String id, String name, String desc, UnaryOperator 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().effect(e -> e.withEffect(unit.get()))))); + list.add(ans); + return ans; + } + + public void build(BootstrapContext ctx) { + for (var e : list) ctx.register(e.id(), e.builder().get().build(ctx, e.id().location())); + } + + public void doTagGen(Function, TagsProvider.TagAppender> func, HolderLookup.Provider pvd) { + for (var e : list) { + for (var t : e.builder().get().tags) { + func.apply(t).add(e.id()); + } + } + } + +} diff --git a/src/main/java/dev/xkmc/l2core/init/reg/datapack/EnchVal.java b/src/main/java/dev/xkmc/l2core/init/reg/datapack/EnchVal.java new file mode 100644 index 0000000..e89911d --- /dev/null +++ b/src/main/java/dev/xkmc/l2core/init/reg/datapack/EnchVal.java @@ -0,0 +1,131 @@ +package dev.xkmc.l2core.init.reg.datapack; + +import cpw.mods.util.Lazy; +import dev.xkmc.l2core.init.reg.simple.DCVal; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Unit; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.enchantment.Enchantment; +import net.neoforged.neoforge.common.Tags; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +public interface EnchVal { + + ResourceKey id(); + + interface Impl extends EnchVal { + Lazy builder(); + } + + interface Flag extends EnchVal { + DCVal unit(); + } + + record Simple(ResourceKey id, Lazy builder) implements Impl { + + } + + record FlagImpl(DCVal unit, ResourceKey id, Lazy builder) implements Flag, Impl { + + } + + class Builder { + + private TagKey supported, primary; + private Enchantment.Cost min, max; + private EquipmentSlotGroup group; + private int weight = 1, maxLevel = 1, anvilCost = 1; + @Nullable + private TagKey exclude; + private final List> effects = new ArrayList<>(); + + final List> tags = new ArrayList<>(); + + Builder() { + supported = primary = Tags.Items.ENCHANTABLES; + min = max = new Enchantment.Cost(10, 5); + group = EquipmentSlotGroup.ANY; + } + + public Builder transform(UnaryOperator func) { + return func.apply(this); + } + + public Builder items(TagKey items) { + return items(items, items); + } + + public Builder items(TagKey supported, TagKey primary) { + this.supported = supported; + this.primary = primary; + return this; + } + + public Builder cost(int base, int slope, int range) { + min = new Enchantment.Cost(base, slope); + max = new Enchantment.Cost(base + range, slope); + return this; + } + + public Builder weight(int weight) { + this.weight = weight; + return this; + } + + public Builder anvilCost(int cost) { + this.anvilCost = cost; + return this; + } + + public Builder maxLevel(int lv) { + this.maxLevel = lv; + return this; + } + + public Builder group(EquipmentSlotGroup group) { + this.group = group; + return this; + } + + public Builder exclusive(TagKey tag) { + this.exclude = tag; + return this; + } + + @SafeVarargs + public final Builder tags(TagKey... tags) { + this.tags.addAll(List.of(tags)); + return this; + } + + public Builder effect(Consumer effect) { + this.effects.add(effect); + return this; + } + + Enchantment build(BootstrapContext ctx, ResourceLocation id) { + var items = ctx.registryLookup(Registries.ITEM).orElseThrow(); + var enchs = ctx.registryLookup(Registries.ENCHANTMENT).orElseThrow(); + var ans = Enchantment.enchantment(Enchantment.definition( + items.getOrThrow(supported), + items.getOrThrow(primary), + weight, maxLevel, + min, max, anvilCost, group)); + if (exclude != null) ans.exclusiveWith(enchs.getOrThrow(exclude)); + for (var e : effects) e.accept(ans); + return ans.build(id); + } + + } + +} diff --git a/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java b/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java index 7687902..5b72893 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/registrate/L2Registrate.java @@ -25,8 +25,6 @@ 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; @@ -66,7 +64,7 @@ public class L2Registrate extends AbstractRegistrate { return entry(name, cb -> new NoConfigBuilder<>(this, this, name, cb, Registries.MOB_EFFECT, sup)); } - private SimpleEntry genPotion(String name, NonNullSupplier sup) { + public SimpleEntry potion(String name, NonNullSupplier sup) { RegistryEntry ans = entry(name, (cb) -> new NoConfigBuilder<>(this, this, name, cb, Registries.POTION, sup)).register(); if (doDataGen.get()) { diff --git a/src/main/java/dev/xkmc/l2core/init/reg/simple/AttVal.java b/src/main/java/dev/xkmc/l2core/init/reg/simple/AttVal.java index a78426c..dc47c58 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/simple/AttVal.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/simple/AttVal.java @@ -5,7 +5,6 @@ import dev.xkmc.l2core.capability.attachment.GeneralCapabilityHolder; import dev.xkmc.l2core.capability.attachment.GeneralCapabilityTemplate; import dev.xkmc.l2core.capability.player.PlayerCapabilityHolder; import dev.xkmc.l2core.capability.player.PlayerCapabilityTemplate; -import net.minecraft.world.entity.player.Player; import net.neoforged.neoforge.attachment.AttachmentHolder; import net.neoforged.neoforge.attachment.AttachmentType; diff --git a/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java b/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java index 4da7b12..cdb5991 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/simple/DCReg.java @@ -64,7 +64,7 @@ public record DCReg(DeferredRegister> reg) { return reg(id, ComponentSerialization.CODEC, ComponentSerialization.STREAM_CODEC, true); } - private record DCValImpl(DeferredHolder, DataComponentType> val) implements DCVal { + public record DCValImpl(DeferredHolder, DataComponentType> val) implements DCVal { @Override public DataComponentType get() { diff --git a/src/main/java/dev/xkmc/l2core/init/reg/simple/IngVal.java b/src/main/java/dev/xkmc/l2core/init/reg/simple/IngVal.java index 55da7a6..c0c9926 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/simple/IngVal.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/simple/IngVal.java @@ -1,6 +1,5 @@ package dev.xkmc.l2core.init.reg.simple; -import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.common.crafting.ICustomIngredient; import net.neoforged.neoforge.common.crafting.IngredientType; diff --git a/src/main/java/dev/xkmc/l2core/init/reg/simple/SR.java b/src/main/java/dev/xkmc/l2core/init/reg/simple/SR.java index b34ff78..1801d22 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/simple/SR.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/simple/SR.java @@ -2,32 +2,38 @@ package dev.xkmc.l2core.init.reg.simple; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; +import java.util.function.Function; import java.util.function.Supplier; public record SR(DeferredRegister reg) { - public static SR of(Reg parent, Registry reg) { - return new SR<>(parent.make(reg)); - } + public static SR of(Reg parent, Registry reg) { + return new SR<>(parent.make(reg)); + } - public static SR of(Reg parent, ResourceKey> reg) { - return new SR<>(parent.make(reg)); - } + public static SR of(Reg parent, ResourceKey> reg) { + return new SR<>(parent.make(reg)); + } - public Val reg(String id, Supplier sup) { - return new ValImpl<>(reg.register(id, sup)); - } + public Val reg(String id, Supplier sup) { + return new ValImpl<>(reg.register(id, sup)); + } - private record ValImpl(DeferredHolder val) implements Val { + public Val reg(String id, Function sup) { + return new ValImpl<>(reg.register(id, sup)); + } - @Override - public T get() { - return val.get(); - } + private record ValImpl(DeferredHolder val) implements Val { - } + @Override + public T get() { + return val.get(); + } + + } } diff --git a/src/main/java/dev/xkmc/l2core/init/reg/simple/package-info.java b/src/main/java/dev/xkmc/l2core/init/reg/simple/package-info.java index 6519e00..397b020 100644 --- a/src/main/java/dev/xkmc/l2core/init/reg/simple/package-info.java +++ b/src/main/java/dev/xkmc/l2core/init/reg/simple/package-info.java @@ -1,8 +1,10 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault +@FieldsAreNonnullByDefault package dev.xkmc.l2core.init.reg.simple; +import net.minecraft.FieldsAreNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/dev/xkmc/l2core/serial/config/ConfigDataProvider.java b/src/main/java/dev/xkmc/l2core/serial/config/ConfigDataProvider.java index d6229b1..83a6f1d 100644 --- a/src/main/java/dev/xkmc/l2core/serial/config/ConfigDataProvider.java +++ b/src/main/java/dev/xkmc/l2core/serial/config/ConfigDataProvider.java @@ -19,13 +19,12 @@ import java.util.concurrent.CompletableFuture; public abstract class ConfigDataProvider implements DataProvider { private final DataGenerator generator; - private final HolderLookup.Provider pvd; + private final CompletableFuture pvd; private final String name; - private final Map> map = new HashMap<>(); - public ConfigDataProvider(DataGenerator generator, HolderLookup.Provider pvd, String name) { + public ConfigDataProvider(DataGenerator generator, CompletableFuture pvd, String name) { this.generator = generator; this.pvd = pvd; this.name = name; @@ -35,17 +34,19 @@ public abstract class ConfigDataProvider implements DataProvider { @Override public CompletableFuture run(CachedOutput cache) { - Path folder = generator.getPackOutput().getOutputFolder(); - add(new Collector(map)); - List> list = new ArrayList<>(); - map.forEach((k, v) -> { - JsonElement elem = v.serialize(pvd); - if (elem != null) { - Path path = folder.resolve(k + ".json"); - list.add(DataProvider.saveStable(cache, elem, path)); - } + return pvd.thenCompose(lookup -> { + Path folder = generator.getPackOutput().getOutputFolder(); + add(new Collector(map)); + List> list = new ArrayList<>(); + map.forEach((k, v) -> { + JsonElement elem = v.serialize(lookup); + if (elem != null) { + Path path = folder.resolve(k + ".json"); + list.add(DataProvider.saveStable(cache, elem, path)); + } + }); + return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new)); }); - return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new)); } @Override diff --git a/src/main/java/dev/xkmc/l2core/serial/loot/AddItemModifier.java b/src/main/java/dev/xkmc/l2core/serial/loot/AddItemModifier.java index e6e08ea..f55f636 100644 --- a/src/main/java/dev/xkmc/l2core/serial/loot/AddItemModifier.java +++ b/src/main/java/dev/xkmc/l2core/serial/loot/AddItemModifier.java @@ -1,6 +1,5 @@ package dev.xkmc.l2core.serial.loot; -import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.xkmc.l2core.serial.configval.DoubleConfigValue; @@ -21,54 +20,52 @@ import java.util.function.DoubleSupplier; public class AddItemModifier extends LootModifier { - public static final Codec CODEC = RecordCodecBuilder.create(i -> LootModifier.codecStart(i).and(i.group( - BuiltInRegistries.ITEM.byNameCodec().fieldOf("item").forGetter(m -> m.item), - BuiltInRegistries.ITEM.byNameCodec().optionalFieldOf("fail").forGetter(m -> m.fail == Items.AIR ? Optional.empty() : Optional.of(m.fail)), - DoubleConfigValue.CODEC.optionalFieldOf("chance") - .forGetter(m -> Optional.ofNullable(m.chance)) - )).apply(i, AddItemModifier::new)); + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(i -> LootModifier.codecStart(i).and(i.group( + BuiltInRegistries.ITEM.byNameCodec().fieldOf("item").forGetter(m -> m.item), + BuiltInRegistries.ITEM.byNameCodec().optionalFieldOf("fail").forGetter(m -> m.fail == Items.AIR ? Optional.empty() : Optional.of(m.fail)), + DoubleConfigValue.CODEC.optionalFieldOf("chance") + .forGetter(m -> Optional.ofNullable(m.chance)) + )).apply(i, AddItemModifier::new)); - public static final MapCodec MAP_CODEC = CODEC.dispatchMap(e -> e, AddItemModifier::codec); + public final Item item, fail; - public final Item item, fail; + @Nullable + public final DoubleSupplier chance; - @Nullable - public final DoubleSupplier chance; + protected AddItemModifier(LootItemCondition[] conditionsIn, Item item, Optional fail, Optional chance) { + super(conditionsIn); + this.item = item; + this.fail = fail.orElse(Items.AIR); + this.chance = chance.orElse(null); + } - protected AddItemModifier(LootItemCondition[] conditionsIn, Item item, Optional fail, Optional chance) { - super(conditionsIn); - this.item = item; - this.fail = fail.orElse(Items.AIR); - this.chance = chance.orElse(null); - } + public AddItemModifier(Item item, @Nullable DoubleConfigValue chance, LootItemCondition... conditionsIn) { + this(item, Items.AIR, chance, conditionsIn); + } - public AddItemModifier(Item item, @Nullable DoubleConfigValue chance, LootItemCondition... conditionsIn) { - this(item, Items.AIR, chance, conditionsIn); - } + public AddItemModifier(Item item, Item fail, @Nullable DoubleConfigValue chance, LootItemCondition... conditionsIn) { + super(conditionsIn); + this.item = item; + this.fail = fail; + this.chance = chance; + } - public AddItemModifier(Item item, Item fail, @Nullable DoubleConfigValue chance, LootItemCondition... conditionsIn) { - super(conditionsIn); - this.item = item; - this.fail = fail; - this.chance = chance; - } + @Override + protected @NotNull ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { + if (!context.hasParam(LootContextParams.DAMAGE_SOURCE)) { + return generatedLoot; + } + if (chance == null || context.getRandom().nextDouble() <= chance.getAsDouble()) { + generatedLoot.add(new ItemStack(item)); + } else if (fail != Items.AIR) { + generatedLoot.add(new ItemStack(fail)); + } + return generatedLoot; + } - @Override - protected @NotNull ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { - if (!context.hasParam(LootContextParams.DAMAGE_SOURCE)) { - return generatedLoot; - } - if (chance == null || context.getRandom().nextDouble() <= chance.getAsDouble()) { - generatedLoot.add(new ItemStack(item)); - } else if (fail != Items.AIR) { - generatedLoot.add(new ItemStack(fail)); - } - return generatedLoot; - } - - @Override - public MapCodec codec() { - return MAP_CODEC; - } + @Override + public MapCodec codec() { + return MAP_CODEC; + } } diff --git a/src/main/java/dev/xkmc/l2core/serial/loot/AddLootTableModifier.java b/src/main/java/dev/xkmc/l2core/serial/loot/AddLootTableModifier.java index 5f97512..cbd30b0 100644 --- a/src/main/java/dev/xkmc/l2core/serial/loot/AddLootTableModifier.java +++ b/src/main/java/dev/xkmc/l2core/serial/loot/AddLootTableModifier.java @@ -1,6 +1,5 @@ package dev.xkmc.l2core.serial.loot; -import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -18,35 +17,33 @@ import static net.minecraft.world.level.storage.loot.LootTable.createStackSplitt public class AddLootTableModifier extends LootModifier { - public static final Codec CODEC = RecordCodecBuilder.create(inst -> codecStart(inst) - .and(ResourceLocation.CODEC.fieldOf("lootTable").forGetter((m) -> m.lootTable)) - .apply(inst, AddLootTableModifier::new)); + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(inst -> codecStart(inst) + .and(ResourceLocation.CODEC.fieldOf("lootTable").forGetter((m) -> m.lootTable)) + .apply(inst, AddLootTableModifier::new)); - public static final MapCodec MAP_CODEC = CODEC.dispatchMap(e -> e, AddLootTableModifier::codec); + private final ResourceLocation lootTable; - private final ResourceLocation lootTable; + protected AddLootTableModifier(LootItemCondition[] conditionsIn, ResourceLocation lootTable) { + super(conditionsIn); + this.lootTable = lootTable; + } - protected AddLootTableModifier(LootItemCondition[] conditionsIn, ResourceLocation lootTable) { - super(conditionsIn); - this.lootTable = lootTable; - } + public AddLootTableModifier(ResourceLocation lootTable, LootItemCondition... conditionsIn) { + super(conditionsIn); + this.lootTable = lootTable; + } - public AddLootTableModifier(ResourceLocation lootTable, LootItemCondition... conditionsIn) { - super(conditionsIn); - this.lootTable = lootTable; - } + @Nonnull + @Override + protected ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { + var extraTable = context.getResolver().lookupOrThrow(Registries.LOOT_TABLE) + .getOrThrow(ResourceKey.create(Registries.LOOT_TABLE, this.lootTable)).value(); + extraTable.getRandomItemsRaw(context, createStackSplitter(context.getLevel(), generatedLoot::add)); + return generatedLoot; + } - @Nonnull - @Override - protected ObjectArrayList doApply(ObjectArrayList generatedLoot, LootContext context) { - var extraTable = context.getResolver().lookupOrThrow(Registries.LOOT_TABLE) - .getOrThrow(ResourceKey.create(Registries.LOOT_TABLE, this.lootTable)).value(); - extraTable.getRandomItemsRaw(context, createStackSplitter(context.getLevel(), generatedLoot::add)); - return generatedLoot; - } - - @Override - public MapCodec codec() { - return MAP_CODEC; - } + @Override + public MapCodec codec() { + return MAP_CODEC; + } } \ No newline at end of file