holder fix

This commit is contained in:
lcy0x1
2024-08-09 11:13:11 +08:00
parent b50d041151
commit cb5c15afee
4 changed files with 143 additions and 9 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.7+13
mod_version=3.0.7+18
mod_group_id=dev.xkmc
mod_authors=lcy0x1
mod_description=Core Library mod for all L2 mods

View File

@@ -74,6 +74,11 @@ public interface LegacyHolder<T> extends Holder<T>, Supplier<T> {
return Kind.REFERENCE;
}
@Override
default Holder<T> getDelegate() {
return holder().getDelegate();
}
@Override
default boolean canSerializeIn(HolderOwner<T> pOwner) {
return holder().canSerializeIn(pOwner);

View File

@@ -1,11 +1,13 @@
package dev.xkmc.l2core.serial.config;
import com.google.gson.JsonElement;
import com.mojang.serialization.JsonOps;
import dev.xkmc.l2serial.serialization.codec.JsonCodec;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.neoforged.neoforge.common.conditions.ICondition;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -37,6 +39,10 @@ public abstract class RecordDataProvider implements DataProvider {
this.map.forEach((k, v) -> {
JsonElement elem = new JsonCodec(pvd).toJson(v);
if (elem != null) {
if (v instanceof ConditionalRecord c) {
var cond = ICondition.LIST_CODEC.encodeStart(JsonOps.INSTANCE, c.conditions()).getOrThrow();
elem.getAsJsonObject().add("neoforge:conditions", cond);
}
Path path = folder.resolve("data/" + k + ".json");
list.add(DataProvider.saveStable(cache, elem, path));
}
@@ -49,4 +55,10 @@ public abstract class RecordDataProvider implements DataProvider {
return this.name;
}
public interface ConditionalRecord {
List<ICondition> conditions();
}
}

View File

@@ -1,29 +1,59 @@
package dev.xkmc.l2core.serial.loot;
import com.tterrag.registrate.providers.loot.RegistrateBlockLootTables;
import com.tterrag.registrate.providers.loot.RegistrateEntityLootTables;
import net.minecraft.Util;
import net.minecraft.advancements.critereon.*;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount;
import net.minecraft.world.level.storage.loot.functions.LootItemFunction;
import net.minecraft.world.level.storage.loot.predicates.BonusLevelTableCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.world.level.storage.loot.predicates.MatchTool;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.entries.LootItem;
import net.minecraft.world.level.storage.loot.entries.LootPoolSingletonContainer;
import net.minecraft.world.level.storage.loot.functions.*;
import net.minecraft.world.level.storage.loot.predicates.*;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
import java.util.List;
import java.util.Optional;
public record LootHelper(RegistrateBlockLootTables pvd) {
public record LootHelper(HolderLookup.Provider pvd) {
public LootHelper(RegistrateBlockLootTables pvd) {
this(pvd.getRegistries());
}
public LootHelper(RegistrateEntityLootTables pvd) {
this(pvd.getRegistries());
}
public <T> Holder<T> resolve(ResourceKey<T> key) {
return pvd.getRegistries().holderOrThrow(key);
return pvd.holderOrThrow(key);
}
public LootPoolSingletonContainer.Builder<?> item(Item item) {
return LootItem.lootTableItem(item);
}
public LootPoolSingletonContainer.Builder<?> item(Item item, int count) {
return LootItem.lootTableItem(item)
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(count)));
}
public LootPoolSingletonContainer.Builder<?> item(Item item, int min, int max) {
return LootItem.lootTableItem(item)
.apply(SetItemCountFunction.setCount(UniformGenerator.between(min, max)));
}
public EnchantmentPredicate hasEnch(ResourceKey<Enchantment> enchant, int min) {
@@ -70,4 +100,91 @@ public record LootHelper(RegistrateBlockLootTables pvd) {
return BonusLevelTableCondition.bonusLevelFlatChance(resolve(Enchantments.FORTUNE), fracs);
}
public LootItemFunction.Builder fortuneBin() {
return fortuneBin(4 / 7f, 3);
}
public LootItemFunction.Builder fortuneBin(float chance, int count) {
return ApplyBonusCount.addBonusBinomialDistributionCount(resolve(Enchantments.FORTUNE), chance, count);
}
public LootItemFunction.Builder lootCount(float factor) {
return EnchantedCountIncreaseFunction.lootingMultiplier(pvd, UniformGenerator.between(0, factor));
}
public LootItemCondition.Builder lootChance(float base, float slope) {
return LootItemRandomChanceWithEnchantedBonusCondition.randomChanceAndLootingBoost(pvd, base, slope);
}
public LootItemCondition.Builder fire(boolean fire) {
return LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS,
EntityPredicate.Builder.entity().flags(
EntityFlagsPredicate.Builder.flags().setOnFire(fire)
).build());
}
public LootItemFunction.Builder smelt() {
return SmeltItemFunction.smelted().when(fire(true));
}
public LootItemCondition.Builder damage(TagKey<DamageType> tag) {
return DamageSourceCondition.hasDamageSource(DamageSourcePredicate.Builder.damageType()
.tag(TagPredicate.is(tag)));
}
public LootItemCondition.Builder entity(EntityType<?> type) {
return LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.THIS,
EntityPredicate.Builder.entity().entityType(
EntityTypePredicate.of(type)));
}
public LootItemCondition.Builder entity(TagKey<EntityType<?>> tag) {
return LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.THIS,
EntityPredicate.Builder.entity().entityType(
EntityTypePredicate.of(tag)));
}
public LootItemCondition.Builder killer(EntityType<?> type) {
return LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.ATTACKER,
EntityPredicate.Builder.entity().entityType(
EntityTypePredicate.of(type)));
}
public LootItemCondition.Builder killer(TagKey<EntityType<?>> tag) {
return LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.ATTACKER,
EntityPredicate.Builder.entity().entityType(
EntityTypePredicate.of(tag)));
}
public LootItemCondition.Builder killerItem(EquipmentSlot slot, Item item) {
return LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.ATTACKER,
EntityPredicate.Builder.entity().equipment(
slot(slot, ItemPredicate.Builder.item().of(item)).build()).build());
}
public LootItemCondition.Builder killerItem(EquipmentSlot slot, TagKey<Item> item) {
return LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.ATTACKER,
EntityPredicate.Builder.entity().equipment(
slot(slot, ItemPredicate.Builder.item().of(item)).build()).build());
}
private EntityEquipmentPredicate.Builder slot(EquipmentSlot slot, ItemPredicate.Builder item) {
var b = EntityEquipmentPredicate.Builder.equipment();
return switch (slot) {
case MAINHAND -> b.mainhand(item);
case OFFHAND -> b.offhand(item);
case FEET -> b.feet(item);
case LEGS -> b.legs(item);
case CHEST -> b.chest(item);
case HEAD -> b.head(item);
case BODY -> b.body(item);
};
}
}