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

feat(bukkit): 剥离 redstone-toggle-mode 成 ToggleableLampBlockBehavior

This commit is contained in:
jhqwqmc
2025-09-07 08:39:29 +08:00
parent 76e1e66308
commit d51404e8df
6 changed files with 87 additions and 53 deletions

View File

@@ -29,6 +29,7 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
public static final Key DOUBLE_HIGH_BLOCK = Key.from("craftengine:double_high_block");
public static final Key CHANGE_OVER_TIME_BLOCK = Key.from("craftengine:change_over_time_block");
public static final Key SIMPLE_STORAGE_BLOCK = Key.from("craftengine:simple_storage_block");
public static final Key TOGGLEABLE_LAMP_BLOCK = Key.from("craftengine:toggleable_lamp_block");
public static void init() {
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
@@ -56,5 +57,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
register(DOUBLE_HIGH_BLOCK, DoubleHighBlockBehavior.FACTORY);
register(CHANGE_OVER_TIME_BLOCK, ChangeOverTimeBlockBehavior.FACTORY);
register(SIMPLE_STORAGE_BLOCK, SimpleStorageBlockBehavior.FACTORY);
register(TOGGLEABLE_LAMP_BLOCK, ToggleableLampBlockBehavior.FACTORY);
}
}

View File

@@ -24,14 +24,12 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
private final Property<Boolean> litProperty;
private final Property<Boolean> poweredProperty;
private final boolean canOpenWithHand;
private final boolean redstoneToggleMode;
public LampBlockBehavior(CustomBlock block, Property<Boolean> litProperty, Property<Boolean> poweredProperty, boolean canOpenWithHand, boolean redstoneToggleMode) {
public LampBlockBehavior(CustomBlock block, Property<Boolean> litProperty, Property<Boolean> poweredProperty, boolean canOpenWithHand) {
super(block);
this.litProperty = litProperty;
this.poweredProperty = poweredProperty;
this.canOpenWithHand = canOpenWithHand;
this.redstoneToggleMode = redstoneToggleMode;
}
@Override
@@ -53,7 +51,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
@Override
public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) {
if (this.canOpenWithHand || this.redstoneToggleMode) return state;
if (this.canOpenWithHand) return state;
Object level = context.getLevel().serverWorld();
state = state.with(this.litProperty, FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, LocationUtils.toBlockPos(context.getClickedPos())));
state = state.with(this.poweredProperty, FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, LocationUtils.toBlockPos(context.getClickedPos())));
@@ -64,7 +62,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
public void tick(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
Object blockState = args[0];
Object world = args[1];
if (this.canOpenWithHand || this.redstoneToggleMode || !CoreReflections.clazz$ServerLevel.isInstance(world)) return;
if (this.canOpenWithHand || !CoreReflections.clazz$ServerLevel.isInstance(world)) return;
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState);
if (optionalCustomState.isEmpty()) return;
Object blockPos = args[2];
@@ -77,20 +75,6 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
}
}
@Override
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) {
if (this.canOpenWithHand || !this.redstoneToggleMode) return;
Object state = args[0];
Object level = args[1];
Object pos = args[2];
Object oldState = args[3];
if (FastNMS.INSTANCE.method$BlockState$getBlock(oldState) != FastNMS.INSTANCE.method$BlockState$getBlock(state) && CoreReflections.clazz$ServerLevel.isInstance(level)) {
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state);
if (optionalCustomState.isEmpty()) return;
checkAndFlip(optionalCustomState.get(), level, pos);
}
}
@Override
public void neighborChanged(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object blockState = args[0];
@@ -101,10 +85,6 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
Object blockPos = args[2];
ImmutableBlockState customState = optionalCustomState.get();
boolean lit = customState.get(this.litProperty);
if (this.redstoneToggleMode) {
checkAndFlip(customState, world, blockPos);
return;
}
if (lit != FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(world, blockPos)) {
if (lit) {
FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(world, blockPos, thisBlock, 4);
@@ -117,19 +97,6 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
}
}
private void checkAndFlip(ImmutableBlockState customState, Object level, Object pos) {
boolean hasNeighborSignal = FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, pos);
boolean isPowered = customState.get(this.poweredProperty);
if (hasNeighborSignal != isPowered) {
ImmutableBlockState blockState = customState;
if (!isPowered) {
blockState = blockState.cycle(this.litProperty);
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState.with(this.poweredProperty, hasNeighborSignal).customBlockState().literalObject(), 3);
}
}
@SuppressWarnings("unchecked")
public static class Factory implements BlockBehaviorFactory {
@Override
@@ -137,8 +104,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
Property<Boolean> lit = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("lit"), "warning.config.block.behavior.lamp.missing_lit");
Property<Boolean> powered = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("powered"), "warning.config.block.behavior.lamp.missing_powered");
boolean canOpenWithHand = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("can-open-with-hand", false), "can-open-with-hand");
boolean redstoneToggleMode = !canOpenWithHand && ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("redstone-toggle-mode", false), "redstone-toggle-mode");
return new LampBlockBehavior(block, lit, powered, canOpenWithHand, redstoneToggleMode);
return new LampBlockBehavior(block, lit, powered, canOpenWithHand);
}
}
}

View File

