From 21d4d9c749b36f48b13a85b6fc79f35b4c53bce7 Mon Sep 17 00:00:00 2001 From: James58899 Date: Sat, 17 Aug 2024 23:44:55 +0800 Subject: [PATCH 1/3] Add GUI block entity binding --- .../galaxy/block/entity/HarvestBlockEntity.kt | 2 +- .../galaxy/block/entity/TestGuiBlockEntity.kt | 4 ++-- .../block/entity/TrashcanBlockEntity.kt | 14 ++---------- src/main/kotlin/one/oktw/galaxy/gui/GUI.kt | 22 +++++++++++++++---- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt b/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt index 41b1cd0e5..4a9fe6198 100644 --- a/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt +++ b/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt @@ -54,7 +54,7 @@ class HarvestBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: Ite override val allowedFacing = listOf(Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST) private val inventory = DefaultedList.ofSize(4, ItemStack.EMPTY) - private val gui = GUI.Builder(ScreenHandlerType.GENERIC_9X3).setTitle(Text.translatable("block.HARVEST")).apply { + private val gui = GUI.Builder(ScreenHandlerType.GENERIC_9X3).setTitle(Text.translatable("block.HARVEST")).blockEntity(this).apply { var i = 0 addSlot(4, 0, object : Slot(this@HarvestBlockEntity, i++, 0, 0) { // Tool override fun canInsert(item: ItemStack) = isHoe(item) diff --git a/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt b/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt index 3f057ea7a..4cd5b5ef9 100644 --- a/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt +++ b/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt @@ -44,7 +44,7 @@ import one.oktw.galaxy.item.Gui class TestGuiBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: ItemStack) : ModelCustomBlockEntity(type, pos, modelItem), CustomBlockClickListener, Inventory { private val inventory = DefaultedList.ofSize(3 * 9, ItemStack.EMPTY) - private val gui = GUI.Builder(ScreenHandlerType.GENERIC_9X6).setTitle(Text.of("Test GUI")).apply { + private val gui = GUI.Builder(ScreenHandlerType.GENERIC_9X6).setTitle(Text.of("Test GUI")).blockEntity(this).apply { var i = 0 for (x in 0 until 9) addSlot(x, 0, Slot(this@TestGuiBlockEntity, i++, 0, 0)) for (y in 4 until 6) for (x in 0 until 9) addSlot(x, y, Slot(this@TestGuiBlockEntity, i++, 0, 0)) @@ -57,7 +57,7 @@ class TestGuiBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: Ite GUISBackStackManager.openGUI(player, gui2) } } - private val gui2 = GUI.Builder(ScreenHandlerType.GENERIC_9X4).setTitle(Text.of("Test GUI2")).apply { + private val gui2 = GUI.Builder(ScreenHandlerType.GENERIC_9X4).setTitle(Text.of("Test GUI2")).blockEntity(this).apply { var i = 0 for (y in 0 until 3) for (x in 0 until 9) addSlot(x, y, Slot(this@TestGuiBlockEntity, i++, 0, 0)) }.build().apply { diff --git a/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt b/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt index 1e4d480b0..0fcb7861f 100644 --- a/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt +++ b/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt @@ -60,20 +60,10 @@ class TrashcanBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: It val gui = GUI .Builder(ScreenHandlerType.GENERIC_9X4) + .setTitle(Text.of("Trashcan")) + .blockEntity(this) .apply { - setTitle(Text.of("Trashcan")) - var i = 0 -// val inv = object : SimpleInventory(9 * 4) { -// override fun canPlayerUse(player: PlayerEntity): Boolean { -// val trashcanBlock = this@TrashcanBlockEntity -// if (trashcanBlock.world!!.getBlockEntity(trashcanBlock.pos) != trashcanBlock) { -// return false -// } -// -// return player.squaredDistanceTo(trashcanBlock.pos.x + 0.5, trashcanBlock.pos.y + 0.5, trashcanBlock.pos.z + 0.5) <= 64 -// } -// } val inv = SimpleInventory(9 * 4) for (y in 0 until 4) for (x in 0 until 9) addSlot(x, y, Slot(inv, i++, 0, 0)) diff --git a/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt b/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt index 7406b1aaa..186387125 100644 --- a/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt +++ b/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt @@ -21,8 +21,10 @@ package one.oktw.galaxy.gui import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.launch +import net.minecraft.block.entity.BlockEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.Inventory import net.minecraft.inventory.SimpleInventory import net.minecraft.item.ItemStack import net.minecraft.screen.NamedScreenHandlerFactory @@ -41,7 +43,12 @@ import org.apache.logging.log4j.LogManager import java.util.concurrent.ConcurrentHashMap @Suppress("unused", "MemberVisibilityCanBePrivate") -class GUI private constructor(private val type: ScreenHandlerType, private val title: Text, private val slotBindings: HashMap) : +class GUI private constructor( + private val type: ScreenHandlerType, + private val title: Text, + private val slotBindings: HashMap, + private val blockEntity: BlockEntity? = null +) : NamedScreenHandlerFactory { private val inventory = when (type) { GENERIC_9X1, GENERIC_3X3 -> SimpleInventory(9) @@ -118,6 +125,8 @@ class GUI private constructor(private val type: ScreenHandlerType() + private var blockEntity: BlockEntity? = null + fun setTitle(title: Text): Builder { this.title = title return this @@ -133,8 +142,13 @@ class GUI private constructor(private val type: ScreenHandlerType { // Rewrite PICKUP_ALL only take from allow use slot & player inventory. if (slot < 0) return @@ -252,8 +267,7 @@ class GUI private constructor(private val type: ScreenHandlerType Date: Sun, 18 Aug 2024 00:33:45 +0800 Subject: [PATCH 2/3] Fix back stack open invalid gui --- src/main/kotlin/one/oktw/galaxy/gui/GUI.kt | 3 ++- .../kotlin/one/oktw/galaxy/gui/GUISBackStackManager.kt | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt b/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt index 186387125..14c9f6248 100644 --- a/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt +++ b/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt @@ -70,7 +70,8 @@ class GUI private constructor( override fun getDisplayName() = title - override fun createMenu(syncId: Int, playerInventory: PlayerInventory, player: PlayerEntity): ScreenHandler { + override fun createMenu(syncId: Int, playerInventory: PlayerInventory, player: PlayerEntity): ScreenHandler? { + if (blockEntity?.isRemoved == true) return null return GuiContainer(syncId, playerInventory) } diff --git a/src/main/kotlin/one/oktw/galaxy/gui/GUISBackStackManager.kt b/src/main/kotlin/one/oktw/galaxy/gui/GUISBackStackManager.kt index 051fac945..8dcea04e7 100644 --- a/src/main/kotlin/one/oktw/galaxy/gui/GUISBackStackManager.kt +++ b/src/main/kotlin/one/oktw/galaxy/gui/GUISBackStackManager.kt @@ -59,7 +59,12 @@ class GUISBackStackManager(private val player: ServerPlayerEntity) : CoroutineSc stack.pollLast() // Remove closed // Delay 1 tick to workaround open GUI on close callback - launch { stack.lastOrNull()?.let(player::openHandledScreen) } // Open previous + launch { + while (stack.isNotEmpty()) { + if (stack.last().let(player::openHandledScreen).isPresent) break // Try open previous + stack.pollLast() // Open fail, remove it + } + } } } } From 4d001a596c72a70dcf0cb8a89df3dfda6f3be9fd Mon Sep 17 00:00:00 2001 From: James58899 Date: Sun, 18 Aug 2024 01:05:59 +0800 Subject: [PATCH 3/3] Fix block can use --- .../one/oktw/galaxy/block/entity/HarvestBlockEntity.kt | 5 ++--- .../one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt | 4 +--- .../one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt | 4 +++- src/main/kotlin/one/oktw/galaxy/gui/GUI.kt | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt b/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt index 4a9fe6198..6e777545b 100644 --- a/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt +++ b/src/main/kotlin/one/oktw/galaxy/block/entity/HarvestBlockEntity.kt @@ -22,6 +22,7 @@ import net.minecraft.block.* import net.minecraft.block.entity.BlockEntityType import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.Inventories +import net.minecraft.inventory.Inventory import net.minecraft.inventory.SidedInventory import net.minecraft.item.HoeItem import net.minecraft.item.ItemStack @@ -167,9 +168,7 @@ class HarvestBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: Ite } override fun canPlayerUse(player: PlayerEntity): Boolean { - return if (world!!.getBlockEntity(pos) !== this) { - false - } else player.squaredDistanceTo(pos.x.toDouble() + 0.5, pos.y.toDouble() + 0.5, pos.z.toDouble() + 0.5) <= 64.0 + return Inventory.canPlayerUse(this, player) } override fun getAvailableSlots(side: Direction): IntArray { diff --git a/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt b/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt index 4cd5b5ef9..ae5da3319 100644 --- a/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt +++ b/src/main/kotlin/one/oktw/galaxy/block/entity/TestGuiBlockEntity.kt @@ -113,8 +113,6 @@ class TestGuiBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: Ite } override fun canPlayerUse(player: PlayerEntity): Boolean { - return if (world!!.getBlockEntity(pos) !== this) { - false - } else player.squaredDistanceTo(pos.x.toDouble() + 0.5, pos.y.toDouble() + 0.5, pos.z.toDouble() + 0.5) <= 64.0 + return Inventory.canPlayerUse(this, player) } } diff --git a/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt b/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt index 0fcb7861f..765526688 100644 --- a/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt +++ b/src/main/kotlin/one/oktw/galaxy/block/entity/TrashcanBlockEntity.kt @@ -51,7 +51,9 @@ class TrashcanBlockEntity(type: BlockEntityType<*>, pos: BlockPos, modelItem: It override fun setStack(slot: Int, stack: ItemStack?) {} - override fun canPlayerUse(player: PlayerEntity): Boolean = false + override fun canPlayerUse(player: PlayerEntity): Boolean { + return Inventory.canPlayerUse(this, player) + } override fun onClick(player: PlayerEntity, hand: Hand, hit: BlockHitResult): ActionResult { if (player.isSpectator) { diff --git a/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt b/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt index 14c9f6248..fddcc2b9f 100644 --- a/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt +++ b/src/main/kotlin/one/oktw/galaxy/gui/GUI.kt @@ -71,7 +71,7 @@ class GUI private constructor( override fun getDisplayName() = title override fun createMenu(syncId: Int, playerInventory: PlayerInventory, player: PlayerEntity): ScreenHandler? { - if (blockEntity?.isRemoved == true) return null + if ((blockEntity as? Inventory)?.canPlayerUse(player) == false) return null return GuiContainer(syncId, playerInventory) }