mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-25 09:59:20 +00:00
@@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.item.listener;
|
||||
import io.papermc.paper.event.block.CompostItemEvent;
|
||||
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
|
||||
import net.momirealms.craftengine.bukkit.api.event.CustomBlockInteractEvent;
|
||||
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitCustomItem;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
@@ -96,9 +97,10 @@ public class ItemEventListener implements Listener {
|
||||
Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled);
|
||||
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
|
||||
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand)
|
||||
.withParameter(DirectContextParameters.EVENT, cancellable)
|
||||
.withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(event.getRightClicked().getLocation()))
|
||||
.withParameter(DirectContextParameters.HAND, hand)
|
||||
.withParameter(DirectContextParameters.EVENT, cancellable)
|
||||
.withParameter(DirectContextParameters.ENTITY, new BukkitEntity(entity))
|
||||
.withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(event.getRightClicked().getLocation()))
|
||||
);
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
customItem.execute(context, EventTrigger.RIGHT_CLICK);
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
@@ -177,6 +178,26 @@ public class BukkitServerPlayer extends Player {
|
||||
return platformPlayer().isSneaking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSwimming() {
|
||||
return platformPlayer().isSwimming();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClimbing() {
|
||||
return platformPlayer().isClimbing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGliding() {
|
||||
return platformPlayer().isGliding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlying() {
|
||||
return platformPlayer().isFlying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameMode gameMode() {
|
||||
return switch (platformPlayer().getGameMode()) {
|
||||
@@ -475,7 +496,7 @@ public class BukkitServerPlayer extends Player {
|
||||
ImmutableBlockState customState = optionalCustomState.get();
|
||||
Item<ItemStack> tool = getItemInHand(InteractionHand.MAIN_HAND);
|
||||
boolean isCorrectTool = FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(tool.getLiteralObject(), blockState);
|
||||
// 如果自定义方块在服务端侧未使用正确地工具,那么需要还原挖掘速度
|
||||
// 如果自定义方块在服务端侧未使用正确的工具,那么需要还原挖掘速度
|
||||
if (!isCorrectTool) {
|
||||
progress *= (10f / 3f);
|
||||
}
|
||||
@@ -939,6 +960,14 @@ public class BukkitServerPlayer extends Player {
|
||||
platformPlayer().performCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public void performCommandAsEvent(String command) {
|
||||
String formattedCommand = command.startsWith("/") ? command : "/" + command;
|
||||
PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(platformPlayer(), formattedCommand);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double luck() {
|
||||
if (VersionHelper.isOrAbove1_21_3()) {
|
||||
@@ -948,11 +977,6 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlying() {
|
||||
return platformPlayer().isFlying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int foodLevel() {
|
||||
return platformPlayer().getFoodLevel();
|
||||
|
||||
@@ -37,6 +37,7 @@ public final class SoundUtils {
|
||||
case HOSTILE -> SoundCategory.HOSTILE;
|
||||
case NEUTRAL -> SoundCategory.NEUTRAL;
|
||||
case WEATHER -> SoundCategory.WEATHER;
|
||||
case UI -> SoundCategory.UI;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,12 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MFluids;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.world.BlockInWorld;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import org.bukkit.Location;
|
||||
@@ -59,6 +61,11 @@ public class BukkitBlockInWorld implements BlockInWorld {
|
||||
return this.block.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return KeyUtils.namespacedKey2Key(this.block.getType().getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public World world() {
|
||||
return new BukkitWorld(this.block.getWorld());
|
||||
|
||||
@@ -92,6 +92,8 @@ warning.config.condition.inverted.invalid_term_type: "<yellow>Issue found in fil
|
||||
warning.config.condition.enchantment.missing_predicate: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'predicate' argument for 'enchantment' condition.</yellow>"
|
||||
warning.config.condition.enchantment.invalid_predicate: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid enchantment 'predicate' argument '<arg:2>'.</yellow>"
|
||||
warning.config.condition.match_block_property.missing_properties: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'properties' argument for 'match_block_property' condition.</yellow>"
|
||||
warning.config.condition.match_block_type.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'match_block_type' condition.</yellow>"
|
||||
warning.config.condition.match_entity_type.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'match_entity_type' condition.</yellow>"
|
||||
warning.config.condition.match_item.missing_id: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'id' argument for 'match_item' condition.</yellow>"
|
||||
warning.config.condition.table_bonus.missing_enchantment: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'enchantment' argument for 'table_bonus' condition.</yellow>"
|
||||
warning.config.condition.table_bonus.missing_chances: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'chances' argument for 'table_bonus' condition.</yellow>"
|
||||
@@ -295,7 +297,7 @@ warning.config.block.behavior.fence_gate.missing_facing: "<yellow>Issue found in
|
||||
warning.config.block.behavior.fence_gate.missing_in_wall: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'in_wall' argument for 'fence_gate_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.fence_gate.missing_open: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'powered' argument for 'fence_gate_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.fence_gate.missing_powered: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'open' argument for 'fence_gate_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.trapdoor.missing_type: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'type' property for 'slab_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.slab.missing_type: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'type' property for 'slab_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.stairs.missing_facing: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'facing' property for 'stairs_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.stairs.missing_half: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'half' property for 'stairs_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.stairs.missing_shape: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'shape' property for 'stairs_block' behavior.</yellow>"
|
||||
@@ -303,9 +305,9 @@ warning.config.block.behavior.pressure_plate.missing_powered: "<yellow>Issue fou
|
||||
warning.config.block.behavior.grass.missing_feature: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'feature' argument for 'grass_block' behavior.</yellow>"
|
||||
warning.config.block.behavior.double_high.missing_half: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'half' property for 'double_block' behavior.</yellow>"
|
||||
warning.config.model.generation.missing_parent: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is missing the required 'parent' argument in 'generation' section.</yellow>"
|
||||
warning.config.model.generation.conflict: "<yellow>Issue found in file <arg:0> - Failed to generate model for '<arg:1>' as two or more configurations attempt to generate different json models with the same path: '<arg:2>'.</yellow>"
|
||||
warning.config.model.generation.invalid_display_position: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid display position '<arg:2>' in 'generation.display' section. Allowed display positions: [<arg:3>]</yellow>"
|
||||
warning.config.model.generation.invalid_gui_light: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid gui-light option '<arg:2>' in 'generation' section. Allowed gui light options: [<arg:3>]</yellow>"
|
||||
warning.config.model.generation.conflict: "<yellow>Issue found in file <arg:0> - Failed to generate model for '<arg:1>' as two or more configurations attempt to generate different json models with the same path: '<arg:2>'.</yellow>"
|
||||
warning.config.model.generation.texture.invalid: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' has a texture '<arg:2>' with path '<arg:3>' that contains illegal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters.</yellow>"
|
||||
warning.config.model.generation.parent.invalid: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' has a parent argument '<arg:2>' that contains illegal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters.</yellow>"
|
||||
warning.config.emoji.missing_keywords: "<yellow>Issue found in file <arg:0> - The emoji '<arg:1>' is missing the required 'keywords' argument.</yellow>"
|
||||
@@ -411,14 +413,14 @@ warning.config.selector.invalid_type: "<yellow>Issue found in file <arg:0> - The
|
||||
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>"
|
||||
warning.config.resource_pack.item_model.already_exist: "<yellow>Failed to generate item model for '<arg:0>' because the file '<arg:1>' already exists.</yellow>"
|
||||
warning.config.resource_pack.model.generation.already_exist: "<yellow>Failed to generate model because the model file '<arg:0>' already exists.</yellow>"
|
||||
warning.config.resource_pack.generation.malformatted_json: "<yellow>Json file '<arg:0>' is malformatted.</yellow>"
|
||||
warning.config.resource_pack.generation.missing_font_texture: "<yellow>Font '<arg:0>' is missing required texture: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.texture_not_in_atlas: "<yellow>Texture '<arg:0>' is not listed in the atlas. You need to add the texture path to the atlas or enable 'obfuscation' option in config.yml.</yellow>"
|
||||
warning.config.resource_pack.generation.missing_model_texture: "<yellow>Model '<arg:0>' is missing texture '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.missing_item_model: "<yellow>Item '<arg:0>' is missing model file: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.missing_block_model: "<yellow>Block state '<arg:0>' is missing model file: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.missing_parent_model: "<yellow>Model '<arg:0>' cannot find parent model: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.malformatted_json: "<yellow>Json file '<arg:0>' is malformatted.</yellow>"
|
||||
warning.config.resource_pack.generation.missing_equipment_texture: "<yellow>Equipment '<arg:0>' is missing texture '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.texture_not_in_atlas: "<yellow>Texture '<arg:0>' is not listed in the atlas. You need to add the texture path to the atlas or enable 'obfuscation' option in config.yml.</yellow>"
|
||||
warning.config.resource_pack.invalid_overlay_format: "<yellow>Issue found in config.yml at 'resource-pack.overlay-format' - Invalid overlay format '<arg:0>'. Overlay format must contain the placeholder '{version}'.</yellow>"
|
||||
warning.config.equipment.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated equipment '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
|
||||
warning.config.equipment.missing_type: "<yellow>Issue found in file <arg:0> - The equipment '<arg:1>' is missing the required 'type' argument.</yellow>"
|
||||
|
||||
@@ -92,6 +92,8 @@ warning.config.condition.inverted.invalid_term_type: "<yellow>在文件 <arg:0>
|
||||
warning.config.condition.enchantment.missing_predicate: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'enchantment' 条件所需的 'predicate' 参数</yellow>"
|
||||
warning.config.condition.enchantment.invalid_predicate: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 使用了无效的附魔 'predicate' 参数 '<arg:2>'</yellow>"
|
||||
warning.config.condition.match_block_property.missing_properties: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'match_block_property' 条件所需的 'properties' 参数</yellow>"
|
||||
warning.config.condition.match_block_type.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'match_block_type' 条件所需的 'id' 参数</yellow>"
|
||||
warning.config.condition.match_entity_type.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'match_entity_type' 条件所需的 'id' 参数</yellow>"
|
||||
warning.config.condition.match_item.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'match_item' 条件所需的 'id' 参数</yellow>"
|
||||
warning.config.condition.table_bonus.missing_enchantment: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'table_bonus' 条件所需的 'enchantment' 参数</yellow>"
|
||||
warning.config.condition.table_bonus.missing_chances: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 缺少 'table_bonus' 条件所需的 'chances' 参数</yellow>"
|
||||
@@ -411,14 +413,14 @@ warning.config.selector.invalid_type: "<yellow>在文件 <arg:0> 中发现问题
|
||||
warning.config.selector.invalid_target: "<yellow>在文件 <arg:0> 中发现问题 - 配置项 '<arg:1>' 使用了无效的选择器目标 '<arg:2>'</yellow>"
|
||||
warning.config.resource_pack.item_model.already_exist: "<yellow>无法为 '<arg:0>' 生成物品模型,因为文件 '<arg:1>' 已存在</yellow>"
|
||||
warning.config.resource_pack.model.generation.already_exist: "<yellow>无法生成模型,因为模型文件 '<arg:0>' 已存在</yellow>"
|
||||
warning.config.resource_pack.generation.malformatted_json: "<yellow>Json文件 '<arg:0>' 格式错误</yellow>"
|
||||
warning.config.resource_pack.generation.missing_font_texture: "<yellow>字体'<arg:0>'缺少必要纹理: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.missing_model_texture: "<yellow>模型'<arg:0>'缺少纹理'<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.texture_not_in_atlas: "<yellow>纹理'<arg:0>'不在图集内. 你需要将纹理路径或文件夹前缀添加到图集内,或者启用 config.yml 中的 'obfuscation' 选项</yellow>"
|
||||
warning.config.resource_pack.generation.missing_item_model: "<yellow>物品'<arg:0>'缺少模型文件: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.missing_block_model: "<yellow>方块状态'<arg:0>'缺少模型文件: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.missing_parent_model: "<yellow>模型'<arg:0>'找不到父级模型文件: '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.malformatted_json: "<yellow>Json文件 '<arg:0>' 格式错误</yellow>"
|
||||
warning.config.resource_pack.generation.missing_equipment_texture: "<yellow>装备 '<arg:0>' 缺少纹理 '<arg:1>'</yellow>"
|
||||
warning.config.resource_pack.generation.texture_not_in_atlas: "<yellow>纹理'<arg:0>'不在图集内. 你需要将纹理路径或文件夹前缀添加到图集内,或者启用 config.yml 中的 'obfuscation' 选项</yellow>"
|
||||
warning.config.resource_pack.invalid_overlay_format: "<yellow>在 config.yml 的 'resource-pack.overlay-format' 处发现问题 - 无效的overlay格式 '<arg:0>'. Overlay格式必须包含占位符 '{version}'</yellow>"
|
||||
warning.config.equipment.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的装备配置 '<arg:1>'。请检查其他文件中是否存在相同配置</yellow>"
|
||||
warning.config.equipment.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 装备 '<arg:1>' 缺少必需的 'type' 参数</yellow>"
|
||||
|
||||
@@ -52,6 +52,14 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
|
||||
public abstract boolean isSneaking();
|
||||
|
||||
public abstract boolean isSwimming();
|
||||
|
||||
public abstract boolean isClimbing();
|
||||
|
||||
public abstract boolean isGliding();
|
||||
|
||||
public abstract boolean isFlying();
|
||||
|
||||
public abstract GameMode gameMode();
|
||||
|
||||
public abstract void setGameMode(GameMode gameMode);
|
||||
@@ -106,9 +114,9 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
|
||||
public abstract void performCommand(String command);
|
||||
|
||||
public abstract double luck();
|
||||
public abstract void performCommandAsEvent(String command);
|
||||
|
||||
public abstract boolean isFlying();
|
||||
public abstract double luck();
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
|
||||
@@ -10,6 +10,8 @@ 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 MATCH_ENTITY_TYPE = Key.of("craftengine:match_entity_type");
|
||||
public static final Key MATCH_BLOCK_TYPE = Key.of("craftengine:match_block_type");
|
||||
public static final Key MATCH_BLOCK_PROPERTY = Key.from("craftengine:match_block_property");
|
||||
public static final Key TABLE_BONUS = Key.from("craftengine:table_bonus");
|
||||
public static final Key SURVIVES_EXPLOSION = Key.from("craftengine:survives_explosion");
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package net.momirealms.craftengine.core.plugin.context.condition;
|
||||
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
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.plugin.locale.LocalizedResourceConfigException;
|
||||
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.BlockInWorld;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MatchBlockTypeCondition<CTX extends Context> implements Condition<CTX> {
|
||||
private final Set<String> ids;
|
||||
private final boolean regexMatch;
|
||||
|
||||
public MatchBlockTypeCondition(Collection<String> ids, boolean regexMatch) {
|
||||
this.ids = new HashSet<>(ids);
|
||||
this.regexMatch = regexMatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return CommonConditions.MATCH_ENTITY_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(CTX ctx) {
|
||||
Optional<BlockInWorld> block = ctx.getOptionalParameter(DirectContextParameters.BLOCK);
|
||||
if (block.isEmpty()) return false;
|
||||
Optional<ImmutableBlockState> customBlock = ctx.getOptionalParameter(DirectContextParameters.CUSTOM_BLOCK_STATE);
|
||||
Key key = customBlock.isPresent() ? customBlock.get().owner().value().id() : block.get().type();
|
||||
return MiscUtils.matchObject(key, this.regexMatch, this.ids);
|
||||
}
|
||||
|
||||
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
|
||||
|
||||
@Override
|
||||
public Condition<CTX> create(Map<String, Object> arguments) {
|
||||
List<String> ids = MiscUtils.getAsStringList(arguments.get("id"));
|
||||
if (ids.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.condition.match_block_type.missing_id");
|
||||
}
|
||||
boolean regex = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("regex", false), "regex");
|
||||
return new MatchBlockTypeCondition<>(ids, regex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.momirealms.craftengine.core.plugin.context.condition;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.Entity;
|
||||
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.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MatchEntityTypeCondition<CTX extends Context> implements Condition<CTX> {
|
||||
private final Set<String> ids;
|
||||
private final boolean regexMatch;
|
||||
|
||||
public MatchEntityTypeCondition(Collection<String> ids, boolean regexMatch) {
|
||||
this.ids = new HashSet<>(ids);
|
||||
this.regexMatch = regexMatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return CommonConditions.MATCH_ENTITY_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(CTX ctx) {
|
||||
Optional<Entity> entity = ctx.getOptionalParameter(DirectContextParameters.ENTITY);
|
||||
if (entity.isEmpty()) return false;
|
||||
Key key = entity.get().type();
|
||||
return MiscUtils.matchObject(key, this.regexMatch, this.ids);
|
||||
}
|
||||
|
||||
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
|
||||
|
||||
@Override
|
||||
public Condition<CTX> create(Map<String, Object> arguments) {
|
||||
List<String> ids = MiscUtils.getAsStringList(arguments.get("id"));
|
||||
if (ids.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.condition.match_entity_type.missing_id");
|
||||
}
|
||||
boolean regex = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("regex", false), "regex");
|
||||
return new MatchEntityTypeCondition<>(ids, regex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,17 +30,7 @@ public class MatchItemCondition<CTX extends Context> implements Condition<CTX> {
|
||||
Optional<Item<?>> item = ctx.getOptionalParameter(DirectContextParameters.ITEM_IN_HAND);
|
||||
if (item.isEmpty()) return false;
|
||||
Key key = item.get().id();
|
||||
String itemId = key.toString();
|
||||
if (this.regexMatch) {
|
||||
for (String regex : ids) {
|
||||
if (itemId.matches(regex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.ids.contains(itemId);
|
||||
}
|
||||
return false;
|
||||
return MiscUtils.matchObject(key, this.regexMatch, this.ids);
|
||||
}
|
||||
|
||||
public static class FactoryImpl<CTX extends Context> implements ConditionFactory<CTX> {
|
||||
|
||||
@@ -17,6 +17,8 @@ public class EventConditions {
|
||||
|
||||
static {
|
||||
register(CommonConditions.MATCH_ITEM, new MatchItemCondition.FactoryImpl<>());
|
||||
register(CommonConditions.MATCH_ENTITY_TYPE, new MatchEntityTypeCondition.FactoryImpl<>());
|
||||
register(CommonConditions.MATCH_BLOCK_TYPE, new MatchBlockTypeCondition.FactoryImpl<>());
|
||||
register(CommonConditions.MATCH_BLOCK_PROPERTY, new MatchBlockPropertyCondition.FactoryImpl<>());
|
||||
register(CommonConditions.TABLE_BONUS, new TableBonusCondition.FactoryImpl<>());
|
||||
register(CommonConditions.SURVIVES_EXPLOSION, new SurvivesExplosionCondition.FactoryImpl<>());
|
||||
|
||||
@@ -16,34 +16,34 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CommandFunction<CTX extends Context> extends AbstractConditionalFunction<CTX> {
|
||||
private final List<TextProvider> command;
|
||||
private final boolean asPlayer;
|
||||
private final PlayerSelector<CTX> selector;
|
||||
private final boolean asPlayer;
|
||||
private final boolean asEvent;
|
||||
|
||||
public CommandFunction(List<Condition<CTX>> predicates, @Nullable PlayerSelector<CTX> selector, List<TextProvider> command, boolean asPlayer) {
|
||||
public CommandFunction(List<Condition<CTX>> predicates, @Nullable PlayerSelector<CTX> selector, List<TextProvider> command, boolean asPlayer, boolean asEvent) {
|
||||
super(predicates);
|
||||
this.asPlayer = asPlayer;
|
||||
this.command = command;
|
||||
this.selector = selector;
|
||||
this.asPlayer = asPlayer;
|
||||
this.asEvent = asEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runInternal(CTX ctx) {
|
||||
if (this.asPlayer) {
|
||||
if (this.selector == null) {
|
||||
ctx.getOptionalParameter(DirectContextParameters.PLAYER).ifPresent(it -> {
|
||||
for (TextProvider c : this.command) {
|
||||
it.performCommand(c.get(ctx));
|
||||
}
|
||||
});
|
||||
ctx.getOptionalParameter(DirectContextParameters.PLAYER)
|
||||
.ifPresent(player -> executeCommands(
|
||||
ctx, this.asEvent ? player::performCommandAsEvent : player::performCommand
|
||||
));
|
||||
} else {
|
||||
for (Player viewer : this.selector.get(ctx)) {
|
||||
RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY));
|
||||
for (TextProvider c : this.command) {
|
||||
viewer.performCommand(c.get(relationalContext));
|
||||
}
|
||||
executeCommands(relationalContext, this.asEvent ? viewer::performCommandAsEvent : viewer::performCommand);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -54,6 +54,12 @@ public class CommandFunction<CTX extends Context> extends AbstractConditionalFun
|
||||
}
|
||||
}
|
||||
|
||||
private void executeCommands(Context ctx, Consumer<String> executor) {
|
||||
for (TextProvider c : this.command) {
|
||||
executor.accept(c.get(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return CommonFunctions.COMMAND;
|
||||
@@ -70,7 +76,8 @@ public class CommandFunction<CTX extends Context> extends AbstractConditionalFun
|
||||
Object command = ResourceConfigUtils.requireNonNullOrThrow(ResourceConfigUtils.get(arguments, "command", "commands"), "warning.config.function.command.missing_command");
|
||||
List<TextProvider> commands = MiscUtils.getAsStringList(command).stream().map(TextProviders::fromString).toList();
|
||||
boolean asPlayer = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("as-player", false), "as-player");
|
||||
return new CommandFunction<>(getPredicates(arguments), PlayerSelectors.fromObject(arguments.get("target"), conditionFactory()), commands, asPlayer);
|
||||
boolean asEvent = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("as-event", false), "as-event");
|
||||
return new CommandFunction<>(getPredicates(arguments), PlayerSelectors.fromObject(arguments.get("target"), conditionFactory()), commands, asPlayer, asEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +57,11 @@ public final class DirectContextParameters {
|
||||
public static final ContextKey<AnchorType> ANCHOR_TYPE = ContextKey.direct("anchor_type");
|
||||
public static final ContextKey<InteractionHand> HAND = ContextKey.direct("hand");
|
||||
public static final ContextKey<Cancellable> EVENT = ContextKey.direct("event");
|
||||
public static final ContextKey<Boolean> IS_FLYING = ContextKey.direct("is_flying");
|
||||
public static final ContextKey<Boolean> IS_SNEAKING = ContextKey.direct("is_sneaking");
|
||||
public static final ContextKey<Boolean> IS_SWIMMING = ContextKey.direct("is_swimming");
|
||||
public static final ContextKey<Boolean> IS_CLIMBING = ContextKey.direct("is_climbing");
|
||||
public static final ContextKey<Boolean> IS_GLIDING = ContextKey.direct("is_gliding");
|
||||
public static final ContextKey<Boolean> IS_FLYING = ContextKey.direct("is_flying");
|
||||
public static final ContextKey<Boolean> IS_CUSTOM = ContextKey.direct("is_custom");
|
||||
public static final ContextKey<Boolean> IS_BLOCK_ITEM = ContextKey.direct("is_block_item");
|
||||
public static final ContextKey<GameMode> GAMEMODE = ContextKey.direct("gamemode");
|
||||
|
||||
@@ -29,8 +29,11 @@ public class PlayerParameterProvider implements ChainParameterProvider<Player> {
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.NAME, Player::name);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.UUID, Player::uuid);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.WORLD, Entity::world);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.IS_FLYING, Player::isFlying);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.IS_SNEAKING, Player::isSneaking);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.IS_SWIMMING, Player::isSwimming);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.IS_CLIMBING, Player::isClimbing);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.IS_GLIDING, Player::isGliding);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.IS_FLYING, Player::isFlying);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.GAMEMODE, Player::gameMode);
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.MAIN_HAND_ITEM, p -> p.getItemInHand(InteractionHand.MAIN_HAND));
|
||||
CONTEXT_FUNCTIONS.put(DirectContextParameters.OFF_HAND_ITEM, p -> p.getItemInHand(InteractionHand.OFF_HAND));
|
||||
|
||||
@@ -12,7 +12,8 @@ public enum SoundSource {
|
||||
NEUTRAL("neutral"),
|
||||
PLAYER("player"),
|
||||
AMBIENT("ambient"),
|
||||
VOICE("voice");
|
||||
VOICE("voice"),
|
||||
UI("ui");
|
||||
|
||||
private final String id;
|
||||
|
||||
|
||||
@@ -4,10 +4,7 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
public class MiscUtils {
|
||||
|
||||
@@ -153,4 +150,18 @@ public class MiscUtils {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean matchObject(Key key, boolean regexMatch, Set<String> ids) {
|
||||
String id = key.toString();
|
||||
if (regexMatch) {
|
||||
for (String regex : ids) {
|
||||
if (id.matches(regex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ids.contains(id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.world;
|
||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface BlockInWorld {
|
||||
@@ -27,6 +28,8 @@ public interface BlockInWorld {
|
||||
|
||||
World world();
|
||||
|
||||
Key type();
|
||||
|
||||
int x();
|
||||
|
||||
int y();
|
||||
|
||||
Reference in New Issue
Block a user