9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-28 03:19:14 +00:00

回退错误的实现,添加限制数量函数

This commit is contained in:
jhqwqmc
2025-09-23 14:33:19 +08:00
parent 5558a6d673
commit ec0c61324d
5 changed files with 73 additions and 98 deletions

View File

@@ -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<CustomBlock> owner = thisState.owner();
for (Object holder : (Iterable<Object>) 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();

View File

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

View File

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

View File

@@ -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<T> extends AbstractLootConditionalFunction<T> {
public static final Factory<?> FACTORY = new Factory<>();
@Nullable
private final NumberProvider min;
@Nullable
private final NumberProvider max;
public LimitCountFunction(List<Condition<LootContext>> 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<T> applyInternal(Item<T> 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<A> implements LootFunctionFactory<A> {
@SuppressWarnings("unchecked")
@Override
public LootFunction<A> create(Map<String, Object> arguments) {
Object min = arguments.get("min");
Object max = arguments.get("max");
List<Condition<LootContext>> conditions = Optional.ofNullable(arguments.get("conditions"))
.map(it -> LootConditions.fromMapList((List<Map<String, Object>>) it))
.orElse(Collections.emptyList());
return new LimitCountFunction<>(conditions, min == null ? null : NumberProviders.fromObject(min), max == null ? null : NumberProviders.fromObject(max));
}
}
}

View File

@@ -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 <T> void register(Key key, LootFunctionFactory<T> factory) {