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

添加循环方块属性函数

This commit is contained in:
jhqwqmc
2025-11-11 00:10:52 +08:00
parent a215232cdb
commit b9950dbb8b
11 changed files with 115 additions and 2 deletions

View File

@@ -59,6 +59,15 @@ public class BukkitCustomBlockStateWrapper extends AbstractBlockStateWrapper imp
return this;
}
@Override
public BlockStateWrapper cycleProperty(String propertyName, boolean backwards) {
return getImmutableBlockState().map(state -> {
Property<?> property = state.owner().value().getProperty(propertyName);
if (property == null) return null;
return state.cycle(property, backwards).customBlockState();
}).orElse(this);
}
@Override
public boolean hasProperty(String propertyName) {
return getImmutableBlockState().map(state -> state.owner().value().getProperty(propertyName) != null).orElse(false);

View File

@@ -54,4 +54,11 @@ public class BukkitVanillaBlockStateWrapper extends AbstractBlockStateWrapper {
if (newState == super.blockState) return this;
return BlockRegistryMirror.byId(BlockStateUtils.blockStateToId(newState));
}
@Override
public BlockStateWrapper cycleProperty(String propertyName, boolean backwards) {
Object newState = this.accessor.cycleProperty(propertyName, backwards);
if (newState == super.blockState) return this;
return BlockRegistryMirror.byId(BlockStateUtils.blockStateToId(newState));
}
}

View File

@@ -479,6 +479,7 @@ warning.config.function.when.missing_source: "<yellow>Issue found in file <arg:0
warning.config.function.if_else.missing_rules: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'rules' argument for 'if_else' function.</yellow>"
warning.config.function.update_block_property.missing_properties: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'properties' argument for 'update_block_property' function.</yellow>"
warning.config.function.transform_block.missing_block: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'block' argument for 'transform_block' function.</yellow>"
warning.config.function.cycle_block_property.missing_property: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'property' argument for 'cycle_block_property' function.</yellow>"
warning.config.selector.missing_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'type' argument for selector.</yellow>"
warning.config.selector.invalid_type: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector type '<arg:2>'.</yellow>"
warning.config.selector.invalid_target: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid selector target '<arg:2>'.</yellow>"

View File

@@ -478,6 +478,7 @@ warning.config.function.when.missing_source: "<yellow>在文件 <arg:0> 发现
warning.config.function.if_else.missing_rules: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'if_else' 函数所需的 'rules' 参数</yellow>"
warning.config.function.update_block_property.missing_properties: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'update_block_property' 函数所需的 'properties' 参数</yellow>"
warning.config.function.transform_block.missing_block: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'transform_block' 函数所需的 'block' 参数</yellow>"
warning.config.function.cycle_block_property.missing_property: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'cycle_block_property' 函数所需的 'property' 参数</yellow>"
warning.config.selector.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少选择器必需的 'type' 参数</yellow>"
warning.config.selector.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 使用了无效的选择器类型 '<arg:2>'</yellow>"
warning.config.selector.invalid_target: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 使用了无效的选择器目标 '<arg:2>'</yellow>"

View File

