9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 04:19:27 +00:00

refactor(block): 重构 ChangeOverTimeBlockBehavior 类

This commit is contained in:
jhqwqmc
2025-08-11 09:40:46 +08:00
parent 4e23f53784
commit 644a9a6466
3 changed files with 25 additions and 48 deletions

View File

@@ -1,71 +1,46 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.core.block.*;
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.RandomUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import org.bukkit.GameEvent;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.util.Vector;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
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.util.Key;
import net.momirealms.craftengine.core.util.RandomUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.sparrow.nbt.CompoundTag;
public class ChangeOverTimeBlockBehavior extends BukkitBlockBehavior {
public static final Factory FACTORY = new Factory();
private final float delay;
private final float changeSpeed;
private final Key nextBlock;
public ChangeOverTimeBlockBehavior(CustomBlock customBlock, float delay, Key nextBlock) {
public ChangeOverTimeBlockBehavior(CustomBlock customBlock, float changeSpeed, Key nextBlock) {
super(customBlock);
this.delay = delay;
this.changeSpeed = changeSpeed;
this.nextBlock = nextBlock;
}
@Override
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
if(!shouldChange(args)) return;
Optional<CustomBlock> optionalNewCustomBlock = BukkitBlockManager.instance().blockById(nextBlock);
if (!optionalNewCustomBlock.isPresent()) return;
Object blockState = args[0];
World level = (World) args[1];
BlockPos blockPos = (BlockPos) args[2];
Optional<ImmutableBlockState> optionalCurrentState = BlockStateUtils .getOptionalCustomBlockState(blockState);
if (optionalCurrentState.isEmpty()) return;
CompoundTag compoundTag = optionalCurrentState.get().propertiesNbt();
ImmutableBlockState newState = optionalNewCustomBlock.get().getBlockState(compoundTag);
BukkitBlockInWorld blockInWorld = (BukkitBlockInWorld) level.getBlockAt(LocationUtils.fromBlockPos(blockPos));
BlockFormEvent event = new BlockFormEvent(blockInWorld.block(),BlockStateUtils.fromBlockData(newState.customBlockState().handle()).createBlockState());
if (event.callEvent()) {
FastNMS.INSTANCE.method$LevelWriter$setBlock(level.serverWorld(), blockPos, newState.customBlockState().handle(), UpdateOption.UPDATE_ALL_IMMEDIATE.flags());
blockInWorld.block().getWorld().sendGameEvent(null, GameEvent.BLOCK_CHANGE, new Vector(blockPos.x(), blockPos.y(), blockPos.z()));
}
}
private boolean shouldChange(Object[] args) {
return RandomUtils.generateRandomFloat(0F, 1F) < this.delay;
public void randomTick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws ReflectiveOperationException {
if (RandomUtils.generateRandomFloat(0F, 1F) >= this.changeSpeed) return;
Optional<Object> nextState = BukkitBlockManager.instance().blockById(this.nextBlock)
.map(CustomBlock::defaultState)
.map(ImmutableBlockState::customBlockState)
.map(BlockStateWrapper::handle);
if (nextState.isEmpty()) return;
CraftBukkitReflections.method$CraftEventFactory$handleBlockFormEvent.invoke(null, args[1], args[2], nextState.get(), UpdateOption.UPDATE_ALL.flags());
}
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
float delay = Float.valueOf(arguments.getOrDefault("delay", 0.05688889F).toString());
Key nextBlock = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.getOrDefault("next-block", "minecraft:air"), "warning.config.block.behavior.change_over_time_block_missing_next_block"));
return new ChangeOverTimeBlockBehavior(block, delay, nextBlock);
float changeSpeed = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("change-speed", 0.05688889F), "change-speed");
Key nextBlock = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.getOrDefault("next-block", "minecraft:air"), "warning.config.block.behavior.change_over_time_block.missing_next_block"));
return new ChangeOverTimeBlockBehavior(block, changeSpeed, nextBlock);
}
}
}