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

feat(block): 允许6/4向附着

This commit is contained in:
jhqwqmc
2025-09-14 01:46:15 +08:00
parent 3b3baf0ac7
commit ed154361eb
6 changed files with 49 additions and 26 deletions

View File

@@ -32,7 +32,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
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 BOUNCING_BLOCK = Key.from("craftengine:bouncing_block");
public static final Key WALL_ATTACHED_BLOCK = Key.from("craftengine:wall_attached_block");
public static final Key SURFACE_ATTACHED_BLOCK = Key.from("craftengine:surface_attached_block");
public static void init() {
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
@@ -63,6 +63,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
register(TOGGLEABLE_LAMP_BLOCK, ToggleableLampBlockBehavior.FACTORY);
register(SOFA_BLOCK, SofaBlockBehavior.FACTORY);
register(BOUNCING_BLOCK, BouncingBlockBehavior.FACTORY);
register(WALL_ATTACHED_BLOCK, WallAttachedBlockBehavior.FACTORY);
register(SURFACE_ATTACHED_BLOCK, SurfaceAttachedBlockBehavior.FACTORY);
}
}

View File

@@ -12,6 +12,7 @@ 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.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.HorizontalDirection;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
@@ -21,48 +22,68 @@ import net.momirealms.craftengine.core.world.World;
import java.util.Map;
import java.util.concurrent.Callable;
public class WallAttachedBlockBehavior extends BukkitBlockBehavior {
public class SurfaceAttachedBlockBehavior extends BukkitBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Property<HorizontalDirection> facingProperty;
private final Property<?> facingProperty;
private final boolean isDirection;
public WallAttachedBlockBehavior(CustomBlock customBlock, Property<HorizontalDirection> facingProperty) {
public SurfaceAttachedBlockBehavior(CustomBlock customBlock, Property<?> facingProperty, boolean isDirection) {
super(customBlock);
this.facingProperty = facingProperty;
this.isDirection = isDirection;
}
@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);
SurfaceAttachedBlockBehavior behavior = state.behavior().getAs(SurfaceAttachedBlockBehavior.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];
boolean flag;
if (isDirection) {
Direction direction = DirectionUtils.fromNMSDirection(args[updateShape$direction]).opposite();
flag = direction == state.get(behavior.facingProperty);
} else {
HorizontalDirection direction = DirectionUtils.fromNMSDirection(args[updateShape$direction]).opposite().toHorizontalDirection();
flag = direction == state.get(behavior.facingProperty);
}
return flag && !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);
SurfaceAttachedBlockBehavior behavior = state.behavior().getAs(SurfaceAttachedBlockBehavior.class).orElse(null);
if (behavior == null) return false;
HorizontalDirection direction = state.get(behavior.facingProperty);
BlockPos blockPos = LocationUtils.fromBlockPos(args[2]).relative(direction.opposite().toDirection());
Direction direction;
if (isDirection) {
direction = ((Direction) state.get(behavior.facingProperty)).opposite();
} else {
direction = ((HorizontalDirection) state.get(behavior.facingProperty)).opposite().toDirection();
}
BlockPos blockPos = LocationUtils.fromBlockPos(args[2]).relative(direction);
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);
return FastNMS.INSTANCE.method$BlockStateBase$isFaceSturdy(nmsState, args[1], nmsPos, DirectionUtils.toNMSDirection(direction), CoreReflections.instance$SupportType$FULL);
}
@SuppressWarnings("unchecked")
@Override
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
WallAttachedBlockBehavior behavior = state.behavior().getAs(WallAttachedBlockBehavior.class).orElse(null);
SurfaceAttachedBlockBehavior behavior = state.behavior().getAs(SurfaceAttachedBlockBehavior.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());
for (Direction direction : context.getNearestLookingDirections()) {
if (isDirection) {
state = state.with((Property<Direction>) behavior.facingProperty, direction.opposite());
if (FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state.customBlockState().literalObject(), level.serverWorld(), LocationUtils.toBlockPos(clickedPos))) {
return state;
}
} else if (direction.axis().isHorizontal()) {
state = state.with((Property<HorizontalDirection>) behavior.facingProperty, direction.opposite().toHorizontalDirection());
if (FastNMS.INSTANCE.method$BlockStateBase$canSurvive(state.customBlockState().literalObject(), level.serverWorld(), LocationUtils.toBlockPos(clickedPos))) {
return state;
}
@@ -73,11 +94,15 @@ public class WallAttachedBlockBehavior extends BukkitBlockBehavior {
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);
Property<?> facing = ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.surface_attached.missing_facing");
boolean isHorizontalDirection = facing.valueClass() == HorizontalDirection.class;
boolean isDirection = facing.valueClass() == Direction.class;
if (!(isHorizontalDirection || isDirection)) {
throw new LocalizedResourceConfigException("warning.config.block.behavior.surface_attached.missing_facing");
}
return new SurfaceAttachedBlockBehavior(block, facing, isDirection);
}
}
}

View File

@@ -5,7 +5,6 @@ import net.momirealms.craftengine.bukkit.block.entity.BlockEntityHolder;
import net.momirealms.craftengine.bukkit.block.entity.SimpleStorageBlockEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
@@ -91,7 +90,7 @@ public class BukkitGuiManager implements GuiManager, Listener {
@Override
public Inventory createInventory(Gui gui, int size) {
CraftEngineGUIHolder holder = new CraftEngineGUIHolder(gui);
org.bukkit.inventory.Inventory inventory = Bukkit.createInventory(holder, size);
org.bukkit.inventory.Inventory inventory = FastNMS.INSTANCE.createCraftEngineWorldlyContainer(holder, size, false, false);
holder.holder().bindValue(inventory);
return new BukkitInventory(inventory);
}

View File

@@ -2,7 +2,6 @@ package net.momirealms.craftengine.bukkit.util;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.nms.StorageContainer;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryEvent;
@@ -58,6 +57,6 @@ public final class InventoryUtils {
if (inventory == null) return false;
Object container = FastNMS.INSTANCE.method$CraftInventory$getInventory(inventory);
if (container == null) return false;
return CraftBukkitReflections.clazz$MinecraftInventory.isInstance(container) || container instanceof StorageContainer;
return container instanceof StorageContainer;
}
}

View File

@@ -316,7 +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.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.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.block.behavior.surface_attached.missing_facing: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'facing' property for 'surface_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.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>"

View File

@@ -311,7 +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.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.wall_attached.missing_facing: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'wall_attached_block' 行为缺少必需的 'facing' 属性</yellow>"
warning.config.block.behavior.surface_attached.missing_facing: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'surface_attached_block' 行为缺少必需的 'facing' 属性</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.invalid_display_position: "<yellow>在文件 <arg:0> 发现问题 - 配置项 '<arg:1>' 在 'generation.display' 区域使用了无效的 display 位置类型 '<arg:2>'. 可用展示类型: [<arg:3>]</yellow>"