9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 20:39:10 +00:00

修复甘蔗的掉落速度

This commit is contained in:
XiaoMoMi
2025-05-25 21:47:12 +08:00
parent 3128fe3551
commit 6326ca5808
7 changed files with 55 additions and 54 deletions

View File

@@ -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<Object> 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<Object> 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));

View File

@@ -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<Object> tagsCanSurviveOn, Set<Object> blocksCansSurviveOn, Set<String> customBlocksCansSurviveOn) {
super(block);
public BushBlockBehavior(CustomBlock block, int delay, boolean stackable, List<Object> tagsCanSurviveOn, Set<Object> blocksCansSurviveOn, Set<String> 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<String, Object> arguments) {
Tuple<List<Object>, Set<Object>, Set<String>> 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());
}
}

View File

@@ -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<Object> tagsCanSurviveOn, Set<Object> blocksCansSurviveOn, Set<String> customBlocksCansSurviveOn) {
super(block, stackable, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn);
public HangingBlockBehavior(CustomBlock block, int delay, boolean stackable, List<Object> tagsCanSurviveOn, Set<Object> blocksCansSurviveOn, Set<String> customBlocksCansSurviveOn) {
super(block, delay, stackable, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn);
}
@Override
@@ -33,7 +34,8 @@ public class HangingBlockBehavior extends BushBlockBehavior {
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
Tuple<List<Object>, Set<Object>, Set<String>> 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());
}
}
}

View File

@@ -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<String, Object> arguments) {
List<String> 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<String> 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"));
}
}
}

View File

@@ -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<String, Object> arguments) {
List<String> 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"));
}
}

View File

@@ -43,46 +43,6 @@ public class VerticalCropBlockBehavior extends BukkitBlockBehavior {
this.direction = direction;
}
@Override
public void tick(Object thisBlock, Object[] args, Callable<Object> 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<Object> 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<Object> 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<Object> superMethod) throws Exception {
Object blockState = args[0];