diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CycleBlockPropertyFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CycleBlockPropertyFunction.java index 358116670..5c7ef9962 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CycleBlockPropertyFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CycleBlockPropertyFunction.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.plugin.context.function; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.momirealms.craftengine.core.block.BlockStateWrapper; import net.momirealms.craftengine.core.block.UpdateOption; import net.momirealms.craftengine.core.plugin.context.Condition; @@ -10,9 +11,9 @@ import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextPar 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 org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; @@ -20,15 +21,28 @@ import java.util.Optional; public class CycleBlockPropertyFunction extends AbstractConditionalFunction { private final String property; + @Nullable + private final Map rules; + @Nullable private final NumberProvider inverse; private final NumberProvider x; private final NumberProvider y; private final NumberProvider z; private final NumberProvider updateFlags; - public CycleBlockPropertyFunction(List> predicates, String property, NumberProvider inverse, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider updateFlags) { + public CycleBlockPropertyFunction( + List> predicates, + String property, + @Nullable Map rules, + @Nullable NumberProvider inverse, + NumberProvider x, + NumberProvider y, + NumberProvider z, + NumberProvider updateFlags + ) { super(predicates); this.property = property; + this.rules = rules; this.inverse = inverse; this.x = x; this.y = y; @@ -44,11 +58,26 @@ public class CycleBlockPropertyFunction extends AbstractCon 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.getBlock(x, y, z); - BlockStateWrapper wrapper = blockAt.blockState().cycleProperty(this.property, this.inverse.getInt(ctx) == 0); + BlockStateWrapper wrapper = updateBlockState(world.getBlock(x, y, z).blockState(), ctx); world.setBlockState(x, y, z, wrapper, this.updateFlags.getInt(ctx)); } + private BlockStateWrapper updateBlockState(BlockStateWrapper wrapper, CTX ctx) { + boolean inverse = this.inverse != null && this.inverse.getInt(ctx) == 0; + if (this.rules == null) { + return wrapper.cycleProperty(this.property, inverse); + } + Object value = wrapper.getProperty(this.property); + if (value == null) { + return wrapper.cycleProperty(this.property, inverse); + } + String mapValue = this.rules.get(value.toString()); + if (mapValue == null) { + return wrapper.cycleProperty(this.property, inverse); + } + return wrapper.withProperty(this.property, mapValue); + } + @Override public Key type() { return CommonFunctions.CYCLE_BLOCK_PROPERTY; @@ -62,8 +91,15 @@ public class CycleBlockPropertyFunction extends AbstractCon @Override public Function create(Map arguments) { + String property = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("property"), "warning.config.function.cycle_block_property.missing_property"); + Map rules; + if (arguments.containsKey("rules")) { + rules = new Object2ObjectOpenHashMap<>(); + MiscUtils.castToMap(arguments.get("rules"), true).forEach((k, v) -> rules.put(k, v.toString())); + } else rules = null; return new CycleBlockPropertyFunction<>(getPredicates(arguments), - ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("property"), "warning.config.function.cycle_block_property.missing_property"), + property, + rules, NumberProviders.fromObject(arguments.getOrDefault("inverse", "")), NumberProviders.fromObject(arguments.getOrDefault("x", "")), NumberProviders.fromObject(arguments.getOrDefault("y", "")),