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:
XiaoMoMi
2025-10-23 20:41:02 +08:00
parent fb8b72d279
commit 21a89a818b
15 changed files with 233 additions and 15 deletions

View File

@@ -64,11 +64,8 @@ blocks:
- type: match_block_property
properties:
age: 2
- type: '!is_null'
argument: item_in_hand
- type: equals
value1: <arg:item_in_hand.id>
value2: default:ender_pearl_flower_seeds
- type: match_item
id: default:ender_pearl_flower_seeds
functions:
- type: break_block
x: <arg:block.block_x>

View File

@@ -132,10 +132,9 @@ blocks:
- type: match_block_property
properties:
age: 3
- type: 'is_null'
argument: item_in_hand
- type: hand
hand: main_hand
- type: '!has_item'
functions:
- type: break_block
x: <arg:block.block_x>

View File

@@ -474,6 +474,8 @@ warning.config.function.merchant_trade.offer.missing_cost_1: "<yellow>Issue foun
warning.config.function.merchant_trade.offer.missing_result: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'result' argument for merchant trade offers.</yellow>"
warning.config.function.when.missing_source: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'source' argument for 'when' function.</yellow>"
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.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

@@ -21,7 +21,7 @@ dependencies {
implementation("net.momirealms:sparrow-nbt-codec:${rootProject.properties["sparrow_nbt_version"]}")
implementation("net.momirealms:sparrow-nbt-legacy-codec:${rootProject.properties["sparrow_nbt_version"]}")
// S3
implementation("net.momirealms:craft-engine-s3:0.7")
implementation("net.momirealms:craft-engine-s3:0.8")
// Util
compileOnly("net.momirealms:sparrow-util:${rootProject.properties["sparrow_util_version"]}")
// Adventure

View File

@@ -25,6 +25,7 @@ public class LootConditions {
register(CommonConditions.ANY_OF, new AnyOfCondition.FactoryImpl<>(LootConditions::fromMap));
register(CommonConditions.ALL_OF, new AllOfCondition.FactoryImpl<>(LootConditions::fromMap));
register(CommonConditions.HAS_PLAYER, new HasPlayerCondition.FactoryImpl<>());
register(CommonConditions.HAS_ITEM, new HasItemCondition.FactoryImpl<>());
register(CommonConditions.ENCHANTMENT, new EnchantmentCondition.Factory<>());
register(CommonConditions.INVERTED, new InvertedCondition.FactoryImpl<>(LootConditions::fromMap));
register(CommonConditions.FALLING_BLOCK, new FallingBlockCondition.FactoryImpl<>());

View File

@@ -11,6 +11,7 @@ public final class CommonConditions {
public static final Key ANY_OF = Key.of("craftengine:any_of");
public static final Key INVERTED = Key.of("craftengine:inverted");
public static final Key MATCH_ITEM = Key.of("craftengine:match_item");
public static final Key HAS_ITEM = Key.of("craftengine:has_item");
public static final Key MATCH_ENTITY = Key.of("craftengine:match_entity");
public static final Key MATCH_BLOCK = Key.of("craftengine:match_block");
public static final Key MATCH_BLOCK_PROPERTY = Key.from("craftengine:match_block_property");

View File

@@ -0,0 +1,38 @@
package net.momirealms.craftengine.core.plugin.context.condition;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.context.Condition;
import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
import net.momirealms.craftengine.core.util.ItemUtils;
import net.momirealms.craftengine.core.util.Key;
import java.util.Map;
import java.util.Optional;
public class HasItemCondition<CTX extends Context> implements Condition<CTX> {
public HasItemCondition() {
}
@Override
public Key type() {
return CommonConditions.HAS_ITEM;
}
@Override
public boolean test(CTX ctx) {
Optional<Item<?>> item = ctx.getOptionalParameter(DirectContextParameters.ITEM_IN_HAND);
if (item.isEmpty()) return false;
Item<?> itemInHand = item.get();
return !ItemUtils.isEmpty(itemInHand);
}
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {
return new HasItemCondition<>();
}
}
}

View File

@@ -14,7 +14,7 @@ public class HasPlayerCondition<CTX extends Context> implements Condition<CTX> {
@Override
public Key type() {
return CommonConditions.IS_NULL;
return CommonConditions.HAS_PLAYER;
}
@Override

View File

@@ -35,7 +35,7 @@ public class MatchItemCondition<CTX extends Context> implements Condition<CTX> {
@Override
public Condition<CTX> create(Map<String, Object> arguments) {
List<String> ids = MiscUtils.getAsStringList(arguments.get("id"));
List<String> ids = MiscUtils.getAsStringList(ResourceConfigUtils.get(arguments, "id", "item"));
if (ids.isEmpty()) {
throw new LocalizedResourceConfigException("warning.config.condition.match_item.missing_id");
}

View File

@@ -17,6 +17,7 @@ public class EventConditions {
static {
register(CommonConditions.HAS_PLAYER, new HasPlayerCondition.FactoryImpl<>());
register(CommonConditions.HAS_ITEM, new HasItemCondition.FactoryImpl<>());
register(CommonConditions.MATCH_ITEM, new MatchItemCondition.FactoryImpl<>());
register(CommonConditions.MATCH_ENTITY, new MatchEntityCondition.FactoryImpl<>());
register(CommonConditions.MATCH_BLOCK, new MatchBlockCondition.FactoryImpl<>());

View File

@@ -24,6 +24,8 @@ public class EventFunctions {
register(CommonFunctions.CANCEL_EVENT, new CancelEventFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.RUN, new RunFunction.FactoryImpl<>(EventFunctions::fromMap, EventConditions::fromMap));
register(CommonFunctions.PLACE_BLOCK, new PlaceBlockFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.UPDATE_BLOCK_PROPERTY, new UpdateBlockPropertyFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.TRANSFORM_BLOCK, new TransformBlockFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.BREAK_BLOCK, new BreakBlockFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.UPDATE_INTERACTION_TICK, new UpdateInteractionFunction.FactoryImpl<>(EventConditions::fromMap));
register(CommonFunctions.SET_COUNT, new SetCountFunction.FactoryImpl<>(EventConditions::fromMap));

View File

@@ -20,6 +20,8 @@ public final class CommonFunctions {
public static final Key UPDATE_INTERACTION_TICK = Key.of("craftengine:update_interaction_tick");
public static final Key SET_COUNT = Key.of("craftengine:set_count");
public static final Key PLACE_BLOCK = Key.of("craftengine:place_block");
public static final Key TRANSFORM_BLOCK = Key.of("craftengine:transform_block");
public static final Key UPDATE_BLOCK_PROPERTY = Key.of("craftengine:update_block_property");
public static final Key SET_FOOD = Key.of("craftengine:set_food");
public static final Key SET_COOLDOWN = Key.of("craftengine:set_cooldown");
public static final Key REMOVE_COOLDOWN = Key.of("craftengine:remove_cooldown");

View File

@@ -58,11 +58,12 @@ public class PlaceBlockFunction<CTX extends Context> extends AbstractConditional
@Override
public Function<CTX> create(Map<String, Object> arguments) {
String state = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("block-state"), "warning.config.function.place_block.missing_block_state");
NumberProvider x = NumberProviders.fromObject(arguments.getOrDefault("x", "<arg:position.x>"));
NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "<arg:position.y>"));
NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "<arg:position.z>"));
NumberProvider flags = Optional.ofNullable(arguments.get("update-flags")).map(NumberProviders::fromObject).orElse(NumberProviders.direct(UpdateOption.UPDATE_ALL.flags()));
return new PlaceBlockFunction<>(LazyReference.lazyReference(() -> CraftEngine.instance().blockManager().createBlockState(state)), x, y, z, flags, getPredicates(arguments));
return new PlaceBlockFunction<>(LazyReference.lazyReference(() -> CraftEngine.instance().blockManager().createBlockState(state)),
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())),
getPredicates(arguments));
}
}
}

