Beginning of InventoryGUI
This commit is contained in:
166
src/main/kotlin/net/axay/kspigot/inventory/InventoryGUI.kt
Normal file
166
src/main/kotlin/net/axay/kspigot/inventory/InventoryGUI.kt
Normal file
@@ -0,0 +1,166 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import net.axay.kspigot.event.listen
|
||||
import net.axay.kspigot.event.register
|
||||
import net.axay.kspigot.main.KSpigot
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.InventoryInteractEvent
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.InventoryView
|
||||
|
||||
// EXTENSIONS
|
||||
|
||||
fun HumanEntity.openGUI(gui: InventoryGUI, page: Int = 1): InventoryView? {
|
||||
closeInventory()
|
||||
gui.loadPage(page)
|
||||
return openInventory(gui.bukkitInventory)
|
||||
}
|
||||
|
||||
// GUI HOLDER
|
||||
|
||||
class InventoryGUIHolder(kSpigot: KSpigot) : AutoCloseable {
|
||||
|
||||
private val registered = HashSet<InventoryGUI>()
|
||||
|
||||
fun register(inventoryGUI: InventoryGUI) {
|
||||
registered += inventoryGUI
|
||||
}
|
||||
|
||||
fun unregister(inventoryGUI: InventoryGUI) {
|
||||
registered -= inventoryGUI
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
object : Listener {
|
||||
@EventHandler
|
||||
private fun onInteract(event: InventoryInteractEvent) {
|
||||
println("interact geht hier")
|
||||
}
|
||||
}.register(kSpigot)
|
||||
|
||||
kSpigot.listen<InventoryClickEvent> {
|
||||
|
||||
val inv = registered.find { search -> search.isThisInv(it.inventory) } ?: return@listen
|
||||
val invPage = inv.currentPage ?: return@listen
|
||||
|
||||
val slot = inv.data.pages[invPage]?.slots?.get(it.slot)
|
||||
if (slot != null)
|
||||
slot.onClick(InventoryGUIClickEvent(it, inv))
|
||||
else
|
||||
it.isCancelled = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
registered.forEach { inv -> inv.bukkitInventory.viewers.forEach { it.closeInventory() } }
|
||||
registered.clear()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// EVENT
|
||||
|
||||
class InventoryGUIClickEvent(
|
||||
val bukkitEvent: InventoryClickEvent,
|
||||
val gui: InventoryGUI,
|
||||
)
|
||||
|
||||
/*
|
||||
* INVENTORY GUI
|
||||
*/
|
||||
|
||||
class InventoryGUIData(
|
||||
val plugin: KSpigot,
|
||||
val inventoryGUIType: InventoryGUIType<*>,
|
||||
val title: String?,
|
||||
val pages: Map<Int, InventoryGUIPage>
|
||||
)
|
||||
|
||||
abstract class InventoryGUI(
|
||||
val data: InventoryGUIData
|
||||
) {
|
||||
|
||||
var currentPage: Int? = null; protected set
|
||||
|
||||
abstract val bukkitInventory: Inventory
|
||||
|
||||
abstract fun loadPage(page: Int, offsetHorizontally: Int = 0, offsetVertically: Int = 0)
|
||||
|
||||
abstract fun isThisInv(inventory: Inventory): Boolean
|
||||
|
||||
fun register() = data.plugin.inventoryGUIHolder.register(this)
|
||||
fun unregister() = data.plugin.inventoryGUIHolder.unregister(this)
|
||||
|
||||
}
|
||||
|
||||
// Inventory GUI implementations
|
||||
|
||||
class InventoryGUIShared(
|
||||
inventoryGUIData: InventoryGUIData
|
||||
) : InventoryGUI(inventoryGUIData) {
|
||||
|
||||
override val bukkitInventory by lazy { data.inventoryGUIType.createBukkitInv(null, data.title) }
|
||||
|
||||
override fun isThisInv(inventory: Inventory) = inventory == bukkitInventory
|
||||
|
||||
override fun loadPage(page: Int, offsetHorizontally: Int, offsetVertically: Int) {
|
||||
|
||||
fun ifOffset(): Boolean = offsetHorizontally != 0 || offsetVertically != 0
|
||||
|
||||
currentPage = page
|
||||
|
||||
data.pages[page]?.slots?.let { slots ->
|
||||
|
||||
val dimensions = data.inventoryGUIType.dimensions
|
||||
|
||||
if (ifOffset()) {
|
||||
dimensions.invSlots.forEach {
|
||||
dimensions.invSlotsWithRealSlots[it.add(offsetHorizontally, offsetVertically)]?.let { slotToClear ->
|
||||
if (dimensions.realSlots.contains(slotToClear))
|
||||
bukkitInventory.clear(slotToClear)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bukkitInventory.clear()
|
||||
}
|
||||
|
||||
slots.forEach {
|
||||
val slot = it.value
|
||||
if (slot is InventoryGUIElement) {
|
||||
|
||||
if (ifOffset()) {
|
||||
val invSlot = InventorySlot.fromRealSlot(it.key, dimensions)
|
||||
if (invSlot != null) {
|
||||
val offsetSlot = invSlot.add(offsetHorizontally, offsetVertically).realSlotIn(dimensions)
|
||||
if (offsetSlot != null)
|
||||
bukkitInventory.setItem(offsetSlot, slot.inventoryGUIElementData.itemStack)
|
||||
}
|
||||
} else {
|
||||
bukkitInventory.setItem(it.key, slot.inventoryGUIElementData.itemStack)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUIPage(
|
||||
val slots: Map<Int, InventoryGUISlot>,
|
||||
transitionTo: InventoryGUIPageChangeEffect?,
|
||||
transitionFrom: InventoryGUIPageChangeEffect?
|
||||
) {
|
||||
val pageChangerTo = transitionTo?.let { InventoryGUIPageChanger(it) }
|
||||
val pageChangerFrom = transitionFrom?.let { InventoryGUIPageChanger(it) }
|
||||
}
|
@@ -0,0 +1,108 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import net.axay.kspigot.main.KSpigot
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
inline fun <T : ForInventory> KSpigot.inventoryGUI(
|
||||
type: InventoryGUIType<T>,
|
||||
builder: InventoryGUIBuilder<T>.() -> Unit,
|
||||
) = InventoryGUIBuilder(this, type).apply(builder).build()
|
||||
|
||||
class InventoryGUIBuilder<in T : ForInventory>(
|
||||
private val kSpigot: KSpigot,
|
||||
val type: InventoryGUIType<in T>
|
||||
) {
|
||||
|
||||
var title: String = ""
|
||||
|
||||
private val guiSlots = HashMap<Int, InventoryGUIPage>()
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun page(page: Int, builder: InventoryGUIPageBuilder<T>.() -> Unit) {
|
||||
guiSlots[page] = InventoryGUIPageBuilder(type, page).apply(builder).build()
|
||||
}
|
||||
|
||||
fun build() = InventoryGUIShared(InventoryGUIData(kSpigot, type, title, guiSlots)).apply { register() }
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUIPageBuilder<in T : ForInventory>(
|
||||
val type: InventoryGUIType<in T>,
|
||||
val page: Int
|
||||
) {
|
||||
|
||||
private val guiSlots = HashMap<Int, InventoryGUISlot>()
|
||||
|
||||
var transitionTo: InventoryGUIPageChangeEffect? = null
|
||||
var transitionFrom: InventoryGUIPageChangeEffect? = null
|
||||
|
||||
/**
|
||||
* A button is an item protected from any player
|
||||
* actions. If clicked, the specified [onClick]
|
||||
* function is invoked.
|
||||
*/
|
||||
fun button(slots: InventorySlotCompound<T>, itemStack: ItemStack, onClick: (InventoryGUIClickEvent) -> Unit)
|
||||
= slots(slots, InventoryGUIButton(InventoryGUIElementData(itemStack), onClick))
|
||||
|
||||
/**
|
||||
* An item protected from any player actions.
|
||||
* This is not a button.
|
||||
*/
|
||||
fun placeholder(slots: InventorySlotCompound<T>, itemStack: ItemStack)
|
||||
= slots(slots, InventoryGUIPlaceholder(InventoryGUIElementData(itemStack)))
|
||||
|
||||
/**
|
||||
* A free slot does not block any player actions.
|
||||
* The player can put items in this slot or take
|
||||
* items out of it.
|
||||
*/
|
||||
fun freeSlot(slots: InventorySlotCompound<T>)
|
||||
= slots(slots, InventoryGUIFreeSlot())
|
||||
|
||||
/**
|
||||
* This is a button which loads the specified
|
||||
* [toPage] if clicked.
|
||||
*/
|
||||
fun pageChanger(slots: InventorySlotCompound<T>, itemStack: ItemStack, toPage: Int, onChange: ((InventoryGUIClickEvent) -> Unit)? = null)
|
||||
= slots(slots, InventoryGUIButtonPageChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
InventoryGUIPageChangeCalculator.InventoryGUIConsistentPageCalculator(toPage),
|
||||
onChange
|
||||
))
|
||||
|
||||
/**
|
||||
* This button always tries to find the previous
|
||||
* page if clicked, and if a previous page
|
||||
* exists it is loaded.
|
||||
*/
|
||||
fun previousPage(slots: InventorySlotCompound<T>, itemStack: ItemStack, onChange: ((InventoryGUIClickEvent) -> Unit)? = null)
|
||||
= slots(slots, InventoryGUIButtonPageChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
InventoryGUIPageChangeCalculator.InventoryGUIPreviousPageCalculator,
|
||||
onChange
|
||||
))
|
||||
|
||||
/**
|
||||
* This button always tries to find the next
|
||||
* page if clicked, and if a next page
|
||||
* exists it is loaded.
|
||||
*/
|
||||
fun nextPage(slots: InventorySlotCompound<T>, itemStack: ItemStack, onChange: ((InventoryGUIClickEvent) -> Unit)? = null)
|
||||
= slots(slots, InventoryGUIButtonPageChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
InventoryGUIPageChangeCalculator.InventoryGUINextPageCalculator,
|
||||
onChange
|
||||
))
|
||||
|
||||
private fun slots(slots: InventorySlotCompound<T>, element: InventoryGUISlot)
|
||||
= slots.withGUIType(type).forEach { curSlot ->
|
||||
curSlot.realSlotIn(type.dimensions)?.let { guiSlots[it] = element }
|
||||
}
|
||||
|
||||
fun build() = InventoryGUIPage(guiSlots, transitionTo, transitionFrom)
|
||||
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
interface InventoryGUISlot {
|
||||
fun onClick(clickEvent: InventoryGUIClickEvent)
|
||||
}
|
||||
|
||||
// ELEMENT
|
||||
|
||||
class InventoryGUIElementData(
|
||||
val itemStack: ItemStack
|
||||
)
|
||||
|
||||
abstract class InventoryGUIElement(
|
||||
val inventoryGUIElementData: InventoryGUIElementData
|
||||
) : InventoryGUISlot
|
||||
|
||||
// Element implementations
|
||||
|
||||
open class InventoryGUIButton(
|
||||
inventoryGUIElementData: InventoryGUIElementData,
|
||||
val action: (InventoryGUIClickEvent) -> Unit,
|
||||
) : InventoryGUIElement(inventoryGUIElementData) {
|
||||
|
||||
override fun onClick(clickEvent: InventoryGUIClickEvent) {
|
||||
clickEvent.bukkitEvent.isCancelled = true
|
||||
action(clickEvent)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUIPlaceholder(
|
||||
inventoryGUIElementData: InventoryGUIElementData
|
||||
) : InventoryGUIElement(inventoryGUIElementData) {
|
||||
|
||||
override fun onClick(clickEvent: InventoryGUIClickEvent) {
|
||||
clickEvent.bukkitEvent.isCancelled = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUIButtonPageChange(
|
||||
inventoryGUIElementData: InventoryGUIElementData,
|
||||
calculator: InventoryGUIPageChangeCalculator,
|
||||
onChange: ((InventoryGUIClickEvent) -> Unit)?
|
||||
)
|
||||
: InventoryGUIButton(inventoryGUIElementData, {
|
||||
it.gui.currentPage?.let { currentPageInt ->
|
||||
|
||||
val newPageInt = calculator.calculateNewPage(currentPageInt, it.gui.data.pages.keys)
|
||||
if (newPageInt != null) {
|
||||
|
||||
onChange?.invoke(it)
|
||||
|
||||
val pageChanger
|
||||
= (it.gui.data.pages[newPageInt]?.pageChangerTo ?: it.gui.data.pages[currentPageInt]?.pageChangerFrom)
|
||||
?: InventoryGUIPageChanger(InventoryGUIPageChangeEffect.INSTANT)
|
||||
|
||||
pageChanger.changePage(it.gui, currentPageInt, newPageInt)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// FREE SLOT
|
||||
|
||||
class InventoryGUIFreeSlot : InventoryGUISlot {
|
||||
override fun onClick(clickEvent: InventoryGUIClickEvent) { /* do nothing */ }
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import net.axay.kspigot.runnables.task
|
||||
|
||||
abstract class InventoryGUIPageChangeCalculator {
|
||||
|
||||
abstract fun calculateNewPage(currentPage: Int, pages: Collection<Int>): Int?
|
||||
|
||||
object InventoryGUIPreviousPageCalculator : InventoryGUIPageChangeCalculator() {
|
||||
override fun calculateNewPage(currentPage: Int, pages: Collection<Int>) = pages.sortedDescending().find { it < currentPage }
|
||||
}
|
||||
|
||||
object InventoryGUINextPageCalculator : InventoryGUIPageChangeCalculator() {
|
||||
override fun calculateNewPage(currentPage: Int, pages: Collection<Int>) = pages.sorted().find { it > currentPage }
|
||||
}
|
||||
|
||||
class InventoryGUIConsistentPageCalculator(private val toPage: Int) : InventoryGUIPageChangeCalculator() {
|
||||
override fun calculateNewPage(currentPage: Int, pages: Collection<Int>) = toPage
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class InventoryGUIPageChangeEffect {
|
||||
INSTANT, SLIDE_HORIZONTALLY
|
||||
}
|
||||
|
||||
class InventoryGUIPageChanger(private val effect: InventoryGUIPageChangeEffect) {
|
||||
|
||||
fun changePage(gui: InventoryGUI, fromPage: Int, toPage: Int) {
|
||||
when (effect) {
|
||||
|
||||
InventoryGUIPageChangeEffect.SLIDE_HORIZONTALLY -> {
|
||||
|
||||
val width = gui.data.inventoryGUIType.dimensions.width
|
||||
|
||||
val ifInverted = fromPage >= toPage
|
||||
|
||||
var currentOffset = 1
|
||||
gui.data.plugin.task(
|
||||
sync = true,
|
||||
period = 1,
|
||||
howOften = width.toLong()
|
||||
) {
|
||||
|
||||
if (ifInverted) {
|
||||
gui.loadPage(fromPage, currentOffset)
|
||||
gui.loadPage(toPage, - (width - currentOffset))
|
||||
} else {
|
||||
gui.loadPage(fromPage, -currentOffset)
|
||||
gui.loadPage(toPage, width - currentOffset)
|
||||
}
|
||||
|
||||
currentOffset++
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InventoryGUIPageChangeEffect.INSTANT -> {
|
||||
|
||||
gui.loadPage(toPage)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
236
src/main/kotlin/net/axay/kspigot/inventory/InventoryGUISlots.kt
Normal file
236
src/main/kotlin/net/axay/kspigot/inventory/InventoryGUISlots.kt
Normal file
@@ -0,0 +1,236 @@
|
||||
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
// INVENTORY
|
||||
|
||||
data class InventoryDimensions(val width: Int, val heigth: Int) {
|
||||
|
||||
val invSlots by lazy {
|
||||
ArrayList<InventorySlot>().apply {
|
||||
(1 .. heigth).forEach { row ->
|
||||
(1 .. width).forEach { slotInRow ->
|
||||
this += InventorySlot(row, slotInRow)
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
val realSlots by lazy {
|
||||
ArrayList<Int>().apply {
|
||||
invSlots.forEach { curSlot ->
|
||||
curSlot.realSlotIn(this@InventoryDimensions)?.let { this += it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val invSlotsWithRealSlots by lazy {
|
||||
HashMap<InventorySlot, Int>().apply {
|
||||
invSlots.forEach { curSlot ->
|
||||
curSlot.realSlotIn(this@InventoryDimensions)?.let { this[curSlot] = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SLOTS
|
||||
|
||||
data class InventorySlot(val row: Int, val slotInRow: Int) : Comparable<InventorySlot> {
|
||||
|
||||
companion object {
|
||||
fun fromRealSlot(realSlot: Int, dimensions: InventoryDimensions)
|
||||
= dimensions.invSlotsWithRealSlots.toList().find { it.second == realSlot }?.first
|
||||
}
|
||||
|
||||
override fun compareTo(other: InventorySlot) = when {
|
||||
row > other.row -> 1
|
||||
row < other.row -> -1
|
||||
else -> when {
|
||||
slotInRow > other.slotInRow -> 1
|
||||
slotInRow < other.slotInRow -> -1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
fun realSlotIn(inventoryDimensions: InventoryDimensions): Int? {
|
||||
if (!isInDimension(inventoryDimensions)) return null
|
||||
val realRow = inventoryDimensions.heigth - (row - 1)
|
||||
val rowsUnder = if (realRow - 1 >= 0) realRow - 1 else 0
|
||||
return ((rowsUnder * inventoryDimensions.width) + slotInRow) - 1
|
||||
}
|
||||
|
||||
fun isInDimension(inventoryDimensions: InventoryDimensions)
|
||||
= (1 .. inventoryDimensions.width).contains(slotInRow) && (1 .. inventoryDimensions.heigth).contains(row)
|
||||
|
||||
fun add(offsetHorizontally: Int, offsetVertically: Int) = InventorySlot(
|
||||
row + offsetVertically,
|
||||
slotInRow + offsetHorizontally
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
interface InventorySlotCompound<out T : ForInventory> {
|
||||
fun withGUIType(invType: InventoryGUIType<in T>): Collection<InventorySlot>
|
||||
}
|
||||
|
||||
open class SingleInventorySlot<out T : ForInventory>(val inventorySlot: InventorySlot)
|
||||
: InventorySlotCompound<T> {
|
||||
|
||||
constructor(row: Int, slotInRow: Int) : this(InventorySlot(row, slotInRow))
|
||||
|
||||
private val slotAsList = listOf(inventorySlot)
|
||||
|
||||
override fun withGUIType(invType: InventoryGUIType<in T>) = slotAsList
|
||||
|
||||
}
|
||||
|
||||
enum class InventorySlotRangeType { LINEAR, RECTANGLE }
|
||||
|
||||
class InventorySlotRange<out T : ForInventory> (
|
||||
|
||||
startSlot: SingleInventorySlot<T>,
|
||||
endSlot: SingleInventorySlot<T>,
|
||||
|
||||
private val type: InventorySlotRangeType
|
||||
|
||||
) : InventorySlotCompound<T>, ClosedRange<InventorySlot> {
|
||||
|
||||
override val start: InventorySlot
|
||||
override val endInclusive: InventorySlot
|
||||
|
||||
init {
|
||||
if (startSlot.inventorySlot <= endSlot.inventorySlot) {
|
||||
start = startSlot.inventorySlot
|
||||
endInclusive = endSlot.inventorySlot
|
||||
} else {
|
||||
start = endSlot.inventorySlot
|
||||
endInclusive = startSlot.inventorySlot
|
||||
}
|
||||
}
|
||||
|
||||
override fun withGUIType(invType: InventoryGUIType<in T>)
|
||||
= LinkedHashSet<InventorySlot>().apply {
|
||||
when (type) {
|
||||
|
||||
InventorySlotRangeType.RECTANGLE -> {
|
||||
// all possible combinations between the two slots
|
||||
// -> form a rectangle
|
||||
for (row in start.row .. endInclusive.row)
|
||||
for (slotInRow in start.slotInRow .. endInclusive.slotInRow)
|
||||
this += InventorySlot(row, slotInRow)
|
||||
}
|
||||
|
||||
InventorySlotRangeType.LINEAR -> {
|
||||
if (endInclusive.row > start.row) {
|
||||
// from start --->| to end of row
|
||||
for (slotInRow in start.slotInRow .. invType.dimensions.width)
|
||||
this += InventorySlot(start.row, slotInRow)
|
||||
// all rows in between
|
||||
if (endInclusive.row > start.row + 1)
|
||||
for (row in start.row + 1 until endInclusive.row)
|
||||
for (slotInRow in 1 .. invType.dimensions.width)
|
||||
this += InventorySlot(row, slotInRow)
|
||||
// from start of row |----> to endInclusive
|
||||
for (slotInRow in 1 .. endInclusive.slotInRow)
|
||||
this += InventorySlot(endInclusive.row, slotInRow)
|
||||
} else if (endInclusive.row == start.row) {
|
||||
// from start ---> to endInclusive in the same row
|
||||
for (slotInRow in start.slotInRow .. endInclusive.slotInRow)
|
||||
this += InventorySlot(start.row, slotInRow)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SLOT RANGE OPERATOR FUNCTIONS
|
||||
|
||||
infix fun <T : ForInventory> SingleInventorySlot<T>.linTo(slot: SingleInventorySlot<T>)
|
||||
= InventorySlotRange(this, slot, InventorySlotRangeType.LINEAR)
|
||||
|
||||
infix fun <T : ForInventory> SingleInventorySlot<T>.rectTo(slot: SingleInventorySlot<T>)
|
||||
= InventorySlotRange(this, slot, InventorySlotRangeType.RECTANGLE)
|
||||
|
||||
// SLOT TYPE SAFETY
|
||||
|
||||
// ROWS
|
||||
interface ForRowOne : ForInventoryOneByNine, ForInventoryTwoByNine, ForInventoryThreeByNine, ForInventoryFourByNine, ForInventoryFiveByNine, ForInventorySixByNine
|
||||
interface ForRowTwo : ForInventoryTwoByNine, ForInventoryThreeByNine, ForInventoryFourByNine, ForInventoryFiveByNine, ForInventorySixByNine
|
||||
interface ForRowThree : ForInventoryThreeByNine, ForInventoryFourByNine, ForInventoryFiveByNine, ForInventorySixByNine
|
||||
interface ForRowFour : ForInventoryFourByNine, ForInventoryFiveByNine, ForInventorySixByNine
|
||||
interface ForRowFive : ForInventoryFiveByNine, ForInventorySixByNine
|
||||
interface ForRowSix : ForInventorySixByNine
|
||||
|
||||
// EDGE CASES:
|
||||
// ROW ONE
|
||||
interface ForRowOneSlotOneToThree : ForRowOne, ForInventoryOneByFive, ForInventoryThreeByThree
|
||||
interface ForRowOneSlotFourToFive : ForRowOne, ForInventoryOneByFive
|
||||
// ROW TWO
|
||||
interface ForRowTwoSlotOneToThree : ForRowTwo, ForInventoryThreeByThree
|
||||
// ROW THREE
|
||||
interface ForRowThreeSlotOneToThree : ForRowThree, ForInventoryThreeByThree
|
||||
|
||||
object Slots {
|
||||
// ROW ONE
|
||||
val RowOneSlotOne = SingleInventorySlot<ForRowOneSlotOneToThree>(1, 1)
|
||||
val RowOneSlotTwo = SingleInventorySlot<ForRowOneSlotOneToThree>(1, 2)
|
||||
val RowOneSlotThree = SingleInventorySlot<ForRowOneSlotOneToThree>(1, 3)
|
||||
val RowOneSlotFour = SingleInventorySlot<ForRowOneSlotFourToFive>(1, 4)
|
||||
val RowOneSlotFive = SingleInventorySlot<ForRowOneSlotFourToFive>(1, 5)
|
||||
val RowOneSlotSix = SingleInventorySlot<ForRowOne>(1, 6)
|
||||
val RowOneSlotSeven = SingleInventorySlot<ForRowOne>(1, 7)
|
||||
val RowOneSlotEight = SingleInventorySlot<ForRowOne>(1, 8)
|
||||
val RowOneSlotNine = SingleInventorySlot<ForRowOne>(1, 9)
|
||||
// ROW TWO
|
||||
val RowTwoSlotOne = SingleInventorySlot<ForRowTwoSlotOneToThree>(2, 1)
|
||||
val RowTwoSlotTwo = SingleInventorySlot<ForRowTwoSlotOneToThree>(2, 2)
|
||||
val RowTwoSlotThree = SingleInventorySlot<ForRowTwoSlotOneToThree>(2, 3)
|
||||
val RowTwoSlotFour = SingleInventorySlot<ForRowTwo>(2, 4)
|
||||
val RowTwoSlotFive = SingleInventorySlot<ForRowTwo>(2, 5)
|
||||
val RowTwoSlotSix = SingleInventorySlot<ForRowTwo>(2, 6)
|
||||
val RowTwoSlotSeven = SingleInventorySlot<ForRowTwo>(2, 7)
|
||||
val RowTwoSlotEight = SingleInventorySlot<ForRowTwo>(2, 8)
|
||||
val RowTwoSlotNine = SingleInventorySlot<ForRowTwo>(2, 9)
|
||||
// ROW THREE
|
||||
val RowThreeSlotOne = SingleInventorySlot<ForRowThreeSlotOneToThree>(3, 1)
|
||||
val RowThreeSlotTwo = SingleInventorySlot<ForRowThreeSlotOneToThree>(3, 2)
|
||||
val RowThreeSlotThree = SingleInventorySlot<ForRowThreeSlotOneToThree>(3, 3)
|
||||
val RowThreeSlotFour = SingleInventorySlot<ForRowThree>(3, 4)
|
||||
val RowThreeSlotFive = SingleInventorySlot<ForRowThree>(3, 5)
|
||||
val RowThreeSlotSix = SingleInventorySlot<ForRowThree>(3, 6)
|
||||
val RowThreeSlotSeven = SingleInventorySlot<ForRowThree>(3, 7)
|
||||
val RowThreeSlotEight = SingleInventorySlot<ForRowThree>(3, 8)
|
||||
val RowThreeSlotNine = SingleInventorySlot<ForRowThree>(3, 9)
|
||||
// ROW FOUR
|
||||
val RowFourSlotOne = SingleInventorySlot<ForRowFour>(4, 1)
|
||||
val RowFourSlotTwo = SingleInventorySlot<ForRowFour>(4, 2)
|
||||
val RowFourSlotThree = SingleInventorySlot<ForRowFour>(4, 3)
|
||||
val RowFourSlotFour = SingleInventorySlot<ForRowFour>(4, 4)
|
||||
val RowFourSlotFive = SingleInventorySlot<ForRowFour>(4, 5)
|
||||
val RowFourSlotSix = SingleInventorySlot<ForRowFour>(4, 6)
|
||||
val RowFourSlotSeven = SingleInventorySlot<ForRowFour>(4, 7)
|
||||
val RowFourSlotEight = SingleInventorySlot<ForRowFour>(4, 8)
|
||||
val RowFourSlotNine = SingleInventorySlot<ForRowFour>(4, 9)
|
||||
// ROW FIVE
|
||||
val RowFiveSlotOne = SingleInventorySlot<ForRowFive>(5, 1)
|
||||
val RowFiveSlotTwo = SingleInventorySlot<ForRowFive>(5, 2)
|
||||
val RowFiveSlotThree = SingleInventorySlot<ForRowFive>(5, 3)
|
||||
val RowFiveSlotFour = SingleInventorySlot<ForRowFive>(5, 4)
|
||||
val RowFiveSlotFive = SingleInventorySlot<ForRowFive>(5, 5)
|
||||
val RowFiveSlotSix = SingleInventorySlot<ForRowFive>(5, 6)
|
||||
val RowFiveSlotSeven = SingleInventorySlot<ForRowFive>(5, 7)
|
||||
val RowFiveSlotEight = SingleInventorySlot<ForRowFive>(5, 8)
|
||||
val RowFiveSlotNine = SingleInventorySlot<ForRowFive>(5, 9)
|
||||
// ROW SIX
|
||||
val RowSixSlotOne = SingleInventorySlot<ForRowSix>(6, 1)
|
||||
val RowSixSlotTwo = SingleInventorySlot<ForRowSix>(6, 2)
|
||||
val RowSixSlotThree = SingleInventorySlot<ForRowSix>(6, 3)
|
||||
val RowSixSlotFour = SingleInventorySlot<ForRowSix>(6, 4)
|
||||
val RowSixSlotFive = SingleInventorySlot<ForRowSix>(6, 5)
|
||||
val RowSixSlotSix = SingleInventorySlot<ForRowSix>(6, 6)
|
||||
val RowSixSlotSeven = SingleInventorySlot<ForRowSix>(6, 7)
|
||||
val RowSixSlotEight = SingleInventorySlot<ForRowSix>(6, 8)
|
||||
val RowSixSlotNine = SingleInventorySlot<ForRowSix>(6, 9)
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
|
||||
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.event.inventory.InventoryType
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.InventoryHolder
|
||||
|
||||
class InventoryGUIType<T : ForInventory>(
|
||||
val dimensions: InventoryDimensions,
|
||||
val bukkitType: InventoryType? = null
|
||||
) {
|
||||
|
||||
private val size = dimensions.width * dimensions.heigth
|
||||
|
||||
companion object {
|
||||
|
||||
val ONE_BY_NINE = InventoryGUIType<ForInventoryOneByNine>(InventoryDimensions(9, 1))
|
||||
val TWO_BY_NINE = InventoryGUIType<ForInventoryTwoByNine>(InventoryDimensions(9, 2))
|
||||
val THREE_BY_NINE = InventoryGUIType<ForInventoryThreeByNine>(InventoryDimensions(9, 3))
|
||||
val FOUR_BY_NINE = InventoryGUIType<ForInventoryFourByNine>(InventoryDimensions(9, 4))
|
||||
val FIVE_BY_NINE = InventoryGUIType<ForInventoryFiveByNine>(InventoryDimensions(9, 5))
|
||||
val SIX_BY_NINE = InventoryGUIType<ForInventorySixByNine>(InventoryDimensions(9, 6))
|
||||
val ONE_BY_FIVE = InventoryGUIType<ForInventoryOneByFive>(InventoryDimensions(5, 1), bukkitType = InventoryType.HOPPER)
|
||||
val THREE_BY_THREE = InventoryGUIType<ForInventoryThreeByThree>(InventoryDimensions(3, 3), bukkitType = InventoryType.DROPPER)
|
||||
|
||||
}
|
||||
|
||||
fun createBukkitInv(holder: InventoryHolder? = null, title: String? = null): Inventory {
|
||||
val realTitle = title ?: ""
|
||||
return when {
|
||||
bukkitType != null -> Bukkit.createInventory(holder, bukkitType, realTitle)
|
||||
else -> Bukkit.createInventory(holder, size, realTitle)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// INVENTORY TYPE SAFETY
|
||||
|
||||
interface ForInventory
|
||||
|
||||
interface ForInventoryOneByNine : ForInventory
|
||||
interface ForInventoryTwoByNine : ForInventory
|
||||
interface ForInventoryThreeByNine : ForInventory
|
||||
interface ForInventoryFourByNine : ForInventory
|
||||
interface ForInventoryFiveByNine : ForInventory
|
||||
interface ForInventorySixByNine : ForInventory
|
||||
interface ForInventoryThreeByThree : ForInventory
|
||||
interface ForInventoryOneByFive : ForInventory
|
||||
|
||||
interface ForEveryInventory
|
||||
: ForInventoryOneByNine, ForInventoryTwoByNine, ForInventoryThreeByNine,
|
||||
ForInventoryFourByNine, ForInventoryFiveByNine, ForInventorySixByNine,
|
||||
ForInventoryThreeByThree, ForInventoryOneByFive
|
@@ -1,5 +1,6 @@
|
||||
package net.axay.kspigot.main
|
||||
|
||||
import net.axay.kspigot.inventory.InventoryGUIHolder
|
||||
import net.axay.kspigot.kotlinextensions.closeIfInitialized
|
||||
import net.axay.kspigot.runnables.KRunnableHolder
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
@@ -21,8 +22,10 @@ abstract class KSpigot : JavaPlugin() {
|
||||
|
||||
// lazy properties
|
||||
private val kRunnableHolderProperty = lazy { KRunnableHolder() }
|
||||
private val inventoryGUIHolderProperty = lazy { InventoryGUIHolder(this) }
|
||||
|
||||
val kRunnableHolder by kRunnableHolderProperty
|
||||
val inventoryGUIHolder by inventoryGUIHolderProperty
|
||||
|
||||
/**
|
||||
* Called when the plugin was loaded
|
||||
@@ -53,6 +56,7 @@ abstract class KSpigot : JavaPlugin() {
|
||||
|
||||
// avoid unnecessary load of lazy properties
|
||||
kRunnableHolderProperty.closeIfInitialized()
|
||||
inventoryGUIHolderProperty.closeIfInitialized()
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user