9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 18:09:27 +00:00

feat(block): 实现门方块存活

This commit is contained in:
jhqwqmc
2025-06-19 12:20:45 +08:00
parent 73b127a5be
commit 3a3940fd67
2 changed files with 51 additions and 11 deletions

View File

@@ -100,7 +100,7 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio
}
world.playBlockSound(position, previousState.sounds().breakSound());
FastNMS.INSTANCE.method$Level$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, stateId);
return CoreReflections.method$Block$defaultBlockState.invoke(MBlocks.AIR);
return MBlocks.AIR$defaultState;
}
return state;
}

View File

@@ -7,6 +7,7 @@ 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.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
@@ -17,15 +18,16 @@ import net.momirealms.craftengine.core.block.state.properties.DoorHinge;
import net.momirealms.craftengine.core.block.state.properties.DoubleBlockHalf;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
import net.momirealms.craftengine.core.item.context.UseOnContext;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters;
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.util.VersionHelper;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.Vec3d;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.*;
import org.bukkit.Bukkit;
import org.bukkit.GameEvent;
import org.bukkit.block.Block;
@@ -40,7 +42,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
public class DoorBlockBehavior extends BukkitBlockBehavior {
public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Property<DoubleBlockHalf> halfProperty;
private final Property<HorizontalDirection> facingProperty;
@@ -58,7 +60,7 @@ public class DoorBlockBehavior extends BukkitBlockBehavior {
Property<Boolean> openProperty,
boolean canOpenWithHand,
boolean canOpenByWindCharge) {
super(block);
super(block, 0);
this.halfProperty = halfProperty;
this.facingProperty = facingProperty;
this.hingeProperty = hingeProperty;
@@ -73,9 +75,19 @@ public class DoorBlockBehavior extends BukkitBlockBehavior {
}
@Override
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) {
public Object updateShape(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
Object level;
Object blockPos;
Object blockState = args[0];
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
if (VersionHelper.isOrAbove1_21_2()) {
level = args[1];
blockPos = args[3];
} else {
level = args[3];
blockPos = args[4];
}
int stateId = BlockStateUtils.blockStateToId(blockState);
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(stateId);
if (immutableBlockState == null || immutableBlockState.isEmpty()) return blockState;
DoubleBlockHalf half = immutableBlockState.get(this.halfProperty);
Object direction = VersionHelper.isOrAbove1_21_2() ? args[4] : args[0];
@@ -93,9 +105,21 @@ public class DoorBlockBehavior extends BukkitBlockBehavior {
}
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;
if (half == DoubleBlockHalf.LOWER && direction == CoreReflections.instance$Direction$DOWN
&& !canSurvive(thisBlock, blockState, level, blockPos)) {
BlockPos pos = LocationUtils.fromBlockPos(blockPos);
net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level));
WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(pos));
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(DirectContextParameters.POSITION, position);
for (Item<Object> item : immutableBlockState.getDrops(builder, world, null)) {
world.dropItemNaturally(position, item);
}
world.playBlockSound(position, immutableBlockState.sounds().breakSound());
FastNMS.INSTANCE.method$Level$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, stateId);
return MBlocks.AIR$defaultState;
}
return blockState;
}
}
@@ -241,6 +265,22 @@ public class DoorBlockBehavior extends BukkitBlockBehavior {
}
}
@Override
public boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) throws Exception {
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state));
if (immutableBlockState == null || immutableBlockState.isEmpty()) return false;
if (immutableBlockState.get(this.halfProperty) == DoubleBlockHalf.UPPER) return true;
int x = FastNMS.INSTANCE.field$Vec3i$x(blockPos);
int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos) - 1;
int z = FastNMS.INSTANCE.field$Vec3i$z(blockPos);
Object targetPos = FastNMS.INSTANCE.constructor$BlockPos(x, y, z);
Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(world, targetPos);
return (boolean) CoreReflections.method$BlockStateBase$isFaceSturdy.invoke(
blockState, world, targetPos, CoreReflections.instance$Direction$UP,
CoreReflections.instance$SupportType$FULL
);
}
@SuppressWarnings("unchecked")
public static class Factory implements BlockBehaviorFactory {
@Override