mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-26 02:19:23 +00:00
初步完成门行为
This commit is contained in:
@@ -62,7 +62,7 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object world = args[1];
|
||||
Object blockPos = args[2];
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 2);
|
||||
|
||||
@@ -20,6 +20,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
public static final Key GRASS_BLOCK = Key.from("craftengine:grass_block");
|
||||
public static final Key LAMP_BLOCK = Key.from("craftengine:lamp_block");
|
||||
public static final Key TRAPDOOR_BLOCK = Key.from("craftengine:trapdoor_block");
|
||||
public static final Key DOOR_BLOCK = Key.from("craftengine:door_block");
|
||||
|
||||
public static void init() {
|
||||
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
||||
@@ -38,5 +39,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||
register(GRASS_BLOCK, GrassBlockBehavior.FACTORY);
|
||||
register(LAMP_BLOCK, LampBlockBehavior.FACTORY);
|
||||
register(TRAPDOOR_BLOCK, TrapDoorBlockBehavior.FACTORY);
|
||||
register(DOOR_BLOCK, DoorBlockBehavior.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ public class ConcretePowderBlockBehavior extends BukkitBlockBehavior {
|
||||
return this.defaultBlockState;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Override
|
||||
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
|
||||
Object level = context.getLevel().serverWorld();
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
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.plugin.reflection.minecraft.MFluids;
|
||||
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.bukkit.world.BukkitWorld;
|
||||
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.UpdateOption;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.block.state.properties.DoorHinge;
|
||||
import net.momirealms.craftengine.core.block.state.properties.DoubleBlockHalf;
|
||||
import net.momirealms.craftengine.core.block.state.properties.SingleBlockHalf;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.ItemKeys;
|
||||
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Vec3d;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameEvent;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Door;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class DoorBlockBehavior extends BukkitBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final Property<DoubleBlockHalf> halfProperty;
|
||||
private final Property<HorizontalDirection> facingProperty;
|
||||
private final Property<DoorHinge> hingeProperty;
|
||||
private final Property<Boolean> poweredProperty;
|
||||
private final Property<Boolean> openProperty;
|
||||
private final boolean canOpenWithHand;
|
||||
private final boolean canOpenByWindCharge;
|
||||
|
||||
public DoorBlockBehavior(CustomBlock block,
|
||||
Property<DoubleBlockHalf> halfProperty,
|
||||
Property<HorizontalDirection> facingProperty,
|
||||
Property<DoorHinge> hingeProperty,
|
||||
Property<Boolean> poweredProperty,
|
||||
Property<Boolean> openProperty,
|
||||
boolean canOpenWithHand,
|
||||
boolean canOpenByWindCharge) {
|
||||
super(block);
|
||||
this.halfProperty = halfProperty;
|
||||
this.facingProperty = facingProperty;
|
||||
this.hingeProperty = hingeProperty;
|
||||
this.poweredProperty = poweredProperty;
|
||||
this.openProperty = openProperty;
|
||||
this.canOpenWithHand = canOpenWithHand;
|
||||
this.canOpenByWindCharge = canOpenByWindCharge;
|
||||
}
|
||||
|
||||
public boolean isOpen(ImmutableBlockState state) {
|
||||
return state.get(this.openProperty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object blockState = args[0];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState == null || immutableBlockState.isEmpty()) return blockState;
|
||||
DoubleBlockHalf half = immutableBlockState.get(this.halfProperty);
|
||||
Object direction = VersionHelper.isOrAbove1_21_2() ? args[4] : args[0];
|
||||
if (DirectionUtils.isYAxis(direction) && half == DoubleBlockHalf.LOWER == (direction == CoreReflections.instance$Direction$UP)) {
|
||||
ImmutableBlockState neighborState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(VersionHelper.isOrAbove1_21_2() ? args[6] : args[2]));
|
||||
if (neighborState == null || neighborState.isEmpty()) {
|
||||
return MBlocks.AIR$defaultState;
|
||||
}
|
||||
Optional<DoorBlockBehavior> anotherDoorBehavior = neighborState.behavior().getAs(DoorBlockBehavior.class);
|
||||
if (anotherDoorBehavior.isEmpty()) {
|
||||
return MBlocks.AIR$defaultState;
|
||||
}
|
||||
if (neighborState.get(anotherDoorBehavior.get().halfProperty) != half) {
|
||||
return neighborState.with(anotherDoorBehavior.get().halfProperty, half);
|
||||
}
|
||||
return MBlocks.AIR$defaultState;
|
||||
} else {
|
||||
return half == DoubleBlockHalf.LOWER &&
|
||||
direction == CoreReflections.instance$Direction$DOWN &&
|
||||
!FastNMS.INSTANCE.method$BlockStateBase$canSurvive(blockState, VersionHelper.isOrAbove1_21_2() ? args[1] : args[3], VersionHelper.isOrAbove1_21_2() ? args[3] : args[2]) ? MBlocks.AIR$defaultState : blockState;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExplosionHit(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
if (this.canOpenByWindCharge && FastNMS.INSTANCE.method$Explosion$canTriggerBlocks(args[3])) {
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(args[0]));
|
||||
if (state == null || state.isEmpty()) return;
|
||||
if (state.get(this.poweredProperty)) return;
|
||||
if (state.get(this.halfProperty) == DoubleBlockHalf.LOWER) {
|
||||
this.setOpen(null, args[1], state, LocationUtils.fromBlockPos(args[2]), !this.isOpen(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
|
||||
World world = context.getLevel();
|
||||
Object level = world.serverWorld();
|
||||
BlockPos pos = context.getClickedPos();
|
||||
if (pos.y() < context.getLevel().worldHeight().getMaxBuildHeight() && world.getBlockAt(pos.above()).canBeReplaced(context)) {
|
||||
boolean hasSignal = FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, LocationUtils.toBlockPos(pos)) || FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, LocationUtils.toBlockPos(pos.above()));
|
||||
return state.with(this.poweredProperty, hasSignal)
|
||||
.with(this.facingProperty, context.getHorizontalDirection().toHorizontalDirection())
|
||||
.with(this.openProperty, hasSignal)
|
||||
.with(this.halfProperty, DoubleBlockHalf.LOWER)
|
||||
.with(this.hingeProperty, getHinge(context));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private DoorHinge getHinge(BlockPlaceContext context) {
|
||||
Object serverLevel = context.getLevel().serverWorld();
|
||||
BlockPos clickedPos = context.getClickedPos();
|
||||
Direction horizontalDirection = context.getHorizontalDirection();
|
||||
BlockPos blockPos = clickedPos.above();
|
||||
|
||||
Direction counterClockWise = horizontalDirection.counterClockWise();
|
||||
Object blockPos1 = LocationUtils.toBlockPos(clickedPos.relative(counterClockWise));
|
||||
Object blockState1 = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, blockPos1);
|
||||
Object blockPos2 = LocationUtils.toBlockPos(blockPos.relative(counterClockWise));
|
||||
Object blockState2 = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, blockPos2);
|
||||
|
||||
Direction clockWise = horizontalDirection.clockWise();
|
||||
Object blockPos3 = LocationUtils.toBlockPos(clickedPos.relative(clockWise));
|
||||
Object blockState3 = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, blockPos3);
|
||||
Object blockPos4 = LocationUtils.toBlockPos(blockPos.relative(clockWise));
|
||||
Object blockState4 = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, blockPos4);
|
||||
|
||||
int i = (FastNMS.INSTANCE.method$BlockStateBase$isCollisionShapeFullBlock(blockState1, serverLevel, blockPos1) ? -1 : 0) +
|
||||
(FastNMS.INSTANCE.method$BlockStateBase$isCollisionShapeFullBlock(blockState2, serverLevel, blockPos2) ? -1 : 0) +
|
||||
(FastNMS.INSTANCE.method$BlockStateBase$isCollisionShapeFullBlock(blockState3, serverLevel, blockPos3) ? 1 : 0) +
|
||||
(FastNMS.INSTANCE.method$BlockStateBase$isCollisionShapeFullBlock(blockState4, serverLevel, blockPos4) ? 1 : 0);
|
||||
|
||||
boolean anotherDoor1 = isAnotherDoor(blockState1);
|
||||
boolean anotherDoor2 = isAnotherDoor(blockState3);
|
||||
if ((!anotherDoor1 || anotherDoor2) && i <= 0) {
|
||||
if ((!anotherDoor2 || anotherDoor1) && i == 0) {
|
||||
int stepX = horizontalDirection.stepX();
|
||||
int stepZ = horizontalDirection.stepZ();
|
||||
Vec3d clickLocation = context.getClickLocation();
|
||||
double d = clickLocation.x - (double) clickedPos.x();
|
||||
double d1 = clickLocation.z - (double) clickedPos.z();
|
||||
return stepX < 0 && d1 < (double) 0.5F || stepX > 0 && d1 > (double) 0.5F || stepZ < 0 && d > (double) 0.5F || stepZ > 0 && d < (double) 0.5F ? DoorHinge.RIGHT : DoorHinge.LEFT;
|
||||
} else {
|
||||
return DoorHinge.LEFT;
|
||||
}
|
||||
} else {
|
||||
return DoorHinge.RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAnotherDoor(Object blockState) {
|
||||
int id = BlockStateUtils.blockStateToId(blockState);
|
||||
if (BlockStateUtils.isVanillaBlock(id)) {
|
||||
BlockData blockData = BlockStateUtils.fromBlockData(blockState);
|
||||
return blockData instanceof Door door && door.getHalf() == Bisected.Half.BOTTOM;
|
||||
} else {
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(id);
|
||||
if (state.isEmpty()) return false;
|
||||
Optional<DoorBlockBehavior> optional = state.behavior().getAs(DoorBlockBehavior.class);
|
||||
return optional.isPresent() && state.get(optional.get().halfProperty) == DoubleBlockHalf.LOWER;
|
||||
}
|
||||
}
|
||||
|
||||
public void setOpen(@Nullable Player player, Object serverLevel, ImmutableBlockState state, BlockPos pos, boolean isOpen) {
|
||||
if (isOpen(state) != isOpen) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(serverLevel, LocationUtils.toBlockPos(pos), state.with(this.openProperty, isOpen).customBlockState().handle(), UpdateOption.builder().updateImmediate().updateClients().build().flags());
|
||||
FastNMS.INSTANCE.method$Level$getCraftWorld(serverLevel).sendGameEvent(player == null ? null : (org.bukkit.entity.Player) player.platformPlayer(), isOpen ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(pos.x(), pos.y(), pos.z()));
|
||||
// todo 播放声音
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context, ImmutableBlockState state) {
|
||||
if (!this.canOpenWithHand) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
setOpen(context.getPlayer(), context.getLevel().serverWorld(), state, context.getClickedPos(), !state.get(this.openProperty));
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathFindable(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object type = VersionHelper.isOrAbove1_20_5() ? args[1] : args[3];
|
||||
Object blockState = args[0];
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (state == null || state.isEmpty()) return false;
|
||||
if (type == CoreReflections.instance$PathComputationType$LAND || type == CoreReflections.instance$PathComputationType$AIR) {
|
||||
return state.get(this.openProperty);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Override
|
||||
public void neighborChanged(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object blockPos = args[2];
|
||||
Object level = args[1];
|
||||
Object blockState = args[0];
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (immutableBlockState == null || immutableBlockState.isEmpty()) return;
|
||||
Object anotherHalfPos = immutableBlockState.get(this.halfProperty) == DoubleBlockHalf.LOWER ? LocationUtils.above(blockPos) : LocationUtils.below(blockPos);
|
||||
Block bukkitBlock = FastNMS.INSTANCE.method$CraftBlock$at(level, blockPos);
|
||||
Block anotherBukkitBlock = FastNMS.INSTANCE.method$CraftBlock$at(level, anotherHalfPos);
|
||||
int power = Math.max(bukkitBlock.getBlockPower(), anotherBukkitBlock.getBlockPower());
|
||||
int oldPower = immutableBlockState.get(this.poweredProperty) ? 15 : 0;
|
||||
if (oldPower == 0 ^ power == 0) {
|
||||
BlockRedstoneEvent event = new BlockRedstoneEvent(bukkitBlock, oldPower, power);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
boolean flag = event.getNewCurrent() > 0;
|
||||
if (flag != immutableBlockState.get(this.openProperty)) {
|
||||
FastNMS.INSTANCE.method$Level$getCraftWorld(level).sendGameEvent(null, flag ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ()));
|
||||
// todo 播放声音
|
||||
}
|
||||
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, immutableBlockState.with(this.poweredProperty, flag).with(this.openProperty, flag).customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static class Factory implements BlockBehaviorFactory {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
Property<DoubleBlockHalf> half = (Property<DoubleBlockHalf>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("half"), "warning.config.block.behavior.door.missing_half");
|
||||
Property<HorizontalDirection> facing = (Property<HorizontalDirection>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.door.missing_facing");
|
||||
Property<DoorHinge> hinge = (Property<DoorHinge>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("hinge"), "warning.config.block.behavior.door.missing_hinge");
|
||||
Property<Boolean> open = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.door.missing_open");
|
||||
Property<Boolean> powered = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("powered"), "warning.config.block.behavior.door.missing_powered");
|
||||
boolean canOpenWithHand = (boolean) arguments.getOrDefault("can-open-with-hand", true);
|
||||
boolean canOpenByWindCharge = (boolean) arguments.getOrDefault("can-open-by-wind-charge", true);
|
||||
return new DoorBlockBehavior(block, half, facing, hinge, powered, open, canOpenWithHand, canOpenByWindCharge);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,14 +33,14 @@ public class FallingBlockBehavior extends BukkitBlockBehavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object world = args[1];
|
||||
Object blockPos = args[2];
|
||||
FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object world;
|
||||
Object blockPos;
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
|
||||
@@ -52,7 +52,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
|
||||
public void neighborChanged(Object thisBlock, Object[] args, Callable<Object> superMethod) {
|
||||
Object blockState = args[0];
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
if (state == null || state.isEmpty()) return;
|
||||
|
||||
@@ -15,6 +15,7 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.block.UpdateOption;
|
||||
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.block.properties.Property;
|
||||
import net.momirealms.craftengine.core.block.state.properties.SingleBlockHalf;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.ItemKeys;
|
||||
@@ -36,8 +37,8 @@ import java.util.concurrent.Callable;
|
||||
|
||||
public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final Property<Half> halfProperty;
|
||||
private final Property<HorizontalDirection> directionProperty;
|
||||
private final Property<SingleBlockHalf> halfProperty;
|
||||
private final Property<HorizontalDirection> facingProperty;
|
||||
private final Property<Boolean> poweredProperty;
|
||||
private final Property<Boolean> openProperty;
|
||||
private final boolean canOpenWithHand;
|
||||
@@ -45,15 +46,15 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
|
||||
public TrapDoorBlockBehavior(CustomBlock block,
|
||||
@Nullable Property<Boolean> waterloggedProperty,
|
||||
Property<Half> halfProperty,
|
||||
Property<HorizontalDirection> directionProperty,
|
||||
Property<SingleBlockHalf> halfProperty,
|
||||
Property<HorizontalDirection> facingProperty,
|
||||
Property<Boolean> poweredProperty,
|
||||
Property<Boolean> openProperty,
|
||||
boolean canOpenWithHand,
|
||||
boolean canOpenByWindCharge) {
|
||||
super(block, waterloggedProperty);
|
||||
this.halfProperty = halfProperty;
|
||||
this.directionProperty = directionProperty;
|
||||
this.facingProperty = facingProperty;
|
||||
this.poweredProperty = poweredProperty;
|
||||
this.openProperty = openProperty;
|
||||
this.canOpenWithHand = canOpenWithHand;
|
||||
@@ -78,11 +79,11 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
Object clickedPos = LocationUtils.toBlockPos(context.getClickedPos());
|
||||
Direction clickedFace = context.getClickedFace();
|
||||
if (!context.replacingClickedOnBlock() && clickedFace.axis().isHorizontal()) {
|
||||
state = state.with(this.directionProperty, clickedFace.toHorizontalDirection())
|
||||
.with(this.halfProperty, context.getClickLocation().y - context.getClickedPos().y() > 0.5 ? Half.TOP : Half.BOTTOM);
|
||||
state = state.with(this.facingProperty, clickedFace.toHorizontalDirection())
|
||||
.with(this.halfProperty, context.getClickLocation().y - context.getClickedPos().y() > 0.5 ? SingleBlockHalf.TOP : SingleBlockHalf.BOTTOM);
|
||||
} else {
|
||||
state = state.with(this.directionProperty, context.getHorizontalDirection().opposite().toHorizontalDirection())
|
||||
.with(this.halfProperty, clickedFace == Direction.UP ? Half.BOTTOM : Half.TOP);
|
||||
state = state.with(this.facingProperty, context.getHorizontalDirection().opposite().toHorizontalDirection())
|
||||
.with(this.halfProperty, clickedFace == Direction.UP ? SingleBlockHalf.BOTTOM : SingleBlockHalf.TOP);
|
||||
}
|
||||
if (FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, clickedPos)) {
|
||||
state = state.with(this.poweredProperty, true);
|
||||
@@ -195,13 +196,13 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior {
|
||||
@Override
|
||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||
Property<Boolean> waterlogged = (Property<Boolean>) block.getProperty("waterlogged");
|
||||
Property<Half> half = (Property<Half>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("half"), "warning.config.block.behavior.trapdoor.missing_half");
|
||||
Property<HorizontalDirection> direction = (Property<HorizontalDirection>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("direction"), "warning.config.block.behavior.trapdoor.missing_direction");
|
||||
Property<SingleBlockHalf> half = (Property<SingleBlockHalf>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("half"), "warning.config.block.behavior.trapdoor.missing_half");
|
||||
Property<HorizontalDirection> facing = (Property<HorizontalDirection>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("facing"), "warning.config.block.behavior.trapdoor.missing_facing");
|
||||
Property<Boolean> open = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_open");
|
||||
Property<Boolean> powered = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_powered");
|
||||
Property<Boolean> powered = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("powered"), "warning.config.block.behavior.trapdoor.missing_powered");
|
||||
boolean canOpenWithHand = (boolean) arguments.getOrDefault("can-open-with-hand", true);
|
||||
boolean canOpenByWindCharge = (boolean) arguments.getOrDefault("can-open-by-wind-charge", true);
|
||||
return new TrapDoorBlockBehavior(block, waterlogged, half, direction, powered, open, canOpenWithHand, canOpenByWindCharge);
|
||||
return new TrapDoorBlockBehavior(block, waterlogged, half, facing, powered, open, canOpenWithHand, canOpenByWindCharge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,4 +50,8 @@ public class DirectionUtils {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isYAxis(Object nmsDirection) {
|
||||
return nmsDirection == CoreReflections.instance$Direction$UP || nmsDirection == CoreReflections.instance$Direction$DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ public class UnsafeCompositeBlockBehavior extends AbstractBlockBehavior {
|
||||
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
|
||||
for (AbstractBlockBehavior behavior : this.behaviors) {
|
||||
state = behavior.updateStateForPlacement(context, state);
|
||||
if (state == null) return null;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package net.momirealms.craftengine.core.block.properties;
|
||||
|
||||
import net.momirealms.craftengine.core.block.state.properties.DoubleBlockHalf;
|
||||
import net.momirealms.craftengine.core.block.state.properties.SingleBlockHalf;
|
||||
import net.momirealms.craftengine.core.block.state.properties.DoorHinge;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
@@ -16,7 +19,9 @@ public class Properties {
|
||||
public static final Key AXIS = Key.of("craftengine:axis");
|
||||
public static final Key HORIZONTAL_DIRECTION = Key.of("craftengine:4-direction");
|
||||
public static final Key DIRECTION = Key.of("craftengine:6-direction");
|
||||
public static final Key HALF = Key.of("craftengine:half");
|
||||
public static final Key SINGLE_BLOCK_HALF = Key.of("craftengine:single_block_half");
|
||||
public static final Key DOUBLE_BLOCK_HALF = Key.of("craftengine:double_block_half");
|
||||
public static final Key HINGE = Key.of("craftengine:hinge");
|
||||
|
||||
static {
|
||||
register(BOOLEAN, BooleanProperty.FACTORY);
|
||||
@@ -25,7 +30,9 @@ public class Properties {
|
||||
register(AXIS, new EnumProperty.Factory<>(Direction.Axis.class));
|
||||
register(DIRECTION, new EnumProperty.Factory<>(Direction.class));
|
||||
register(HORIZONTAL_DIRECTION, new EnumProperty.Factory<>(HorizontalDirection.class));
|
||||
register(HALF, new EnumProperty.Factory<>(Half.class));
|
||||
register(SINGLE_BLOCK_HALF, new EnumProperty.Factory<>(SingleBlockHalf.class));
|
||||
register(DOUBLE_BLOCK_HALF, new EnumProperty.Factory<>(DoubleBlockHalf.class));
|
||||
register(HINGE, new EnumProperty.Factory<>(DoorHinge.class));
|
||||
}
|
||||
|
||||
public static void register(Key key, PropertyFactory factory) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.momirealms.craftengine.core.block.state.properties;
|
||||
|
||||
public enum DoorHinge {
|
||||
LEFT, RIGHT
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.momirealms.craftengine.core.block.state.properties;
|
||||
|
||||
public enum DoubleBlockHalf {
|
||||
UPPER, LOWER
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.momirealms.craftengine.core.block.state.properties;
|
||||
|
||||
public enum SingleBlockHalf {
|
||||
TOP, BOTTOM
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
public enum Half {
|
||||
TOP, BOTTOM
|
||||
}
|
||||
@@ -35,6 +35,10 @@ public class BlockPos extends Vec3i {
|
||||
: new BlockPos(this.x() + direction.stepX() * i, this.y() + direction.stepY() * i, this.z() + direction.stepZ() * i);
|
||||
}
|
||||
|
||||
public BlockPos above() {
|
||||
return new BlockPos(this.x(), this.y() + 1, this.z());
|
||||
}
|
||||
|
||||
public int toSectionBlockIndex() {
|
||||
return (y & 15) << 8 | (z & 15) << 4 | x & 15;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.17
|
||||
nms_helper_version=0.67.24
|
||||
nms_helper_version=0.67.26
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.31.23
|
||||
|
||||
Reference in New Issue
Block a user