mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 17:09:19 +00:00
feat(block): 实现 wall_attached_block 行为
This commit is contained in:
@@ -32,6 +32,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
|||||||
public static final Key TOGGLEABLE_LAMP_BLOCK = Key.from("craftengine:toggleable_lamp_block");
|
public static final Key TOGGLEABLE_LAMP_BLOCK = Key.from("craftengine:toggleable_lamp_block");
|
||||||
public static final Key SOFA_BLOCK = Key.from("craftengine:sofa_block");
|
public static final Key SOFA_BLOCK = Key.from("craftengine:sofa_block");
|
||||||
public static final Key BOUNCING_BLOCK = Key.from("craftengine:bouncing_block");
|
public static final Key BOUNCING_BLOCK = Key.from("craftengine:bouncing_block");
|
||||||
|
public static final Key WALL_ATTACHED_BLOCK = Key.from("craftengine:wall_attached_block");
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
||||||
@@ -62,5 +63,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
|||||||
register(TOGGLEABLE_LAMP_BLOCK, ToggleableLampBlockBehavior.FACTORY);
|
register(TOGGLEABLE_LAMP_BLOCK, ToggleableLampBlockBehavior.FACTORY);
|
||||||
register(SOFA_BLOCK, SofaBlockBehavior.FACTORY);
|
register(SOFA_BLOCK, SofaBlockBehavior.FACTORY);
|
||||||
register(BOUNCING_BLOCK, BouncingBlockBehavior.FACTORY);
|
register(BOUNCING_BLOCK, BouncingBlockBehavior.FACTORY);
|
||||||
|
register(WALL_ATTACHED_BLOCK, WallAttachedBlockBehavior.FACTORY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||||
|
import net.momirealms.craftengine.core.block.BlockBehavior;
|
||||||
|
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||||
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
|
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||||
|
import net.momirealms.craftengine.core.block.properties.Property;
|
||||||
|
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||||
|
import net.momirealms.craftengine.core.util.Direction;
|
||||||
|
import net.momirealms.craftengine.core.util.HorizontalDirection;
|
||||||
|
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||||
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
|
import net.momirealms.craftengine.core.world.World;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class WallAttachedBlockBehavior extends BukkitBlockBehavior {
|
||||||
|
public static final Factory FACTORY = new Factory();
|
||||||
|
private final Property<HorizontalDirection> facingProperty;
|
||||||
|
|
||||||
|
public WallAttachedBlockBehavior(CustomBlock customBlock, Property<HorizontalDirection> facingProperty) {
|
||||||
|
super(customBlock);
|
||||||
|
this.facingProperty = facingProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||||
|
ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null);
|
||||||
|
if (state == null) return args[0];
|
||||||
|
WallAttachedBlockBehavior behavior = state.behavior().getAs(WallAttachedBlockBehavior.class).orElse(null);
|
||||||
|
if (behavior == null) return state;
|
||||||
|
HorizontalDirection direction = DirectionUtils.fromNMSDirection(args[updateShape$direction]).opposite().toHorizontalDirection();
|
||||||
|
return direction == state.get(behavior.facingProperty) && !FastNMS.INSTANCE.method$BlockStateBase$canSurvive(args[0], args[updateShape$level], args[updateShape$blockPos]) ? MBlocks.AIR$defaultState : args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canSurvive(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||||
|
ImmutableBlockState state = BlockStateUtils.getOptionalCustomBlockState(args[0]).orElse(null);
|
||||||
|
if (state == null) return false;
|
||||||
|
WallAttachedBlockBehavior behavior = state.behavior().getAs(WallAttachedBlockBehavior.class).orElse(null);
|
||||||
|
if (behavior == null) return false;
|
||||||
|
HorizontalDirection direction = state.get(behavior.facingProperty);
|
||||||
|
BlockPos blockPos = LocationUtils.fromBlockPos(args[2]).relative(direction.opposite().toDirection());
|
||||||
|
Object nmsPos = LocationUtils.toBlockPos(blockPos);
|
||||||
|
Object nmsState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(args[1], nmsPos);
|
||||||
|
return FastNMS.INSTANCE.method$BlockStateBase$isFaceSturdy(nmsState, args[1], nmsPos, DirectionUtils.toNMSDirection(direction.opposite().toDirection()), CoreReflections.instance$SupportType$FULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
|
||||||
|
WallAttachedBlockBehavior behavior = state.behavior().getAs(WallAttachedBlockBehavior.class).orElse(null);
|
||||||
|
if (behavior == null) return null;
|
||||||
|
World level = context.getLevel();
|
||||||
|
BlockPos clickedPos = context.getClickedPos();
|
||||||
|
Direction[] nearestLookingDirections = context.getNearestLookingDirections();
|
||||||
|
for (Direction direction : nearestLookingDirections) {
|
||||||
|
if (direction.axis().isHorizontal()) {
|
||||||
|
state = state.with(behavior.facingProperty, direction.opposite().toHorizontalDirection());
|
||||||
|
if (FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state.customBlockState().literalObject(), level.serverWorld(), LocationUtils.toBlockPos(clickedPos))) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Factory implements BlockBehaviorFactory {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||||
|
Property<HorizontalDirection> facing = (Property<HorizontalDirection>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.wall_attached.missing_facing");
|
||||||
|
return new WallAttachedBlockBehavior(block, facing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -316,6 +316,7 @@ 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.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.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.block.behavior.change_over_time.missing_next_block: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'next_block' property for 'change_over_time_block' behavior.</yellow>"
|
warning.config.block.behavior.change_over_time.missing_next_block: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'next_block' property for 'change_over_time_block' behavior.</yellow>"
|
||||||
|
warning.config.block.behavior.wall_attached.missing_facing: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'facing' property for 'wall_attached_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.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.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_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>"
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ warning.config.block.behavior.pressure_plate.missing_powered: "<yellow>在文件
|
|||||||
warning.config.block.behavior.grass.missing_feature: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'grass_block' 行为缺少必需的 'feature' 参数</yellow>"
|
warning.config.block.behavior.grass.missing_feature: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'grass_block' 行为缺少必需的 'feature' 参数</yellow>"
|
||||||
warning.config.block.behavior.double_high.missing_half: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'double_block' 行为缺少必需的 'half' 属性</yellow>"
|
warning.config.block.behavior.double_high.missing_half: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'double_block' 行为缺少必需的 'half' 属性</yellow>"
|
||||||
warning.config.block.behavior.change_over_time.missing_next_block: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'change_over_time_block' 行为缺少必需的 'next-block' 配置项</yellow>"
|
warning.config.block.behavior.change_over_time.missing_next_block: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'change_over_time_block' 行为缺少必需的 'next-block' 配置项</yellow>"
|
||||||
|
warning.config.block.behavior.wall_attached.missing_facing: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'wall_attached_block' 行为缺少必需的 'facing' 属性</yellow>"
|
||||||
warning.config.model.generation.missing_parent: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 的 'generation' 段落缺少必需的 'parent' 参数</yellow>"
|
warning.config.model.generation.missing_parent: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 的 'generation' 段落缺少必需的 'parent' 参数</yellow>"
|
||||||
warning.config.model.generation.conflict: "<yellow>在文件 <arg:0> 发现问题 - 无法为 '<arg:1>' 生成模型 存在多个配置尝试使用相同路径 '<arg:2>' 生成不同的 JSON 模型</yellow>"
|
warning.config.model.generation.conflict: "<yellow>在文件 <arg:0> 发现问题 - 无法为 '<arg:1>' 生成模型 存在多个配置尝试使用相同路径 '<arg:2>' 生成不同的 JSON 模型</yellow>"
|
||||||
warning.config.model.generation.invalid_display_position: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 在 'generation.display' 区域使用了无效的 display 位置类型 '<arg:2>'. 可用展示类型: [<arg:3>]</yellow>"
|
warning.config.model.generation.invalid_display_position: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 在 'generation.display' 区域使用了无效的 display 位置类型 '<arg:2>'. 可用展示类型: [<arg:3>]</yellow>"
|
||||||
|
|||||||
@@ -48,4 +48,23 @@ public class BlockPlaceContext extends UseOnContext {
|
|||||||
public Direction getNearestLookingDirection() {
|
public Direction getNearestLookingDirection() {
|
||||||
return Direction.orderedByNearest(this.getPlayer())[0];
|
return Direction.orderedByNearest(this.getPlayer())[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Direction[] getNearestLookingDirections() {
|
||||||
|
Direction[] directions = Direction.orderedByNearest(this.getPlayer());
|
||||||
|
if (!this.replaceClicked) {
|
||||||
|
Direction clickedFace = this.getClickedFace();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < directions.length && directions[i] != clickedFace.opposite()) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
System.arraycopy(directions, 0, directions, 1, i);
|
||||||
|
directions[0] = clickedFace.opposite();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return directions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
# Rule: [major update].[feature update].[bug fix]
|
# Rule: [major update].[feature update].[bug fix]
|
||||||
project_version=0.0.62.19
|
project_version=0.0.62.19
|
||||||
config_version=45
|
config_version=45
|
||||||
lang_version=27
|
lang_version=28
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
latest_supported_version=1.21.8
|
latest_supported_version=1.21.8
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user