-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Player Inventory as secondary GUI (#22)
* feat: implement attached guis Uses PlayerInventory as another GUI * fix: cleanup gui template Should work for Player inventories now. * misc: attached gui cleanup * misc: remove comment
- Loading branch information
1 parent
691c54a
commit 4ffaa71
Showing
11 changed files
with
285 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,54 @@ | ||
package me.tech.mcchestui | ||
|
||
import net.kyori.adventure.text.Component | ||
import org.bukkit.Bukkit | ||
import org.bukkit.event.inventory.InventoryType | ||
import org.bukkit.inventory.Inventory | ||
|
||
sealed class GUIType( | ||
val slotsPerRow: Int, | ||
val rows: Int, | ||
val inventoryType: InventoryType | ||
) { | ||
/** | ||
* @return total amount of slots a [InventoryType] can hold. | ||
*/ | ||
val totalSlots: Int | ||
get() = slotsPerRow * rows | ||
|
||
internal open fun createBukkitInventory( | ||
title: Component | ||
): Inventory { | ||
return Bukkit.createInventory(null, inventoryType, title) | ||
} | ||
|
||
sealed interface GUIType { | ||
val slotsPerRow: Int | ||
val rows: Int | ||
val inventoryType: InventoryType | ||
|
||
data class Chest(override val rows: Int) : GUIType { | ||
override val slotsPerRow: Int | ||
get() = 9 | ||
|
||
override val inventoryType: InventoryType | ||
get() = InventoryType.CHEST | ||
|
||
class Chest(rows: Int) : GUIType( | ||
slotsPerRow = 9, | ||
rows, | ||
inventoryType = InventoryType.CHEST | ||
) { | ||
init { | ||
if(rows < 1 || rows > 6) { | ||
throw IllegalArgumentException( | ||
"chest rows cannot be ${if(rows < 1) "below" else "above"} $rows." | ||
) | ||
} | ||
} | ||
} | ||
|
||
data object Dispenser : GUIType { | ||
override val slotsPerRow: Int | ||
get() = 3 | ||
|
||
override val rows: Int | ||
get() = 3 | ||
|
||
override val inventoryType: InventoryType | ||
get() = InventoryType.DISPENSER | ||
} | ||
|
||
data object Hopper : GUIType { | ||
override val slotsPerRow: Int | ||
get() = 5 | ||
|
||
override val rows: Int | ||
get() = 1 | ||
override fun createBukkitInventory(title: Component): Inventory { | ||
return Bukkit.createInventory(null, slotsPerRow * rows, title) | ||
} | ||
} | ||
|
||
override val inventoryType: InventoryType | ||
get() = InventoryType.HOPPER | ||
} | ||
data object Dispenser : GUIType( | ||
slotsPerRow = 3, | ||
rows = 3, | ||
inventoryType = InventoryType.HOPPER | ||
) | ||
|
||
data object Hopper : GUIType( | ||
slotsPerRow = 5, | ||
rows = 1, | ||
inventoryType = InventoryType.HOPPER | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package me.tech.mcchestui.attached | ||
|
||
import me.tech.mcchestui.GUI | ||
import org.bukkit.entity.Player | ||
import org.bukkit.inventory.PlayerInventory | ||
|
||
/** | ||
* Attach a [PlayerInventory] to a [GUI] to be used as a | ||
* secondary menu alongside the parent [GUI]. | ||
* | ||
* @param player [PlayerInventory] to be used. | ||
*/ | ||
fun GUI.attach(player: Player) { | ||
// cache inventory. | ||
attachedInventoryCache.saveInventory(player) | ||
player.inventory.storageContents = emptyArray() | ||
|
||
attach(player.inventory) | ||
} | ||
|
||
/** | ||
* Attach a [PlayerInventory] to a [GUI] to be used as a | ||
* secondary menu alongside the parent [GUI]. | ||
* | ||
* @param playerInventory inventory to be used. | ||
*/ | ||
private fun GUI.attach(playerInventory: PlayerInventory) { | ||
attachedGui = GUI(plugin, playerInventory) | ||
} |
78 changes: 78 additions & 0 deletions
78
src/main/kotlin/me/tech/mcchestui/attached/AttachedInventoryCache.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package me.tech.mcchestui.attached | ||
|
||
import me.tech.mcchestui.GUI | ||
import org.bukkit.entity.Player | ||
|
||
import org.bukkit.inventory.ItemStack | ||
import org.bukkit.inventory.PlayerInventory | ||
import java.util.* | ||
|
||
/** | ||
* Used to cache the items removed from a [Player] when | ||
* a [GUI.attachedGui] is being used. | ||
* | ||
* The items of the [Player] are restored when the GUICloseEvent is called | ||
* on the parent [GUI]. | ||
* Contents of the [Player] inventory will then be restored. | ||
*/ | ||
interface AttachedInventoryCache { | ||
/** | ||
* Save the storage contents of a [PlayerInventory] before the contents of | ||
* the [GUI.attachedGui] override the [PlayerInventory]. | ||
* | ||
* @param player | ||
* @return whether the operation was a success. | ||
*/ | ||
fun saveInventory(player: Player): Boolean | ||
|
||
/** | ||
* Restore the storage contents of a [PlayerInventory] to their state | ||
* before being overridden by the [GUI.attachedGui]. | ||
* | ||
* @param player | ||
* @return whether the operation was a success. | ||
*/ | ||
fun restoreInventory(player: Player): Boolean | ||
} | ||
|
||
/** | ||
* Memory attached gui cache. | ||
*/ | ||
internal object MemoryAttachedInventoryCache : AttachedInventoryCache { | ||
private val cachedInventory = mutableMapOf<UUID, Array<ItemStack?>>() | ||
|
||
override fun saveInventory(player: Player): Boolean { | ||
cachedInventory[player.uniqueId] = player.inventory.storageContents | ||
|
||
return true | ||
} | ||
|
||
override fun restoreInventory(player: Player): Boolean { | ||
val inventory = cachedInventory[player.uniqueId] | ||
?: return false | ||
|
||
player.inventory.storageContents = inventory | ||
cachedInventory.remove(player.uniqueId) | ||
|
||
return true | ||
} | ||
} | ||
|
||
/** | ||
* Attach a custom [AttachedInventoryCache] to a [GUI]. | ||
* By default, the [MemoryAttachedInventoryCache] is used. | ||
*/ | ||
fun GUI.attachInventoryCache(cache: AttachedInventoryCache) { | ||
attachedInventoryCache = cache | ||
} | ||
|
||
/** | ||
* Restore a players inventory from the [AttachedInventoryCache]. | ||
* | ||
* @param player player to cache. | ||
* @param gui gui to cache for. | ||
*/ | ||
internal fun restoreCachedInventory(player: Player, gui: GUI) { | ||
player.inventory.storageContents = emptyArray() | ||
gui.attachedInventoryCache.restoreInventory(player) | ||
} |
Oops, something went wrong.