View File

@@ -0,0 +1,96 @@
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.plugin.CraftEngine;
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.LazyReference;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldPosition;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.Tag;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
public class TransformBlockFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
private final LazyReference<BlockStateWrapper> lazyBlockState;
private final CompoundTag properties;
private final NumberProvider x;
private final NumberProvider y;
private final NumberProvider z;
private final NumberProvider updateFlags;
public TransformBlockFunction(LazyReference<BlockStateWrapper> lazyBlockState, CompoundTag properties, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider updateFlags, List<Condition<CTX>> predicates) {
super(predicates);
this.properties = properties;
this.x = x;
this.y = y;
this.z = z;
this.updateFlags = updateFlags;
this.lazyBlockState = lazyBlockState;
}
@Override
public void runInternal(CTX ctx) {
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
if (optionalWorldPosition.isPresent()) {
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));
BlockStateWrapper existingBlockState = world.getBlockAt(x, y, z).blockState().withProperties(this.properties);
CompoundTag newProperties = new CompoundTag();
for (String propertyName : existingBlockState.getPropertyNames()) {
newProperties.putString(propertyName, String.valueOf(existingBlockState.getProperty(propertyName)).toLowerCase(Locale.ROOT));
}
if (!this.properties.isEmpty()) {
for (Map.Entry<String, Tag> tagEntry : this.properties.entrySet()) {
newProperties.put(tagEntry.getKey(), tagEntry.getValue());
}
}
world.setBlockAt(x, y, z, this.lazyBlockState.get().withProperties(newProperties), this.updateFlags.getInt(ctx));
}
}
@Override
public Key type() {
return CommonFunctions.TRANSFORM_BLOCK;
}
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) {
String block = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("block"), "warning.config.function.transform_block.missing_block");
CompoundTag properties = new CompoundTag();
Map<String, Object> propertiesMap = MiscUtils.castToMap(arguments.get("properties"), true);
if (propertiesMap != null) {
for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
properties.putString(entry.getKey(), String.valueOf(entry.getValue()));
}
}
return new TransformBlockFunction<>(
LazyReference.lazyReference(() -> CraftEngine.instance().blockManager().createBlockState(block)),
properties,
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())),
getPredicates(arguments));
}
}
}