@@ -0,0 +1,75 @@
package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
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.behavior.BlockBehaviorFactory;
import net.momirealms.craftengine.core.block.properties.Property;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
public class ToggleableLampBlockBehavior extends BukkitBlockBehavior {
public static final Factory FACTORY = new Factory();
private final Property<Boolean> litProperty;
private final Property<Boolean> poweredProperty;
public ToggleableLampBlockBehavior(CustomBlock block, Property<Boolean> litProperty, Property<Boolean> poweredProperty) {
super(block);
this.litProperty = litProperty;
this.poweredProperty = poweredProperty;
}
@Override
public void onPlace(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object state = args[0];
Object level = args[1];
Object pos = args[2];
Object oldState = args[3];
if (FastNMS.INSTANCE.method$BlockState$getBlock(oldState) != FastNMS.INSTANCE.method$BlockState$getBlock(state) && CoreReflections.clazz$ServerLevel.isInstance(level)) {
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state);
if (optionalCustomState.isEmpty()) return;
checkAndFlip(optionalCustomState.get(), level, pos);
}
}
@Override
public void neighborChanged(Object thisBlock, Object[] args, Callable<Object> superMethod) {
Object blockState = args[0];
Object world = args[1];
if (!CoreReflections.clazz$ServerLevel.isInstance(world)) return;
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState);
if (optionalCustomState.isEmpty()) return;
Object blockPos = args[2];
ImmutableBlockState customState = optionalCustomState.get();
checkAndFlip(customState, world, blockPos);
}
private void checkAndFlip(ImmutableBlockState customState, Object level, Object pos) {
boolean hasNeighborSignal = FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, pos);
boolean isPowered = customState.get(this.poweredProperty);
if (hasNeighborSignal != isPowered) {
ImmutableBlockState blockState = customState;
if (!isPowered) {
blockState = blockState.cycle(this.litProperty);
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, blockState.with(this.poweredProperty, hasNeighborSignal).customBlockState().literalObject(), 3);
}
}
@SuppressWarnings("unchecked")
public static class Factory implements BlockBehaviorFactory {
@Override
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
Property<Boolean> lit = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("lit"), "warning.config.block.behavior.toggleable_lamp.missing_lit");
Property<Boolean> powered = (Property<Boolean>) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("powered"), "warning.config.block.behavior.toggleable_lamp.missing_powered");
return new ToggleableLampBlockBehavior(block, lit, powered);
}
}
}

View File

@@ -221,9 +221,6 @@ items#misc:
lit:
type: boolean
default: false
powered:
type: boolean
default: false
appearances:
off:
state: cactus:0
@@ -248,22 +245,14 @@ items#misc:
top: minecraft:block/custom/copper_coil_on
side: minecraft:block/custom/copper_coil_on_side
variants:
lit=false,powered=false:
lit=false:
appearance: 'off'
id: 0
lit=true,powered=false:
lit=true:
appearance: 'on'
id: 1
settings:
luminance: 8
lit=false,powered=true:
appearance: 'off'
id: 2
lit=true,powered=true:
appearance: 'on'
id: 3
settings:
luminance: 8
default:pebble:
material: nether_brick
custom-model-data: 3005

View File

@@ -281,7 +281,8 @@ warning.config.block.behavior.vertical_crop.missing_age: "<yellow>Issue found in
warning.config.block.behavior.leaves.missing_persistent: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'persistent' property for 'leaves_block' behavior.</yellow>"
warning.config.block.behavior.leaves.missing_distance: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'distance' property for 'leaves_block' behavior.</yellow>"
warning.config.block.behavior.lamp.missing_lit: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'lit' property for 'lamp_block' behavior.</yellow>"
warning.config.block.behavior.lamp.missing_powered: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'powered' property for 'lamp_block' behavior.</yellow>"
warning.config.block.behavior.toggleable_lamp.missing_lit: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'lit' property for 'toggleable_lamp_block' behavior.</yellow>"
warning.config.block.behavior.toggleable_lamp.missing_powered: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'powered' property for 'toggleable_lamp_block' behavior.</yellow>"
warning.config.block.behavior.sapling.missing_stage: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'stage' property for 'sapling_block' behavior.</yellow>"
warning.config.block.behavior.sapling.missing_feature: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'feature' argument for 'sapling_block' behavior.</yellow>"
warning.config.block.behavior.strippable.missing_stripped: "<yellow>Issue found in file <arg:0> - The block '<arg:1>' is missing the required 'stripped' argument for 'strippable_block' behavior.</yellow>"

View File

@@ -281,7 +281,8 @@ warning.config.block.behavior.vertical_crop.missing_age: "<yellow>在文件 <arg
warning.config.block.behavior.leaves.missing_persistent: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'leaves_block' 行为缺少必需的 'persistent' 属性</yellow>"
warning.config.block.behavior.leaves.missing_distance: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'leaves_block' 行为缺少必需的 'distance' 属性</yellow>"
warning.config.block.behavior.lamp.missing_lit: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'lamp_block' 行为缺少必需的 'lit' 属性</yellow>"
warning.config.block.behavior.lamp.missing_powered: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'lamp_block' 行为缺少必需的 'powered' 属性</yellow>"
warning.config.block.behavior.toggleable_lamp.missing_lit: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'toggleable_lamp_block' 行为缺少必需的 'lit' 属性</yellow>"
warning.config.block.behavior.toggleable_lamp.missing_powered: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'toggleable_lamp_block' 行为缺少必需的 'powered' 属性</yellow>"
warning.config.block.behavior.sapling.missing_stage: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'sapling_block' 行为缺少必需的 'stage' 属性</yellow>"
warning.config.block.behavior.sapling.missing_feature: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'sapling_block' 行为缺少必需的 'feature' 参数</yellow>"
warning.config.block.behavior.strippable.missing_stripped: "<yellow>在文件 <arg:0> 发现问题 - 方块 '<arg:1>' 的 'strippable_block' 行为缺少必需的 'stripped' 参数</yellow>"