From 76e1e6630873dcc976b4be177ac6553f377403c8 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sun, 7 Sep 2025 08:08:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(bukkit):=20=E6=94=B9=E8=BF=9B=20LampBlockB?= =?UTF-8?q?ehavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/behavior/LampBlockBehavior.java | 76 +++++++++++++++++-- .../behavior/VerticalCropBlockBehavior.java | 2 +- .../main/resources/additional-real-blocks.yml | 3 +- .../default/configuration/blocks.yml | 15 +++- .../src/main/resources/translations/de.yml | 2 +- .../src/main/resources/translations/en.yml | 3 +- .../src/main/resources/translations/es.yml | 2 +- .../src/main/resources/translations/ru_ru.yml | 2 +- .../src/main/resources/translations/tr.yml | 2 +- .../src/main/resources/translations/zh_cn.yml | 3 +- 10 files changed, 94 insertions(+), 16 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java index 432837793..ebea5c631 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java @@ -1,6 +1,7 @@ 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.bukkit.util.LocationUtils; import net.momirealms.craftengine.core.block.BlockBehavior; @@ -8,7 +9,9 @@ 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.entity.player.InteractionResult; import net.momirealms.craftengine.core.item.context.BlockPlaceContext; +import net.momirealms.craftengine.core.item.context.UseOnContext; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import java.util.Map; @@ -19,44 +22,89 @@ import java.util.concurrent.Callable; public class LampBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Property litProperty; + private final Property poweredProperty; + private final boolean canOpenWithHand; + private final boolean redstoneToggleMode; - public LampBlockBehavior(CustomBlock block, Property litProperty) { + public LampBlockBehavior(CustomBlock block, Property litProperty, Property poweredProperty, boolean canOpenWithHand, boolean redstoneToggleMode) { super(block); this.litProperty = litProperty; + this.poweredProperty = poweredProperty; + this.canOpenWithHand = canOpenWithHand; + this.redstoneToggleMode = redstoneToggleMode; + } + + @Override + public InteractionResult useWithoutItem(UseOnContext context, ImmutableBlockState state) { + if (!this.canOpenWithHand) { + return InteractionResult.PASS; + } + LampBlockBehavior behavior = state.behavior().getAs(LampBlockBehavior.class).orElse(null); + if (behavior == null) return InteractionResult.PASS; + FastNMS.INSTANCE.method$LevelWriter$setBlock( + context.getLevel().serverWorld(), + LocationUtils.toBlockPos(context.getClickedPos()), + state.cycle(behavior.litProperty).cycle(behavior.poweredProperty).customBlockState().literalObject(), + 2 + ); + Optional.ofNullable(context.getPlayer()).ifPresent(p -> p.swingHand(context.getHand())); + return InteractionResult.SUCCESS_AND_CANCEL; } @Override public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { + if (this.canOpenWithHand || this.redstoneToggleMode) 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()))); return state; } @Override public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object blockState = args[0]; + Object world = args[1]; + if (this.canOpenWithHand || this.redstoneToggleMode || !CoreReflections.clazz$ServerLevel.isInstance(world)) return; Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); if (optionalCustomState.isEmpty()) return; - Object world = args[1]; Object blockPos = args[2]; ImmutableBlockState customState = optionalCustomState.get(); if (customState.get(this.litProperty) && !FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(world, blockPos)) { if (FastNMS.INSTANCE.method$CraftEventFactory$callRedstoneChange(world, blockPos, 0, 15).getNewCurrent() != 15) { return; } - FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().literalObject(), 2); + FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).cycle(this.poweredProperty).customBlockState().literalObject(), 2); + } + } + + @Override + public void onPlace(Object thisBlock, Object[] args, Callable 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 optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state); + if (optionalCustomState.isEmpty()) return; + checkAndFlip(optionalCustomState.get(), level, pos); } } @Override public void neighborChanged(Object thisBlock, Object[] args, Callable superMethod) { Object blockState = args[0]; + Object world = args[1]; + if (this.canOpenWithHand || !CoreReflections.clazz$ServerLevel.isInstance(world)) return; Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); if (optionalCustomState.isEmpty()) return; - Object world = args[1]; 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); @@ -64,17 +112,33 @@ public class LampBlockBehavior extends BukkitBlockBehavior { if (FastNMS.INSTANCE.method$CraftEventFactory$callRedstoneChange(world, blockPos, 0, 15).getNewCurrent() != 15) { return; } - FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().literalObject(), 2); + FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).cycle(this.poweredProperty).customBlockState().literalObject(), 2); } } } + 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 arguments) { Property lit = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("lit"), "warning.config.block.behavior.lamp.missing_lit"); - return new LampBlockBehavior(block, lit); + Property powered = (Property) 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); } } } 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 8e416ac4f..c42f10337 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 @@ -83,7 +83,7 @@ public class VerticalCropBlockBehavior extends BukkitBlockBehavior { @SuppressWarnings("unchecked") @Override public BlockBehavior create(CustomBlock block, Map arguments) { - Property ageProperty = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("age"), "warning.config.block.behavior.sugar_cane.missing_age"); + Property ageProperty = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("age"), "warning.config.block.behavior.vertical_crop.missing_age"); int maxHeight = ResourceConfigUtils.getAsInt(arguments.getOrDefault("max-height", 3), "max-height"); boolean direction = arguments.getOrDefault("direction", "up").toString().equalsIgnoreCase("up"); return new VerticalCropBlockBehavior(block, ageProperty, maxHeight, diff --git a/common-files/src/main/resources/additional-real-blocks.yml b/common-files/src/main/resources/additional-real-blocks.yml index 58279f8a7..3f92d92f0 100644 --- a/common-files/src/main/resources/additional-real-blocks.yml +++ b/common-files/src/main/resources/additional-real-blocks.yml @@ -80,4 +80,5 @@ minecraft:mangrove_fence_gate: 16 minecraft:cherry_fence_gate: 16 minecraft:bamboo_fence_gate: 16 minecraft:crimson_fence_gate: 16 -minecraft:warped_fence_gate: 16 \ No newline at end of file +minecraft:warped_fence_gate: 16 +minecraft:cactus: 15 \ No newline at end of file diff --git a/common-files/src/main/resources/resources/default/configuration/blocks.yml b/common-files/src/main/resources/resources/default/configuration/blocks.yml index 573ed098d..5495ed843 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks.yml @@ -221,6 +221,9 @@ items#misc: lit: type: boolean default: false + powered: + type: boolean + default: false appearances: off: state: cactus:0 @@ -245,14 +248,22 @@ items#misc: top: minecraft:block/custom/copper_coil_on side: minecraft:block/custom/copper_coil_on_side variants: - lit=false: + lit=false,powered=false: appearance: 'off' id: 0 - lit=true: + lit=true,powered=false: 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 diff --git a/common-files/src/main/resources/translations/de.yml b/common-files/src/main/resources/translations/de.yml index 3e3ffe8b1..f22dc1863 100644 --- a/common-files/src/main/resources/translations/de.yml +++ b/common-files/src/main/resources/translations/de.yml @@ -273,7 +273,7 @@ warning.config.block.behavior.missing_type: "Problem in Datei ge warning.config.block.behavior.invalid_type: "Problem in Datei gefunden - Der Block '' verwendet einen ungültigen Block-Behavior-Typ ''." warning.config.block.behavior.concrete.missing_solid: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'solid-block'-Option für das 'concrete_block'-Behavior." warning.config.block.behavior.crop.missing_age: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'age'-Property für das 'crop_block'-Behavior." -warning.config.block.behavior.sugar_cane.missing_age: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'age'-Property für das 'sugar_cane_block'-Behavior." +warning.config.block.behavior.vertical_crop.missing_age: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'age'-Property für das 'vertical_crop_block'-Behavior." warning.config.block.behavior.leaves.missing_persistent: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'persistent'-Property für das 'leaves_block'-Behavior." warning.config.block.behavior.leaves.missing_distance: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'distance'-Property für das 'leaves_block'-Behavior." warning.config.block.behavior.lamp.missing_lit: "Problem in Datei gefunden - Beim Block '' fehlt die erforderliche 'lit'-Property für das 'lamp_block'-Behavior." diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index efd506c7d..5dbb40cfc 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -277,10 +277,11 @@ warning.config.block.behavior.missing_type: "Issue found in file warning.config.block.behavior.invalid_type: "Issue found in file - The block '' is using an invalid block behavior type ''." warning.config.block.behavior.concrete.missing_solid: "Issue found in file - The block '' is missing the required 'solid-block' option for 'concrete_block' behavior." warning.config.block.behavior.crop.missing_age: "Issue found in file - The block '' is missing the required 'age' property for 'crop_block' behavior." -warning.config.block.behavior.sugar_cane.missing_age: "Issue found in file - The block '' is missing the required 'age' property for 'sugar_cane_block' behavior." +warning.config.block.behavior.vertical_crop.missing_age: "Issue found in file - The block '' is missing the required 'age' property for 'vertical_crop_block' behavior." warning.config.block.behavior.leaves.missing_persistent: "Issue found in file - The block '' is missing the required 'persistent' property for 'leaves_block' behavior." warning.config.block.behavior.leaves.missing_distance: "Issue found in file - The block '' is missing the required 'distance' property for 'leaves_block' behavior." warning.config.block.behavior.lamp.missing_lit: "Issue found in file - The block '' is missing the required 'lit' property for 'lamp_block' behavior." +warning.config.block.behavior.lamp.missing_powered: "Issue found in file - The block '' is missing the required 'powered' property for 'lamp_block' behavior." warning.config.block.behavior.sapling.missing_stage: "Issue found in file - The block '' is missing the required 'stage' property for 'sapling_block' behavior." warning.config.block.behavior.sapling.missing_feature: "Issue found in file - The block '' is missing the required 'feature' argument for 'sapling_block' behavior." warning.config.block.behavior.strippable.missing_stripped: "Issue found in file - The block '' is missing the required 'stripped' argument for 'strippable_block' behavior." diff --git a/common-files/src/main/resources/translations/es.yml b/common-files/src/main/resources/translations/es.yml index b26e3f80d..77b0cc709 100644 --- a/common-files/src/main/resources/translations/es.yml +++ b/common-files/src/main/resources/translations/es.yml @@ -195,7 +195,7 @@ warning.config.block.behavior.missing_type: "Problema encontrado en el a warning.config.block.behavior.invalid_type: "Problema encontrado en el archivo - El bloque '' está usando un tipo de comportamiento de bloque inválido ''." warning.config.block.behavior.concrete.missing_solid: "Problema encontrado en el archivo - El bloque '' carece de la opción requerida 'solid-block' para el comportamiento 'concrete_block'." warning.config.block.behavior.crop.missing_age: "Problema encontrado en el archivo - El bloque '' carece de la propiedad requerida 'age' para el comportamiento 'crop_block'." -warning.config.block.behavior.sugar_cane.missing_age: "Problema encontrado en el archivo - El bloque '' carece de la propiedad requerida 'age' para el comportamiento 'sugar_cane_block'." +warning.config.block.behavior.vertical_crop.missing_age: "Problema encontrado en el archivo - El bloque '' carece de la propiedad requerida 'age' para el comportamiento 'vertical_crop_block'." warning.config.block.behavior.leaves.missing_persistent: "Problema encontrado en el archivo - El bloque '' carece de la propiedad requerida 'persistent' para el comportamiento 'leaves_block'." warning.config.block.behavior.leaves.missing_distance: "Problema encontrado en el archivo - El bloque '' carece de la propiedad requerida 'distance' para el comportamiento 'leaves_block'." warning.config.block.behavior.sapling.missing_stage: "Problema encontrado en el archivo - El bloque '' carece de la propiedad requerida 'stage' para el comportamiento 'sapling_block'." diff --git a/common-files/src/main/resources/translations/ru_ru.yml b/common-files/src/main/resources/translations/ru_ru.yml index 60036cb99..209c6cf28 100644 --- a/common-files/src/main/resources/translations/ru_ru.yml +++ b/common-files/src/main/resources/translations/ru_ru.yml @@ -245,7 +245,7 @@ warning.config.block.behavior.missing_type: "Проблема найде warning.config.block.behavior.invalid_type: "Проблема найдена в файле - Блок '' имеет недействительный блочный behavior тип ''." warning.config.block.behavior.concrete.missing_solid: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'solid-block' вариант для 'concrete_block' behavior." warning.config.block.behavior.crop.missing_age: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'age' свойство для 'crop_block' behavior." -warning.config.block.behavior.sugar_cane.missing_age: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'age' свойство для 'sugar_cane_block' behavior." +warning.config.block.behavior.vertical_crop.missing_age: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'age' свойство для 'vertical_crop_block' behavior." warning.config.block.behavior.leaves.missing_persistent: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'persistent' свойство для 'leaves_block' behavior." warning.config.block.behavior.leaves.missing_distance: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'distance' свойство для 'leaves_block' behavior." warning.config.block.behavior.lamp.missing_lit: "Проблема найдена в файле - В блоке '' отсутствует необходимый 'lit' свойство для 'lamp_block' behavior." diff --git a/common-files/src/main/resources/translations/tr.yml b/common-files/src/main/resources/translations/tr.yml index 0704fb7f2..d1cff3a7c 100644 --- a/common-files/src/main/resources/translations/tr.yml +++ b/common-files/src/main/resources/translations/tr.yml @@ -193,7 +193,7 @@ warning.config.block.behavior.missing_type: " dosyasında sorun b warning.config.block.behavior.invalid_type: " dosyasında sorun bulundu - '' bloğu geçersiz bir blok davranış türü '' kullanıyor." warning.config.block.behavior.concrete.missing_solid: " dosyasında sorun bulundu - '' bloğu, 'concrete_block' davranışı için gerekli 'solid-block' seçeneği eksik." warning.config.block.behavior.crop.missing_age: " dosyasında sorun bulundu - '' bloğu, 'crop_block' davranışı için gerekli 'age' özelliği eksik." -warning.config.block.behavior.sugar_cane.missing_age: " dosyasında sorun bulundu - '' bloğu, 'sugar_cane_block' davranışı için gerekli 'age' özelliği eksik." +warning.config.block.behavior.vertical_crop.missing_age: " dosyasında sorun bulundu - '' bloğu, 'vertical_crop_block' davranışı için gerekli 'age' özelliği eksik." warning.config.block.behavior.leaves.missing_persistent: " dosyasında sorun bulundu - '' bloğu, 'leaves_block' davranışı için gerekli 'persistent' özelliği eksik." warning.config.block.behavior.leaves.missing_distance: " dosyasında sorun bulundu - '' bloğu, 'leaves_block' davranışı için gerekli 'distance' özelliği eksik." warning.config.block.behavior.sapling.missing_stage: " dosyasında sorun bulundu - '' bloğu, 'sapling_block' davranışı için gerekli 'stage' özelliği eksik." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 239100483..df83c94fe 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -277,10 +277,11 @@ warning.config.block.behavior.missing_type: "在文件 发现问 warning.config.block.behavior.invalid_type: "在文件 发现问题 - 方块 '' 使用了无效的行为类型 ''" warning.config.block.behavior.concrete.missing_solid: "在文件 发现问题 - 方块 '' 的 'concrete_block' 行为缺少必需的 'solid-block' 选项" warning.config.block.behavior.crop.missing_age: "在文件 发现问题 - 方块 '' 的 'crop_block' 行为缺少必需的 'age' 属性" -warning.config.block.behavior.sugar_cane.missing_age: "在文件 发现问题 - 方块 '' 的 'sugar_cane_block' 行为缺少必需的 'age' 属性" +warning.config.block.behavior.vertical_crop.missing_age: "在文件 发现问题 - 方块 '' 的 'vertical_crop_block' 行为缺少必需的 'age' 属性" warning.config.block.behavior.leaves.missing_persistent: "在文件 发现问题 - 方块 '' 的 'leaves_block' 行为缺少必需的 'persistent' 属性" warning.config.block.behavior.leaves.missing_distance: "在文件 发现问题 - 方块 '' 的 'leaves_block' 行为缺少必需的 'distance' 属性" warning.config.block.behavior.lamp.missing_lit: "在文件 发现问题 - 方块 '' 的 'lamp_block' 行为缺少必需的 'lit' 属性" +warning.config.block.behavior.lamp.missing_powered: "在文件 发现问题 - 方块 '' 的 'lamp_block' 行为缺少必需的 'powered' 属性" warning.config.block.behavior.sapling.missing_stage: "在文件 发现问题 - 方块 '' 的 'sapling_block' 行为缺少必需的 'stage' 属性" warning.config.block.behavior.sapling.missing_feature: "在文件 发现问题 - 方块 '' 的 'sapling_block' 行为缺少必需的 'feature' 参数" warning.config.block.behavior.strippable.missing_stripped: "在文件 发现问题 - 方块 '' 的 'strippable_block' 行为缺少必需的 'stripped' 参数"