From 6326ca5808c55084903e258ac5c807059b359e93 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sun, 25 May 2025 21:47:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=98=E8=94=97=E7=9A=84?= =?UTF-8?q?=E6=8E=89=E8=90=BD=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../default/configuration/plants.yml | 2 + .../AbstractCanSurviveBlockBehavior.java | 33 ++++++++++++++- .../block/behavior/BushBlockBehavior.java | 8 ++-- .../block/behavior/HangingBlockBehavior.java | 8 ++-- .../behavior/NearLiquidBlockBehavior.java | 10 +++-- .../block/behavior/OnLiquidBlockBehavior.java | 8 ++-- .../behavior/VerticalCropBlockBehavior.java | 40 ------------------- 7 files changed, 55 insertions(+), 54 deletions(-) diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml b/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml index 7c7f05927..09e8cce5f 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml @@ -130,6 +130,7 @@ blocks: direction: up - type: bush_block stackable: true + delay: 1 bottom-blocks: - minecraft:netherrack - minecraft:soul_sand @@ -140,6 +141,7 @@ blocks: - minecraft:basalt - type: near_liquid_block liquid-type: lava + delay: 1 stackable: true positions: - -1,-1,0 diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java index 16e915a1b..627a1d15b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java @@ -20,9 +20,36 @@ import net.momirealms.craftengine.core.world.WorldPosition; import java.util.concurrent.Callable; public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavior { + protected final int delay; - protected AbstractCanSurviveBlockBehavior(CustomBlock customBlock) { + protected AbstractCanSurviveBlockBehavior(CustomBlock customBlock, int delay) { super(customBlock); + this.delay = delay; + } + + @Override + public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + if (this.delay == 0) return; + Object blockState = args[0]; + Object level = args[1]; + Object blockPos = args[2]; + if (!canSurvive(thisBlock, args, () -> true)) { + int stateId = BlockStateUtils.blockStateToId(blockState); + ImmutableBlockState currentState = BukkitBlockManager.instance().getImmutableBlockState(stateId); + if (currentState != null && !currentState.isEmpty() && currentState.owner().value() == this.customBlock) { + // break the crop + FastNMS.INSTANCE.method$Level$removeBlock(level, blockPos, false); + net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); + WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(LocationUtils.fromBlockPos(blockPos))); + ContextHolder.Builder builder = ContextHolder.builder() + .withParameter(DirectContextParameters.POSITION, position); + for (Item item : currentState.getDrops(builder, world, null)) { + world.dropItemNaturally(position, item); + } + world.playBlockSound(position, currentState.sounds().breakSound()); + FastNMS.INSTANCE.method$Level$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, stateId); + } + } } @Override @@ -57,6 +84,10 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio if (previousState == null || previousState.isEmpty()) { return state; } + if (this.delay != 0) { + Reflections.method$LevelAccessor$scheduleTick.invoke(level, blockPos, thisBlock, this.delay); + return state; + } if (!canSurvive(thisBlock, new Object[] {state, level, blockPos}, () -> true)) { BlockPos pos = LocationUtils.fromBlockPos(blockPos); net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java index 11cf0c44b..819173ed1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java @@ -10,6 +10,7 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; 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.util.Tuple; import net.momirealms.craftengine.shared.block.BlockBehavior; import org.bukkit.Bukkit; @@ -27,8 +28,8 @@ public class BushBlockBehavior extends AbstractCanSurviveBlockBehavior { protected final boolean any; protected final boolean stackable; - public BushBlockBehavior(CustomBlock block, boolean stackable, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { - super(block); + public BushBlockBehavior(CustomBlock block, int delay, boolean stackable, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { + super(block, delay); this.stackable = stackable; this.tagsCanSurviveOn = tagsCanSurviveOn; this.blocksCansSurviveOn = blocksCansSurviveOn; @@ -42,7 +43,8 @@ public class BushBlockBehavior extends AbstractCanSurviveBlockBehavior { public BlockBehavior create(CustomBlock block, Map arguments) { Tuple, Set, Set> tuple = readTagsAndState(arguments, false); boolean stackable = (boolean) arguments.getOrDefault("stackable", false); - return new BushBlockBehavior(block, stackable, tuple.left(), tuple.mid(), tuple.right()); + int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay"); + return new BushBlockBehavior(block, delay, stackable, tuple.left(), tuple.mid(), tuple.right()); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java index a11b68890..3e061a22f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.util.Tuple; import net.momirealms.craftengine.shared.block.BlockBehavior; @@ -13,8 +14,8 @@ import java.util.Set; public class HangingBlockBehavior extends BushBlockBehavior { public static final Factory FACTORY = new Factory(); - public HangingBlockBehavior(CustomBlock block, boolean stackable, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { - super(block, stackable, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); + public HangingBlockBehavior(CustomBlock block, int delay, boolean stackable, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { + super(block, delay, stackable, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); } @Override @@ -33,7 +34,8 @@ public class HangingBlockBehavior extends BushBlockBehavior { public BlockBehavior create(CustomBlock block, Map arguments) { Tuple, Set, Set> tuple = readTagsAndState(arguments, true); boolean stackable = (boolean) arguments.getOrDefault("stackable", false); - return new HangingBlockBehavior(block, stackable, tuple.left(), tuple.mid(), tuple.right()); + int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay"); + return new HangingBlockBehavior(block, delay, stackable, tuple.left(), tuple.mid(), tuple.right()); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java index fd40a6b95..e9e740470 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java @@ -9,6 +9,7 @@ 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.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.shared.block.BlockBehavior; @@ -24,8 +25,8 @@ public class NearLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { private final boolean stackable; private final BlockPos[] positions; - public NearLiquidBlockBehavior(CustomBlock block, BlockPos[] positions, boolean stackable, boolean onWater, boolean onLava) { - super(block); + public NearLiquidBlockBehavior(CustomBlock block, int delay, BlockPos[] positions, boolean stackable, boolean onWater, boolean onLava) { + super(block, delay); this.onWater = onWater; this.onLava = onLava; this.stackable = stackable; @@ -45,16 +46,17 @@ public class NearLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { public BlockBehavior create(CustomBlock block, Map arguments) { List liquidTypes = MiscUtils.getAsStringList(arguments.getOrDefault("liquid-type", List.of("water"))); boolean stackable = (boolean) arguments.getOrDefault("stackable", false); + int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay"); List positionsToCheck = MiscUtils.getAsStringList(arguments.getOrDefault("positions", List.of())); if (positionsToCheck.isEmpty()) { - return new NearLiquidBlockBehavior(block, new BlockPos[]{new BlockPos(0,-1,0)}, stackable, liquidTypes.contains("water"), liquidTypes.contains("lava")); + return new NearLiquidBlockBehavior(block, delay, new BlockPos[]{new BlockPos(0,-1,0)}, stackable, liquidTypes.contains("water"), liquidTypes.contains("lava")); } else { BlockPos[] pos = new BlockPos[positionsToCheck.size()]; for (int i = 0; i < pos.length; i++) { String[] split = positionsToCheck.get(i).split(","); pos[i] = new BlockPos(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])); } - return new NearLiquidBlockBehavior(block, pos, stackable, liquidTypes.contains("water"), liquidTypes.contains("lava")); + return new NearLiquidBlockBehavior(block, delay, pos, stackable, liquidTypes.contains("water"), liquidTypes.contains("lava")); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java index cb73eeaab..541b1d40e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java @@ -9,6 +9,7 @@ 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.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.shared.block.BlockBehavior; import java.util.List; @@ -20,8 +21,8 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { private final boolean onLava; private final boolean stackable; - public OnLiquidBlockBehavior(CustomBlock block, boolean stackable, boolean onWater, boolean onLava) { - super(block); + public OnLiquidBlockBehavior(CustomBlock block, int delay, boolean stackable, boolean onWater, boolean onLava) { + super(block, delay); this.onWater = onWater; this.onLava = onLava; this.stackable = stackable; @@ -40,7 +41,8 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { public BlockBehavior create(CustomBlock block, Map arguments) { List liquidTypes = MiscUtils.getAsStringList(arguments.getOrDefault("liquid-type", List.of("water"))); boolean stackable = (boolean) arguments.getOrDefault("stackable", false); - return new OnLiquidBlockBehavior(block, stackable, liquidTypes.contains("water"), liquidTypes.contains("lava")); + int delay = ResourceConfigUtils.getAsInt(arguments.getOrDefault("delay", 0), "delay"); + return new OnLiquidBlockBehavior(block, delay, stackable, liquidTypes.contains("water"), liquidTypes.contains("lava")); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/VerticalCropBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/VerticalCropBlockBehavior.java index 039010453..cc180490c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/VerticalCropBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/VerticalCropBlockBehavior.java @@ -43,46 +43,6 @@ public class VerticalCropBlockBehavior extends BukkitBlockBehavior { this.direction = direction; } - @Override - public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { - Object blockState = args[0]; - Object level = args[1]; - Object blockPos = args[2]; - if (!canSurvive(thisBlock, args, () -> true)) { - int stateId = BlockStateUtils.blockStateToId(blockState); - ImmutableBlockState currentState = BukkitBlockManager.instance().getImmutableBlockState(stateId); - if (currentState != null && !currentState.isEmpty()) { - // break the crop - FastNMS.INSTANCE.method$Level$removeBlock(level, blockPos, false); - net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(LocationUtils.fromBlockPos(blockPos))); - ContextHolder.Builder builder = ContextHolder.builder() - .withParameter(DirectContextParameters.POSITION, position); - for (Item item : currentState.getDrops(builder, world, null)) { - world.dropItemNaturally(position, item); - } - world.playBlockSound(position, currentState.sounds().breakSound()); - FastNMS.INSTANCE.method$Level$levelEvent(level, WorldEvents.BLOCK_BREAK_EFFECT, blockPos, stateId); - } - } - } - - @Override - public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { - Object world; - Object blockPos; - if (VersionHelper.isOrAbove1_21_2()) { - world = args[1]; - blockPos = args[3]; - } else { - world = args[3]; - blockPos = args[4]; - } - Reflections.method$LevelAccessor$scheduleTick.invoke(world, blockPos, thisBlock, 1); - // return state, do not call super. - return args[0]; - } - @Override public void randomTick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object blockState = args[0];