This commit is contained in:
lcy0x1
2024-07-12 10:01:53 +08:00
parent 66e91ea647
commit c879440d94
12 changed files with 321 additions and 105 deletions

View File

@@ -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

View File

@@ -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<DataComponentType<?>> reg;
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.pvd = pvd;
}
public <T> DCVal<T> reg(String id, Codec<T> codec) {
return new DCReg.DCValImpl<>(reg.register(id, () -> DataComponentType.<T>builder().persistent(codec).build()));
}
public DCVal<Unit> unit(String id) {
return reg(id, Unit.CODEC);
}
public DCVal<EnchantmentValueEffect> val(String id) {
return reg(id, EnchantmentValueEffect.CODEC);
}
public EnchVal ench(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 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<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().effect(e -> e.withEffect(unit.get())))));
list.add(ans);
return ans;
}
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) {
for (var e : list) {
for (var t : e.builder().get().tags) {
func.apply(t).add(e.id());
}
}
}
}

View File

@@ -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<Enchantment> id();
interface Impl extends EnchVal {
Lazy<Builder> builder();
}
interface Flag extends EnchVal {
DCVal<Unit> unit();
}
record Simple(ResourceKey<Enchantment> id, Lazy<Builder> builder) implements Impl {
}
record FlagImpl(DCVal<Unit> unit, ResourceKey<Enchantment> id, Lazy<Builder> builder) implements Flag, Impl {
}
class Builder {
private TagKey<Item> supported, primary;
private Enchantment.Cost min, max;
private EquipmentSlotGroup group;
private int weight = 1, maxLevel = 1, anvilCost = 1;
@Nullable
private TagKey<Enchantment> exclude;
private final List<Consumer<Enchantment.Builder>> effects = new ArrayList<>();
final List<TagKey<Enchantment>> tags = new ArrayList<>();
Builder() {
supported = primary = Tags.Items.ENCHANTABLES;
min = max = new Enchantment.Cost(10, 5);
group = EquipmentSlotGroup.ANY;
}
public Builder transform(UnaryOperator<Builder> func) {
return func.apply(this);
}
public Builder items(TagKey<Item> items) {
return items(items, items);
}
public Builder items(TagKey<Item> supported, TagKey<Item> 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<Enchantment> tag) {
this.exclude = tag;
return this;
}
@SafeVarargs
public final Builder tags(TagKey<Enchantment>... tags) {
this.tags.addAll(List.of(tags));
return this;
}
public Builder effect(Consumer<Enchantment.Builder> effect) {
this.effects.add(effect);
return this;
}
Enchantment build(BootstrapContext<Enchantment> 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);
}
}
}

View File

@@ -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<L2Registrate> {
return entry(name, cb -> new NoConfigBuilder<>(this, this, name, cb, Registries.MOB_EFFECT, sup));
}
private <T extends Potion> SimpleEntry<Potion> genPotion(String name, NonNullSupplier<T> sup) {
public <T extends Potion> SimpleEntry<Potion> potion(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()) {

View File

@@ -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;

View File

@@ -64,7 +64,7 @@ public record DCReg(DeferredRegister<DataComponentType<?>> reg) {
return reg(id, ComponentSerialization.CODEC, ComponentSerialization.STREAM_CODEC, true);
}
private record DCValImpl<T>(DeferredHolder<DataComponentType<?>, DataComponentType<T>> val) implements DCVal<T> {
public record DCValImpl<T>(DeferredHolder<DataComponentType<?>, DataComponentType<T>> val) implements DCVal<T> {
@Override
public DataComponentType<T> get() {

View File

@@ -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;

View File

@@ -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<T>(DeferredRegister<T> reg) {
public static <T> SR<T> of(Reg parent, Registry<T> reg) {
return new SR<>(parent.make(reg));
}
public static <T> SR<T> of(Reg parent, Registry<T> reg) {
return new SR<>(parent.make(reg));
}
public static <T> SR<T> of(Reg parent, ResourceKey<Registry<T>> reg) {
return new SR<>(parent.make(reg));
}
public static <T> SR<T> of(Reg parent, ResourceKey<Registry<T>> reg) {
return new SR<>(parent.make(reg));
}
public <H extends T> Val<H> reg(String id, Supplier<H> sup) {
return new ValImpl<>(reg.register(id, sup));
}
public <H extends T> Val<H> reg(String id, Supplier<H> sup) {
return new ValImpl<>(reg.register(id, sup));
}
private record ValImpl<R, T extends R>(DeferredHolder<R, T> val) implements Val<T> {
public <H extends T> Val<H> reg(String id, Function<ResourceLocation, H> sup) {
return new ValImpl<>(reg.register(id, sup));
}
@Override
public T get() {
return val.get();
}
private record ValImpl<R, T extends R>(DeferredHolder<R, T> val) implements Val<T> {
}
@Override
public T get() {
return val.get();
}
}
}

View File

@@ -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;

View File

@@ -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<HolderLookup.Provider> pvd;
private final String name;
private final Map<String, ConfigEntry<?>> map = new HashMap<>();
public ConfigDataProvider(DataGenerator generator, HolderLookup.Provider pvd, String name) {
public ConfigDataProvider(DataGenerator generator, CompletableFuture<HolderLookup.Provider> 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<CompletableFuture<?>> 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<CompletableFuture<?>> 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

View File

@@ -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<AddItemModifier> 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.<Item>empty() : Optional.of(m.fail)),
DoubleConfigValue.CODEC.optionalFieldOf("chance")
.forGetter(m -> Optional.ofNullable(m.chance))
)).apply(i, AddItemModifier::new));
public static final MapCodec<AddItemModifier> 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.<Item>empty() : Optional.of(m.fail)),
DoubleConfigValue.CODEC.optionalFieldOf("chance")
.forGetter(m -> Optional.ofNullable(m.chance))
)).apply(i, AddItemModifier::new));
public static final MapCodec<AddItemModifier> 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<Item> fail, Optional<DoubleSupplier> chance) {
super(conditionsIn);
this.item = item;
this.fail = fail.orElse(Items.AIR);
this.chance = chance.orElse(null);
}
protected AddItemModifier(LootItemCondition[] conditionsIn, Item item, Optional<Item> fail, Optional<DoubleSupplier> 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<ItemStack> doApply(ObjectArrayList<ItemStack> 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<ItemStack> doApply(ObjectArrayList<ItemStack> 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<AddItemModifier> codec() {
return MAP_CODEC;
}
@Override
public MapCodec<AddItemModifier> codec() {
return MAP_CODEC;
}
}

View File

@@ -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<AddLootTableModifier> CODEC = RecordCodecBuilder.create(inst -> codecStart(inst)
.and(ResourceLocation.CODEC.fieldOf("lootTable").forGetter((m) -> m.lootTable))
.apply(inst, AddLootTableModifier::new));
public static final MapCodec<AddLootTableModifier> MAP_CODEC = RecordCodecBuilder.mapCodec(inst -> codecStart(inst)
.and(ResourceLocation.CODEC.fieldOf("lootTable").forGetter((m) -> m.lootTable))
.apply(inst, AddLootTableModifier::new));
public static final MapCodec<AddLootTableModifier> 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<ItemStack> doApply(ObjectArrayList<ItemStack> 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<ItemStack> doApply(ObjectArrayList<ItemStack> 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<AddLootTableModifier> codec() {
return MAP_CODEC;
}
@Override
public MapCodec<AddLootTableModifier> codec() {
return MAP_CODEC;
}
}