Beginning of InventoryGUI

This commit is contained in:
bluefireoly
2020-09-27 00:44:00 +02:00
parent f856b8d227
commit 9fc0f60fe0
7 changed files with 709 additions and 0 deletions

View 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) }
}

View File

@@ -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)
}

View File

@@ -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 */ }
}

View File

@@ -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)
}
}
}
}

View 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)
}

View File

@@ -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

View File

@@ -1,5 +1,6 @@
package net.axay.kspigot.main package net.axay.kspigot.main
import net.axay.kspigot.inventory.InventoryGUIHolder
import net.axay.kspigot.kotlinextensions.closeIfInitialized import net.axay.kspigot.kotlinextensions.closeIfInitialized
import net.axay.kspigot.runnables.KRunnableHolder import net.axay.kspigot.runnables.KRunnableHolder
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
@@ -21,8 +22,10 @@ abstract class KSpigot : JavaPlugin() {
// lazy properties // lazy properties
private val kRunnableHolderProperty = lazy { KRunnableHolder() } private val kRunnableHolderProperty = lazy { KRunnableHolder() }
private val inventoryGUIHolderProperty = lazy { InventoryGUIHolder(this) }
val kRunnableHolder by kRunnableHolderProperty val kRunnableHolder by kRunnableHolderProperty
val inventoryGUIHolder by inventoryGUIHolderProperty
/** /**
* Called when the plugin was loaded * Called when the plugin was loaded
@@ -53,6 +56,7 @@ abstract class KSpigot : JavaPlugin() {
// avoid unnecessary load of lazy properties // avoid unnecessary load of lazy properties
kRunnableHolderProperty.closeIfInitialized() kRunnableHolderProperty.closeIfInitialized()
inventoryGUIHolderProperty.closeIfInitialized()
} }