View File

@@ -0,0 +1,78 @@
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.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 net.momirealms.sparrow.nbt.CompoundTag;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class UpdateBlockPropertyFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
private final CompoundTag properties;
private final NumberProvider x;
private final NumberProvider y;
private final NumberProvider z;
private final NumberProvider updateFlags;
public UpdateBlockPropertyFunction(CompoundTag properties, NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider updateFlags, List<Condition<CTX>> predicates) {
super(predicates);
this.properties = properties;
this.x = x;
this.y = y;
this.z = z;
this.updateFlags = updateFlags;
}
@Override
public void runInternal(CTX ctx) {
Optional<WorldPosition> optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION);
if (optionalWorldPosition.isPresent()) {
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);
BlockStateWrapper wrapper = blockAt.blockState().withProperties(this.properties);
world.setBlockAt(x, y, z, wrapper, this.updateFlags.getInt(ctx));
}
}
@Override
public Key type() {
return CommonFunctions.UPDATE_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) {
Map<String, Object> state = ResourceConfigUtils.getAsMap(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("properties"), "warning.config.function.update_block_property.missing_properties"), "properties");
CompoundTag properties = new CompoundTag();
for (Map.Entry<String, Object> entry : state.entrySet()) {
properties.putString(entry.getKey(), String.valueOf(entry.getValue()));
}
return new UpdateBlockPropertyFunction<>(properties,
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())),
getPredicates(arguments));
}
}
}