From ec0c61324d3f5ea07d3d5d9e1d934ced2f78295d Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Tue, 23 Sep 2025 14:33:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E9=80=80=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E6=B7=BB=E5=8A=A0=E9=99=90=E5=88=B6?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/injector/BlockStateGenerator.java | 80 +------------------ .../reflection/minecraft/CoreReflections.java | 16 ---- .../default/configuration/blocks/honeydew.yml | 8 +- .../loot/function/LimitCountFunction.java | 65 +++++++++++++++ .../core/loot/function/LootFunctions.java | 2 + 5 files changed, 73 insertions(+), 98 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/loot/function/LimitCountFunction.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java index 03d0d98b0..2c2e4d036 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockStateGenerator.java @@ -19,19 +19,16 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlockStateProperties; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MLootContextParams; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.BlockSettings; -import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.DelegatingBlockState; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; -import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.World; @@ -69,19 +66,7 @@ public final class BlockStateGenerator { .method(ElementMatchers.is(CoreReflections.method$StateHolder$setValue)) .intercept(MethodDelegation.to(SetPropertyValueInterceptor.INSTANCE)) .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isBlock)) - .intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE)) - .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isHolderSetBlock)) - .intercept(MethodDelegation.to(IsHolderSetBlockInterceptor.INSTANCE)); - if (CoreReflections.method$BlockStateBase$isHolderBlock != null) { - stateBuilder = stateBuilder - .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isHolderBlock)) - .intercept(MethodDelegation.to(IsHolderBlockInterceptor.INSTANCE)); - } - if (CoreReflections.method$BlockStateBase$isResourceKeyBlock != null) { - stateBuilder = stateBuilder - .method(ElementMatchers.is(CoreReflections.method$BlockStateBase$isResourceKeyBlock)) - .intercept(MethodDelegation.to(IsResourceKeyBlockInterceptor.INSTANCE)); - } + .intercept(MethodDelegation.to(IsBlockInterceptor.INSTANCE)); Class clazz$CraftEngineBlock = stateBuilder.make().load(BlockStateGenerator.class.getClassLoader()).getLoaded(); constructor$CraftEngineBlockState = VersionHelper.isOrAbove1_20_5() ? MethodHandles.publicLookup().in(clazz$CraftEngineBlock) @@ -217,69 +202,6 @@ public final class BlockStateGenerator { } } - public static class IsHolderSetBlockInterceptor { - public static final IsHolderSetBlockInterceptor INSTANCE = new IsHolderSetBlockInterceptor(); - - @SuppressWarnings("unchecked") - @RuntimeType - public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { - DelegatingBlockState customState = (DelegatingBlockState) thisObj; - ImmutableBlockState thisState = customState.blockState(); - if (thisState == null) return false; - Holder owner = thisState.owner(); - for (Object holder : (Iterable) args[0]) { - Object block = FastNMS.INSTANCE.method$Holder$value(holder); - if (block == null) continue; - if (!(FastNMS.INSTANCE.method$Block$defaultState(block) instanceof DelegatingBlockState customHolder)) - continue; - ImmutableBlockState holderState = customHolder.blockState(); - if (holderState == null) continue; - return holderState.owner().equals(owner); - } - return false; - } - } - - public static class IsHolderBlockInterceptor { - public static final IsHolderBlockInterceptor INSTANCE = new IsHolderBlockInterceptor(); - - @RuntimeType - public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { - DelegatingBlockState customState = (DelegatingBlockState) thisObj; - ImmutableBlockState thisState = customState.blockState(); - if (thisState == null) return false; - Object block = FastNMS.INSTANCE.method$Holder$value(args[0]); - if (block == null) return false; - if (FastNMS.INSTANCE.method$Block$defaultState(block) instanceof DelegatingBlockState holder) { - ImmutableBlockState holderState = holder.blockState(); - if (holderState == null) return false; - return holderState.owner().equals(thisState.owner()); - } - return false; - } - } - - public static class IsResourceKeyBlockInterceptor { - public static final IsResourceKeyBlockInterceptor INSTANCE = new IsResourceKeyBlockInterceptor(); - - @RuntimeType - public boolean intercept(@This Object thisObj, @AllArguments Object[] args) { - DelegatingBlockState customState = (DelegatingBlockState) thisObj; - ImmutableBlockState thisState = customState.blockState(); - if (thisState == null) return false; - Object block = FastNMS.INSTANCE.method$HolderGetter$getResourceKey(MBuiltInRegistries.BLOCK, args[0]) - .map(FastNMS.INSTANCE::method$Holder$value) - .orElse(null); - if (block == null) return false; - if (FastNMS.INSTANCE.method$Block$defaultState(block) instanceof DelegatingBlockState holder) { - ImmutableBlockState holderState = holder.blockState(); - if (holderState == null) return false; - return holderState.owner().equals(thisState.owner()); - } - return false; - } - } - public static class CreateStateInterceptor { public static final CreateStateInterceptor INSTANCE = new CreateStateInterceptor(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index 64590cb41..f4b0439d1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java @@ -4419,22 +4419,6 @@ public final class CoreReflections { ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Block) ); - public static final Method method$BlockStateBase$isHolderSetBlock = requireNonNull( - ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$HolderSet) - ); - - // 1.20.2+ - public static final Method method$BlockStateBase$isHolderBlock = MiscUtils.requireNonNullIf( - ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$Holder), - VersionHelper.isOrAbove1_20_2() - ); - - // 1.20.3+ - public static final Method method$BlockStateBase$isResourceKeyBlock = MiscUtils.requireNonNullIf( - ReflectionUtils.getDeclaredMethod(clazz$BlockStateBase, boolean.class, new String[]{"is", "a"}, clazz$ResourceKey), - VersionHelper.isOrAbove1_20_3() - ); - public static final Method method$BlockBehaviour$propagatesSkylightDown = requireNonNull( VersionHelper.isOrAbove1_21_2() ? ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, boolean.class, new String[]{"propagatesSkylightDown", "e_"}, clazz$BlockState) diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/honeydew.yml b/common-files/src/main/resources/resources/default/configuration/blocks/honeydew.yml index 25400f3ec..0291afcbe 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/honeydew.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/honeydew.yml @@ -40,13 +40,15 @@ blocks: - type: item item: default:honeydew_item functions: + - type: set_count + add: false + count: 3~7 - type: apply_bonus enchantment: minecraft:fortune formula: type: ore_drops - - type: set_count - add: false - count: 3~7 + - type: limit_count + max: 9 - type: explosion_decay settings: map-color: 19 diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/function/LimitCountFunction.java b/core/src/main/java/net/momirealms/craftengine/core/loot/function/LimitCountFunction.java new file mode 100644 index 000000000..8ecc4fc2b --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/function/LimitCountFunction.java @@ -0,0 +1,65 @@ +package net.momirealms.craftengine.core.loot.function; + +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.loot.LootConditions; +import net.momirealms.craftengine.core.loot.LootContext; +import net.momirealms.craftengine.core.plugin.context.Condition; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.util.Key; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class LimitCountFunction extends AbstractLootConditionalFunction { + public static final Factory FACTORY = new Factory<>(); + @Nullable + private final NumberProvider min; + @Nullable + private final NumberProvider max; + + public LimitCountFunction(List> predicates, @Nullable NumberProvider min, @Nullable NumberProvider max) { + super(predicates); + this.min = min; + this.max = max; + } + + @Override + public Key type() { + return LootFunctions.LIMIT_COUNT; + } + + @Override + protected Item applyInternal(Item item, LootContext context) { + int amount = item.count(); + if (min != null) { + int minAmount = min.getInt(context); + if (amount < minAmount) { + item.count(minAmount); + } + } + if (max != null) { + int maxAmount = max.getInt(context); + if (amount > maxAmount) { + item.count(maxAmount); + } + } + return item; + } + + public static class Factory implements LootFunctionFactory { + @SuppressWarnings("unchecked") + @Override + public LootFunction create(Map arguments) { + Object min = arguments.get("min"); + Object max = arguments.get("max"); + List> conditions = Optional.ofNullable(arguments.get("conditions")) + .map(it -> LootConditions.fromMapList((List>) it)) + .orElse(Collections.emptyList()); + return new LimitCountFunction<>(conditions, min == null ? null : NumberProviders.fromObject(min), max == null ? null : NumberProviders.fromObject(max)); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java index c2233c20f..c9d221c95 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java @@ -20,12 +20,14 @@ public class LootFunctions { public static final Key SET_COUNT = Key.from("craftengine:set_count"); public static final Key EXPLOSION_DECAY = Key.from("craftengine:explosion_decay"); public static final Key DROP_EXP = Key.from("craftengine:drop_exp"); + public static final Key LIMIT_COUNT = Key.from("craftengine:limit_count"); static { register(SET_COUNT, SetCountFunction.FACTORY); register(EXPLOSION_DECAY, ExplosionDecayFunction.FACTORY); register(APPLY_BONUS, ApplyBonusCountFunction.FACTORY); register(DROP_EXP, DropExpFunction.FACTORY); + register(LIMIT_COUNT, LimitCountFunction.FACTORY); } public static void register(Key key, LootFunctionFactory factory) {