From d0d8d0650fbdf11bf0bc8256027a9fe26b35eb14 Mon Sep 17 00:00:00 2001 From: Caadiq Date: Mon, 29 Dec 2025 14:47:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20/=EC=A0=9C=EC=9E=91=EB=8C=80,=20/workbe?= =?UTF-8?q?nch=20=EB=AA=85=EB=A0=B9=EC=96=B4=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=EB=8C=80=20=EB=B8=94=EB=A1=9D=20=EC=97=86?= =?UTF-8?q?=EC=9D=B4=20=EC=A0=9C=EC=9E=91=EB=8C=80=20GUI=20=EC=97=B4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beemer/essentials/Essentials.kt | 1 + .../beemer/essentials/command/HelpCommand.kt | 5 ++ .../essentials/command/WorkbenchCommand.kt | 66 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 Essentials/src/main/kotlin/com/beemer/essentials/command/WorkbenchCommand.kt diff --git a/Essentials/src/main/kotlin/com/beemer/essentials/Essentials.kt b/Essentials/src/main/kotlin/com/beemer/essentials/Essentials.kt index 94b9e0c..812d52e 100644 --- a/Essentials/src/main/kotlin/com/beemer/essentials/Essentials.kt +++ b/Essentials/src/main/kotlin/com/beemer/essentials/Essentials.kt @@ -33,5 +33,6 @@ class Essentials(modEventBus: IEventBus) { NeoForge.EVENT_BUS.register(NicknameCommand) NeoForge.EVENT_BUS.register(HeadCommand) NeoForge.EVENT_BUS.register(HelpCommand) + NeoForge.EVENT_BUS.register(WorkbenchCommand) } } diff --git a/Essentials/src/main/kotlin/com/beemer/essentials/command/HelpCommand.kt b/Essentials/src/main/kotlin/com/beemer/essentials/command/HelpCommand.kt index a348d44..00f1a3d 100644 --- a/Essentials/src/main/kotlin/com/beemer/essentials/command/HelpCommand.kt +++ b/Essentials/src/main/kotlin/com/beemer/essentials/command/HelpCommand.kt @@ -70,6 +70,11 @@ object HelpCommand { sendCategory(player, "머리", ChatFormatting.GOLD) sendCommand(player, "/머리", "내 머리 아이템 받기") sendCommand(player, "/머리 <닉네임>", "해당 플레이어 머리 받기") + player.sendSystemMessage(Component.empty()) + + // 제작대 + sendCategory(player, "제작대", ChatFormatting.WHITE) + sendCommand(player, "/제작대", "제작대 열기") val footer = Component.literal("═══════════════════════════════").withStyle { diff --git a/Essentials/src/main/kotlin/com/beemer/essentials/command/WorkbenchCommand.kt b/Essentials/src/main/kotlin/com/beemer/essentials/command/WorkbenchCommand.kt new file mode 100644 index 0000000..cb5b92e --- /dev/null +++ b/Essentials/src/main/kotlin/com/beemer/essentials/command/WorkbenchCommand.kt @@ -0,0 +1,66 @@ +package com.beemer.essentials.command + +import java.util.Optional +import java.util.function.BiFunction +import net.minecraft.ChatFormatting +import net.minecraft.commands.Commands +import net.minecraft.core.BlockPos +import net.minecraft.network.chat.Component +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.SimpleMenuProvider +import net.minecraft.world.entity.player.Player +import net.minecraft.world.inventory.ContainerLevelAccess +import net.minecraft.world.inventory.CraftingMenu +import net.minecraft.world.level.Level +import net.neoforged.bus.api.SubscribeEvent +import net.neoforged.neoforge.event.RegisterCommandsEvent + +object WorkbenchCommand { + @SubscribeEvent + fun onRegisterCommands(event: RegisterCommandsEvent) { + // /제작대, /workbench - 제작대 GUI 열기 + listOf("제작대", "workbench").forEach { command -> + event.dispatcher.register( + Commands.literal(command).executes { context -> + val player = context.source.entity as? ServerPlayer + if (player == null) { + context.source.sendFailure( + Component.literal("플레이어만 사용할 수 있는 명령어입니다.") + .withStyle(ChatFormatting.RED) + ) + return@executes 0 + } + + openWorkbench(player) + 1 + } + ) + } + } + + /** 항상 유효한 ContainerLevelAccess 생성 */ + private fun createAlwaysValidAccess(level: Level, pos: BlockPos): ContainerLevelAccess { + return object : ContainerLevelAccess { + override fun evaluate(function: BiFunction): Optional { + return Optional.ofNullable(function.apply(level, pos)) + } + } + } + + /** 플레이어에게 제작대 GUI 열기 */ + private fun openWorkbench(player: ServerPlayer) { + val access = createAlwaysValidAccess(player.level(), player.blockPosition()) + + player.openMenu( + SimpleMenuProvider( + { containerId, inventory, _ -> + object : CraftingMenu(containerId, inventory, access) { + // stillValid를 오버라이드하여 항상 true 반환 (거리 제한 없음) + override fun stillValid(player: Player): Boolean = true + } + }, + Component.translatable("container.crafting") + ) + ) + } +}