@@ -23,6 +23,8 @@ public interface BlockStateWrapper extends Comparable<BlockStateWrapper> {
BlockStateWrapper withProperty(String propertyName, String propertyValue);
BlockStateWrapper cycleProperty(String propertyName, boolean backwards);
String getAsString();
boolean isCustom();

View File

@@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.loot.LootTable;
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.MiscUtils;
import net.momirealms.craftengine.core.world.CEWorld;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.sparrow.nbt.CompoundTag;
@@ -152,6 +153,16 @@ public final class ImmutableBlockState {
return this.owner;
}
public <T extends Comparable<T>> ImmutableBlockState cycle(Property<T> property, boolean backwards) {
T currentValue = get(property);
List<T> values = property.possibleValues();
return with(property, getRelative(values, currentValue, backwards));
}
private static <T> T getRelative(List<T> values, T currentValue, boolean backwards) {
return backwards ? MiscUtils.findPreviousInIterable(values, currentValue) : getNextValue(values, currentValue);
}
public <T extends Comparable<T>> ImmutableBlockState cycle(Property<T> property) {
T currentValue = get(property);
List<T> values = property.possibleValues();

View File

@@ -18,5 +18,10 @@ public interface StatePropertyAccessor {
Object withProperty(String propertyName, String value);
@NotNull
Object cycleProperty(String propertyName);
default Object cycleProperty(String propertyName) {
return cycleProperty(propertyName, false);
}
@NotNull
Object cycleProperty(String propertyName, boolean backwards);
}

View File

@@ -54,6 +54,7 @@ public class EventFunctions {
register(CommonFunctions.ALTERNATIVES, new IfElseFunction.FactoryImpl<>(EventConditions::fromMap, EventFunctions::fromMap));
register(CommonFunctions.WHEN, new WhenFunction.FactoryImpl<>(EventConditions::fromMap, EventFunctions::fromMap));
register(CommonFunctions.DAMAGE_ITEM, new DamageItemFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.CYCLE_BLOCK_PROPERTY, new CycleBlockPropertyFunction.FactoryImpl<>(EventConditions::fromMap));
}
public static void register(Key key, FunctionFactory<Context> factory) {

View File

@@ -45,4 +45,5 @@ public final class CommonFunctions {
public static final Key ALL_OF = Key.of("craftengine:all_of");
public static final Key DUMMY = Key.of("craftengine:dummy");
public static final Key DAMAGE_ITEM = Key.of("craftengine:damage_item");
public static final Key CYCLE_BLOCK_PROPERTY = Key.of("craftengine:cycle_block_property");
}

View File

@@ -0,0 +1,75 @@
package net.momirealms.craftengine.core.plugin.context.function;
import net.momirealms.craftengine.core.block.BlockStateWrapper;
import net.momirealms.craftengine.core.block.UpdateOption;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.world.ExistingBlock;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldPosition;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class CycleBlockPropertyFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
private final String property;
private final NumberProvider x;
private final NumberProvider y;
private final NumberProvider z;
private final NumberProvider updateFlags;
public CycleBlockPropertyFunction(List<Condition<CTX>> predicates, String property, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider updateFlags) {
super(predicates);
this.property = property;
this.x = x;
this.y = y;
this.z = z;
this.updateFlags = updateFlags;
}
@Override
protected void runInternal(CTX ctx) {
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
if (optionalWorldPosition.isEmpty()) return;
World world = optionalWorldPosition.get().world();
int x = MiscUtils.fastFloor(this.x.getDouble(ctx));
int y = MiscUtils.fastFloor(this.y.getDouble(ctx));
int z = MiscUtils.fastFloor(this.z.getDouble(ctx));
ExistingBlock blockAt = world.getBlockAt(x, y, z);
boolean isSecondaryUseActive = ctx.getOptionalParameter(DirectContextParameters.PLAYER)
.map(Player::isSecondaryUseActive)
.orElse(false);
BlockStateWrapper wrapper = blockAt.blockState().cycleProperty(this.property, isSecondaryUseActive);
world.setBlockAt(x, y, z, wrapper, this.updateFlags.getInt(ctx));
}
@Override
public Key type() {
return CommonFunctions.CYCLE_BLOCK_PROPERTY;
}
public static class FactoryImpl<CTX extends Context> extends AbstractFactory<CTX> {
public FactoryImpl(java.util.function.Function<Map<String, Object>, Condition<CTX>> factory) {
super(factory);
}
@Override
public Function<CTX> create(Map<String, Object> arguments) {
return new CycleBlockPropertyFunction<>(getPredicates(arguments),
ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("property"), "warning.config.function.cycle_block_property.missing_property"),
NumberProviders.fromObject(arguments.getOrDefault("x", "<arg:position.x>")),
NumberProviders.fromObject(arguments.getOrDefault("y", "<arg:position.y>")),
NumberProviders.fromObject(arguments.getOrDefault("z", "<arg:position.z>")),
Optional.ofNullable(arguments.get("update-flags")).map(NumberProviders::fromObject).orElse(NumberProviders.direct(UpdateOption.UPDATE_ALL.flags())));
}
}
}

View File

@@ -49,7 +49,7 @@ byte_buddy_version=1.17.8
ahocorasick_version=0.6.3
snake_yaml_version=2.5
anti_grief_version=1.0.4
nms_helper_version=1.0.128
nms_helper_version=1.0.129
evalex_version=3.5.0
reactive_streams_version=1.0.4
amazon_awssdk_version=2.34.5