diff --git a/src/main/kotlin/com/liamxsage/energeticstorage/gui/DiskDriveGui.kt b/src/main/kotlin/com/liamxsage/energeticstorage/gui/DiskDriveGui.kt index 24900eb..f91d6d6 100644 --- a/src/main/kotlin/com/liamxsage/energeticstorage/gui/DiskDriveGui.kt +++ b/src/main/kotlin/com/liamxsage/energeticstorage/gui/DiskDriveGui.kt @@ -19,6 +19,7 @@ import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.inventory.Inventory import org.bukkit.inventory.InventoryHolder +import org.bukkit.inventory.PlayerInventory import java.util.* class DiskDriveGui : InventoryHolder, Listener { @@ -96,66 +97,104 @@ class DiskDriveGui : InventoryHolder, Listener { when(clickType) { in setOf(ClickType.SWAP, ClickType.SWAP_RIGHT_CLICK) -> return@with in setOf(ClickType.INVENTORY_CLICK, ClickType.SHIFT_IN, ClickType.INTO_HALF, ClickType.INTO) -> { - val item = currentItem ?: return - if (item.type != Material.MUSIC_DISC_5 || !item.hasKey(DISK_ID_NAMESPACE)) return@with - val driveUUID = item.getKey(DISK_ID_NAMESPACE) ?: return - val drive = DiskCache.getDiskByUUID(UUID.fromString(driveUUID)) ?: return - - if (!diskDrive.canFitDrive) { - player.sendDeniedSound() - return@with - } - - if (diskDrive.disks.any { it.uuid == drive.uuid }) { - player.sendDeniedSound() - return@with - } - - val firstEmpty = thisInventory.firstEmpty() - if (firstEmpty == -1) { - player.sendDeniedSound() - return@with - } - - drive.diskDriveUUID = diskDrive.uuid - diskDrive.disks.add(drive) - drive.saveToDB() - playerInventory.removeItem(item) - thisInventory.setItem(firstEmpty, item) - - player.sendInsertDiskSound() - diskDrive.updateBlock(block) + handleInsertDisk(diskDrive, player, thisInventory, playerInventory, block) } in setOf(ClickType.OUT, ClickType.OUT_HALF, ClickType.SHIFT_OUT) -> { - if (slot == 0) { - player.closeInventory() - return@with - } - if (slot in setOf(1, 8)) return@with + handleRemoveDisk(player, thisInventory, playerInventory, diskDrive, block) + } + else -> return@with + } + } + + /** + * Handles the logic for removing a disk from a disk drive in an inventory click event. + * + * @param player The player who triggered the inventory click event. + * @param thisInventory The inventory in which the event occurred. + * @param playerInventory The player's inventory. + * @param diskDrive The disk drive from which the disk is removed. + * @param block The block representing the disk drive. + */ + private fun InventoryClickEvent.handleRemoveDisk( + player: Player, + thisInventory: Inventory, + playerInventory: PlayerInventory, + diskDrive: DiskDrive, + block: Block + ) { + if (slot == 0) { + player.closeInventory() + return + } + if (slot in setOf(1, 8)) return - val diskItem = thisInventory.getItem(slot) ?: return@with - if (diskItem.type != Material.MUSIC_DISC_5 || !diskItem.hasKey(DISK_ID_NAMESPACE)) return@with + val diskItem = thisInventory.getItem(slot) ?: return + if (diskItem.type != Material.MUSIC_DISC_5 || !diskItem.hasKey(DISK_ID_NAMESPACE)) return - val diskUUID = diskItem.getKey(DISK_ID_NAMESPACE) ?: return - val disk = DiskCache.getDiskByUUID(UUID.fromString(diskUUID)) ?: Disk(UUID.fromString(diskUUID)) + val diskUUID = diskItem.getKey(DISK_ID_NAMESPACE) ?: return + val disk = DiskCache.getDiskByUUID(UUID.fromString(diskUUID)) ?: Disk(UUID.fromString(diskUUID)) - val firstEmpty = playerInventory.firstEmpty() - if (firstEmpty == -1) { - player.sendDeniedSound() - return@with - } + val firstEmpty = playerInventory.firstEmpty() + if (firstEmpty == -1) { + player.sendDeniedSound() + return + } - diskDrive.disks.remove(disk) - disk.diskDriveUUID = null - disk.saveToDB() + diskDrive.disks.remove(disk) + disk.diskDriveUUID = null + disk.saveToDB() - thisInventory.setItem(slot, null) - playerInventory.setItem(firstEmpty, diskItem) + thisInventory.setItem(slot, null) + playerInventory.setItem(firstEmpty, diskItem) - player.sendRemoveDiskSound() - diskDrive.updateBlock(block) - } - else -> return@with + player.sendRemoveDiskSound() + diskDrive.updateBlock(block) + } + + /** + * Handles inserting a disk into a disk drive during an inventory click event. + * + * @param diskDrive The disk drive receiving the disk. + * @param player The player interacting with the disk drive. + * @param thisInventory The inventory where the disk is being inserted. + * @param playerInventory The player's inventory. + * @param block The block representing the disk drive. + */ + private fun InventoryClickEvent.handleInsertDisk( + diskDrive: DiskDrive, + player: Player, + thisInventory: Inventory, + playerInventory: PlayerInventory, + block: Block + ) { + val item = currentItem ?: return + if (item.type != Material.MUSIC_DISC_5 || !item.hasKey(DISK_ID_NAMESPACE)) return + val driveUUID = item.getKey(DISK_ID_NAMESPACE) ?: return + val drive = DiskCache.getDiskByUUID(UUID.fromString(driveUUID)) ?: return + + if (!diskDrive.canFitDrive) { + player.sendDeniedSound() + return } + + if (diskDrive.disks.any { it.uuid == drive.uuid }) { + player.sendDeniedSound() + return + } + + val firstEmpty = thisInventory.firstEmpty() + if (firstEmpty == -1) { + player.sendDeniedSound() + return + } + + drive.diskDriveUUID = diskDrive.uuid + diskDrive.disks.add(drive) + drive.saveToDB() + playerInventory.removeItem(item) + thisInventory.setItem(firstEmpty, item) + + player.sendInsertDiskSound() + diskDrive.updateBlock(block) } } \ No newline at end of file diff --git a/src/main/kotlin/com/liamxsage/energeticstorage/gui/GuiFunctions.kt b/src/main/kotlin/com/liamxsage/energeticstorage/gui/GuiFunctions.kt index f1fa678..fc629cf 100644 --- a/src/main/kotlin/com/liamxsage/energeticstorage/gui/GuiFunctions.kt +++ b/src/main/kotlin/com/liamxsage/energeticstorage/gui/GuiFunctions.kt @@ -5,34 +5,79 @@ import org.bukkit.Material import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.inventory.InventoryHolder +/** + * Determines the [ClickType] for a given [InventoryClickEvent] based on the [InventoryHolder] and [title] of the clicked inventory. + * + * @param event The [InventoryClickEvent] that triggered the click. + * @param title The [Component] title of the inventory. + * @return The determined [ClickType] for the click. + */ fun InventoryHolder.findClickType(event: InventoryClickEvent, title: Component): ClickType { val inventory = event.clickedInventory + val isHolderClick = inventory?.holder == this - if ((inventory == null) || inventory.holder == null || inventory.holder !== this) { - // Check for a shift click or bottom inventory click. - if (event.view.title() == title) { - return if ((event.isShiftClick)) ClickType.SHIFT_IN else ClickType.INVENTORY_CLICK - } + return when { + !isHolderClick -> determineClickTypeForNonHolderClick(event.view.title(), title, event.isShiftClick) + else -> determineTypeForHolderClick(event) + } +} - return ClickType.NONE +/** + * Determines the [ClickType] for a non-holder click in an inventory. + * + * @param viewTitle the title of the inventory view + * @param title the title of the inventory being clicked + * @param isShiftClick indicates if the click is a shift-click + * @return the determined [ClickType] for the click + */ +private fun determineClickTypeForNonHolderClick(viewTitle: Component, title: Component, isShiftClick: Boolean): ClickType { + return if (viewTitle == title) { + if (isShiftClick) ClickType.SHIFT_IN else ClickType.INVENTORY_CLICK + } else { + ClickType.NONE } +} +/** + * Determines the [ClickType] based on the [InventoryClickEvent]. + * + * @param event the InventoryClickEvent + * @return the determined ClickType + */ +private fun determineTypeForHolderClick(event: InventoryClickEvent): ClickType { val clickedItem = event.currentItem val cursor = event.cursor + val isClickedItemEmpty = clickedItem == null || clickedItem.type == Material.AIR + val isCursorEmpty = cursor.type == Material.AIR return when { - (clickedItem == null || clickedItem.type == Material.AIR) && (cursor.type == Material.AIR) -> { - ClickType.NONE - } - - clickedItem == null || clickedItem.type == Material.AIR -> { - if ((event.isLeftClick)) ClickType.INTO else ClickType.INTO_HALF - } + isClickedItemEmpty && isCursorEmpty -> ClickType.NONE + isClickedItemEmpty -> determineClickTypeForEmptyClickedItem(event.isLeftClick) + isCursorEmpty -> determineClickTypeForEmptyCursor(event) + else -> if (event.isLeftClick) ClickType.SWAP else ClickType.SWAP_RIGHT_CLICK + } +} - cursor.type == Material.AIR -> { - if ((event.isShiftClick)) ClickType.SHIFT_OUT else if ((event.isLeftClick)) ClickType.OUT else ClickType.OUT_HALF - } +/** + * Determines the click type for an empty clicked item. + * + * @param isLeftClick Boolean indicating whether the click is a left click or not + * @return The determined ClickType - either ClickType.INTO or ClickType.INTO_HALF + */ +private fun determineClickTypeForEmptyClickedItem(isLeftClick: Boolean): ClickType { + return if (isLeftClick) ClickType.INTO else ClickType.INTO_HALF +} - else -> if ((event.isLeftClick)) ClickType.SWAP else ClickType.SWAP_RIGHT_CLICK +/** + * Determines the click type for an empty cursor in the InventoryClickEvent. + * + * @param event The InventoryClickEvent. + * @return The ClickType corresponding to the click type for an empty cursor. + */ +private fun determineClickTypeForEmptyCursor(event: InventoryClickEvent): ClickType { + return if (event.isShiftClick) { + ClickType.SHIFT_OUT + } else { + if (event.isLeftClick) ClickType.OUT else ClickType.OUT_HALF } } \ No newline at end of file diff --git a/src/main/kotlin/com/liamxsage/energeticstorage/items/ItemBuilder.kt b/src/main/kotlin/com/liamxsage/energeticstorage/items/ItemBuilder.kt index 3be3a5d..b390645 100644 --- a/src/main/kotlin/com/liamxsage/energeticstorage/items/ItemBuilder.kt +++ b/src/main/kotlin/com/liamxsage/energeticstorage/items/ItemBuilder.kt @@ -25,7 +25,6 @@ import org.bukkit.inventory.meta.SkullMeta import org.bukkit.persistence.PersistentDataType import java.lang.reflect.Field import java.net.URI -import java.net.URL import java.util.* diff --git a/src/main/kotlin/com/liamxsage/energeticstorage/listeners/PlayerInteractListener.kt b/src/main/kotlin/com/liamxsage/energeticstorage/listeners/PlayerInteractListener.kt index c513acf..a221494 100644 --- a/src/main/kotlin/com/liamxsage/energeticstorage/listeners/PlayerInteractListener.kt +++ b/src/main/kotlin/com/liamxsage/energeticstorage/listeners/PlayerInteractListener.kt @@ -33,25 +33,51 @@ class PlayerInteractListener : Listener { if (!block.isNetworkInterface) return@with val networkInterfaceType = getNetworkInterfaceType(block) ?: return@with isCancelled = true + if (item?.isNetworkInterface == true) return@with - if (item?.isNetworkInterface == true) { - return@with - } + handleClickOnNetworkInterface(networkInterfaceType, block) + } + + /** + * Handles the interaction with the network interface based on the provided network interface type. + * + * @param networkInterfaceType The type of the network interface. + * @param block The block that was clicked. + */ + private fun PlayerInteractEvent.handleClickOnNetworkInterface( + networkInterfaceType: NetworkInterfaceType, + block: Block + ) { + when (networkInterfaceType) { + NetworkInterfaceType.DISK_DRIVE -> handleDiskDriveInteraction( + block, + player.inventory.itemInMainHand, + player + ) - when(networkInterfaceType) { - NetworkInterfaceType.DISK_DRIVE -> handleDiskDriveInteraction(block, player.inventory.itemInMainHand, player) NetworkInterfaceType.TERMINAL -> player.sendMessagePrefixed("Terminal") - else -> { /* Do nothing */ } + else -> { /* Do nothing */ + } } - if (!player.isESDebugModeEnabled) return@with + if (!player.isESDebugModeEnabled) return + sendDebugInfo(networkInterfaceType) + } + /** + * Sends debug information about the player's interaction with a network interface block. + * + * @param networkInterfaceType The type of the network interface. + */ + private fun PlayerInteractEvent.sendDebugInfo(networkInterfaceType: NetworkInterfaceType) { // The following code is only for debugging purposes val connectedInterfaced = getConnectedNetworkInterfaces(clickedBlock!!) val interfacesSummedByType = connectedInterfaced.values.groupBy { it::class.java }.mapValues { it.value.size } player.sendMessagePrefixed("Clicked Network Interface: ${ networkInterfaceType.name.lowercase(Locale.getDefault()) - .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}") + .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + }" + ) player.sendMessagePrefixed("Network Interfaces found:") interfacesSummedByType.forEach { (type, amount) -> player.sendMessagePrefixed("${type.simpleName}: $amount") @@ -59,37 +85,19 @@ class PlayerInteractListener : Listener { player.sendInfoSound() } + /** + * Handles the interaction with a disk drive. + * + * @param block The block representing the disk drive. + * @param item The item held by the player. + * @param player The player interacting with the disk drive. + */ private fun handleDiskDriveInteraction(block: Block, item: ItemStack?, player: Player) { if (!block.persistentDataContainer.has(DISK_DRIVE_ID_NAMESPACE)) return val diskDriveUUID = block.persistentDataContainer[DISK_DRIVE_ID_NAMESPACE, PersistentDataType.STRING] ?: return val diskDrive = DiskDriveCache.getDiskDriveByUUID(UUID.fromString(diskDriveUUID)) ?: DiskDrive(UUID.fromString(diskDriveUUID)) - if (item != null && item.type == Material.MUSIC_DISC_5 && item.hasKey(DISK_ID_NAMESPACE)) { - val driveUUID = item.getKey(DISK_ID_NAMESPACE) ?: return - val drive = DiskCache.getDiskByUUID(UUID.fromString(driveUUID)) ?: return - - if (!diskDrive.canFitDrive) { - player.sendMessagePrefixed("All drive slots of this system are full.") - return - } - - if (diskDrive.disks.any { it.uuid == drive.uuid }) { - player.sendMessagePrefixed("This drive is already inserted into the system. Did you dupe it?") - return - } - - drive.diskDriveUUID = diskDrive.uuid - diskDrive.disks.add(drive) - drive.saveToDB() - if (item.amount == 1) player.inventory.removeItem(item) - else item.amount = item.amount.minus(1) - DiskDriveCache.addDiskDrive(diskDrive) - diskDrive.updateBlock(block) - - player.sendMessagePrefixed("Successfully inserted drive.") - player.sendSuccessSound() - return - } + if (tryInsertingDiskIntoDrive(item, diskDrive, player, block)) return DiskDriveGui.instance.openInventory(player, diskDrive, block) @@ -99,4 +107,46 @@ class PlayerInteractListener : Listener { player.sendMessagePrefixed("Filled Items: ${diskDrive.totalItems}/${diskDrive.totalSize}") player.sendMessagePrefixed("Filled Types: ${diskDrive.totalTypes}/${diskDrive.totalTypesSize}") } + + /** + * Tries to insert a disk into a disk drive. + * + * @param item The item to insert into the disk drive. + * @param diskDrive The disk drive to insert the item into. + * @param player The player performing the action. + * @param block The block representing the disk drive. + * @return True if the disk was successfully inserted, false otherwise. + */ + private fun tryInsertingDiskIntoDrive( + item: ItemStack?, + diskDrive: DiskDrive, + player: Player, + block: Block + ): Boolean { + if (item == null || item.type != Material.MUSIC_DISC_5 || !item.hasKey(DISK_ID_NAMESPACE)) return false + val driveUUID = item.getKey(DISK_ID_NAMESPACE) ?: return false + val drive = DiskCache.getDiskByUUID(UUID.fromString(driveUUID)) ?: return false + + if (!diskDrive.canFitDrive) { + player.sendMessagePrefixed("All drive slots of this system are full.") + return true + } + + if (diskDrive.disks.any { it.uuid == drive.uuid }) { + player.sendMessagePrefixed("This drive is already inserted into the system. Did you dupe it?") + return true + } + + drive.diskDriveUUID = diskDrive.uuid + diskDrive.disks.add(drive) + drive.saveToDB() + if (item.amount == 1) player.inventory.removeItem(item) + else item.amount = item.amount.minus(1) + DiskDriveCache.addDiskDrive(diskDrive) + diskDrive.updateBlock(block) + + player.sendMessagePrefixed("Successfully inserted drive.") + player.sendSuccessSound() + return true + } } \ No newline at end of file