Skip to content

Commit

Permalink
Merge pull request #38 from StaticFX/feature/left_right_click_listeners
Browse files Browse the repository at this point in the history
add listener on kitem for left and right clicked events
  • Loading branch information
StaticFX authored Aug 21, 2024
2 parents 9fbd471 + 415a1af commit 59e819a
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 37 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM gradle:8.3.0 as build
FROM gradle:8.7.0 as build

WORKDIR /app

COPY . .

RUN --mount=type=cache,target=/root/.gradle gradle build --parallel --no-daemon

FROM openjdk:20-slim as serverBuilder
FROM openjdk:21-slim as serverBuilder

WORKDIR /app

Expand Down
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
osshrToken=3gSBY7kZ
osshrPassword=LPx4MlixFR1eJ21Oe3g1CAtmVl6vFfoCQW0Fw+VNzYdc
7 changes: 7 additions & 0 deletions src/main/kotlin/de/staticred/kia/KIA.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package de.staticred.kia
import de.staticred.kia.events.InventoryClickListener
import de.staticred.kia.events.InventoryDragItemListener
import de.staticred.kia.events.InventoryOpenCloseListener
import de.staticred.kia.events.PlayerInteractListener
import de.staticred.kia.example.InventoryExample
import org.bukkit.Bukkit
import org.bukkit.plugin.java.JavaPlugin
Expand All @@ -11,11 +12,16 @@ import org.bukkit.plugin.java.JavaPlugin
* Plugin class of KIA
*/
object KIA {
/**
* The paper plugin kia is attached to
*/
lateinit var plugin: JavaPlugin
private set

/**
* Create new loaded instance of KIA
* @param javaPlugin plugin instance KIA will use to attach its eventlisteners
* @param exampleCommand by default false. If true, will register the /kia example command
*/
fun create(
javaPlugin: JavaPlugin,
Expand All @@ -37,5 +43,6 @@ object KIA {
plugin.server.pluginManager.registerEvents(InventoryClickListener(), plugin)
plugin.server.pluginManager.registerEvents(InventoryOpenCloseListener(), plugin)
plugin.server.pluginManager.registerEvents(InventoryDragItemListener(), plugin)
plugin.server.pluginManager.registerEvents(PlayerInteractListener(), plugin)
}
}
25 changes: 25 additions & 0 deletions src/main/kotlin/de/staticred/kia/events/PlayerInteractListener.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.staticred.kia.events

import de.staticred.kia.inventory.item.RegisteredKItem
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.block.Action
import org.bukkit.event.player.PlayerInteractEvent

class PlayerInteractListener : Listener {
@EventHandler
fun onPlayerInteract(event: PlayerInteractEvent) {
val item = event.item ?: return
val player = event.player

if (item !is RegisteredKItem) return

if (event.action == Action.LEFT_CLICK_AIR || event.action == Action.LEFT_CLICK_BLOCK) {
item.leftClicked(player, event)
}

if (event.action == Action.RIGHT_CLICK_AIR || event.action == Action.RIGHT_CLICK_BLOCK) {
item.rightClicked(player, event)
}
}
}
91 changes: 62 additions & 29 deletions src/main/kotlin/de/staticred/kia/example/InventoryExample.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import de.staticred.kia.inventory.builder.animation
import de.staticred.kia.inventory.builder.kInventory
import de.staticred.kia.inventory.builder.kItem
import de.staticred.kia.inventory.extensions.openInventory
import de.staticred.kia.inventory.extensions.setHotbarItem
import de.staticred.kia.util.rows
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.event.ClickEvent
import net.kyori.adventure.text.minimessage.MiniMessage
import org.bukkit.Material
Expand All @@ -14,47 +16,78 @@ import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType
import java.util.concurrent.TimeUnit

class InventoryExample: Command("kia") {


override fun execute(sender: CommandSender, command: String, args: Array<out String>?): Boolean {
class InventoryExample : Command("kia") {
override fun execute(
sender: CommandSender,
command: String,
args: Array<out String>?,
): Boolean {
if (sender !is Player) return false
val miniMessage = MiniMessage.miniMessage()

val text = miniMessage.deserialize("<dark_gray><st>---------------------------------</st></dark_gray> ")
.append { miniMessage.deserialize("\n<gradient:#B125EA:#7F52FF>KIA - Kotlin Inventory API</gradient>") }
.append { miniMessage.deserialize("\n<color:#E24462>GitHub: https://github.com/StaticFX/KIA </color>") }
.append { miniMessage.deserialize("\n<color:#E24462>By: StaticFX / Devin </color>") }
.append { miniMessage.deserialize("\n<color:#E24462><underlined>Click to open example inventory</underlined></color>") }.clickEvent(
ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/kia inv"))
.append { miniMessage.deserialize("\n<dark_gray><st>---------------------------------</st></dark_gray>") }

val inventory = kInventory(sender, 3.rows, InventoryType.CHEST) {
title = miniMessage.deserialize("<gradient:#B125EA:#7F52FF>KIA - Kotlin Inventory API</gradient>")

openingAnimation = animation(27, 50, TimeUnit.MILLISECONDS) {
onAnimationFrame { frame ->
setItem(frame, kItem(Material.GRAY_STAINED_GLASS_PANE) {
setDisplayName(miniMessage.deserialize("<black>|</black>"))
} )
}

onEnd {
setItem(1, 4, kItem(Material.PAPER) {
setDisplayName(miniMessage.deserialize("<rainbow:!>Thanks for using KIA!</rainbow>"))
})
}
val text =
miniMessage
.deserialize("<dark_gray><st>---------------------------------</st></dark_gray> ")
.append { miniMessage.deserialize("\n<gradient:#B125EA:#7F52FF>KIA - Kotlin Inventory API</gradient>") }
.append { miniMessage.deserialize("\n<color:#E24462>GitHub: https://github.com/StaticFX/KIA </color>") }
.append { miniMessage.deserialize("\n<color:#E24462>By: StaticFX / Devin </color>") }
.append {
miniMessage.deserialize(
"\n<color:#E24462><underlined>Click to open example inventory</underlined></color>",
)
}.clickEvent(
ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/kia inv"),
).append { miniMessage.deserialize("\n<dark_gray><st>---------------------------------</st></dark_gray>") }

val inventory =
kInventory(sender, 3.rows, InventoryType.CHEST) {
title = miniMessage.deserialize("<gradient:#B125EA:#7F52FF>KIA - Kotlin Inventory API</gradient>")

openingAnimation =
animation(27, 50, TimeUnit.MILLISECONDS) {
onAnimationFrame { frame ->
setItem(
frame,
kItem(Material.GRAY_STAINED_GLASS_PANE) {
setDisplayName(miniMessage.deserialize("<black>|</black>"))
},
)
}

onEnd {
setItem(
1,
4,
kItem(Material.PAPER) {
setDisplayName(miniMessage.deserialize("<rainbow:!>Thanks for using KIA!</rainbow>"))
},
)
}
}
}
}

if (args != null && args.isNotEmpty()) {
if (args[0] == "inv") {
sender.openInventory(inventory)
} else if (args[0] == "items") {
val item =
kItem(Material.PAPER) {
setDisplayName(Component.text("Left or right click me"))
onLeftClick { clicker, _ ->
clicker.sendMessage("You left clicked")
}

onRightClick { clicker, _ ->
clicker.sendMessage("You right clicked")
}
}

sender.setHotbarItem(0, item)
}
} else {
sender.sendMessage(text)
}

return true
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.staticred.kia.inventory.extensions

import de.staticred.kia.inventory.KInventory
import de.staticred.kia.inventory.item.KItem
import org.bukkit.entity.Player

/**
Expand All @@ -15,4 +16,21 @@ fun Player.openInventory(inventory: KInventory) {
}

openInventory(inventory.toBukkitInventory())
}
}

/**
* Sets the given item at the given slot in the players hotbar
* @param slot number between 0-8 referring to the players hotbar
* @param item the item to set
* @throws IllegalArgumentException when slot is out of bounds
*/
fun Player.setHotbarItem(
slot: Int,
item: KItem,
) {
if (slot !in 0..8) {
throw IllegalArgumentException("Slot must be between 0 and 8")
}

inventory.setItem(slot, item.toItemStack())
}
65 changes: 60 additions & 5 deletions src/main/kotlin/de/staticred/kia/inventory/item/RegisteredKItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@ package de.staticred.kia.inventory.item
import de.staticred.kia.inventory.KInventory
import de.staticred.kia.util.Identifiable
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerInteractEvent
import java.util.*

/**
* Models a registered KItems
*
* Registered KItems will, when initialized, add a UUID to their NBT tags, so they can be identified later again.
* Registered KItems will, when initialized
* add a UUID to their NBT tags, so they can be identified later again.
*
* This allows the item to be tracked inside bukkit events, which allows
* for event listeners on this item
*
* @See ItemManager
* @since 1.0.2
*/
interface RegisteredKItem: KItem, Identifiable<UUID> {

interface RegisteredKItem :
KItem,
Identifiable<UUID> {
/**
* Whether the item can be clicked while inside an animation or not
*/
Expand All @@ -35,5 +41,54 @@ interface RegisteredKItem: KItem, Identifiable<UUID> {
* @param player who clicked the item
* @param kInventory the inventory the item is inside
*/
fun clicked(player: Player, kInventory: KInventory)
}
fun clicked(
player: Player,
kInventory: KInventory,
)

/**
* Executed when the player left-clicked with this item
*
* This can occur outside an inventory, therefore the parent might be null
* @see parent
*
* The code block will receive a [PlayerInteractEvent] which is validated
* to have a valid item and a valid click.
*
* @param action code block which is executed
*/
fun onLeftClick(action: RegisteredKItem.(Player, PlayerInteractEvent) -> Unit)

/**
* Executed when the player right-clicked with this item
*
* This can occur outside an inventory, therefore the parent might be null
* @see parent
*
* The code block will receive a [PlayerInteractEvent] which is validated
* to have a valid item and a valid click.
*
* @param action code block which is executed
*/
fun onRightClick(action: RegisteredKItem.(Player, PlayerInteractEvent) -> Unit)

/**
* When the item has been left-clicked by a player
* @param player who clicked
* @param event the bukkit event
*/
fun leftClicked(
player: Player,
event: PlayerInteractEvent,
)

/**
* When the item has been right-clicked by a player
* @param player who clicked
* @param event the bukkit event
*/
fun rightClicked(
player: Player,
event: PlayerInteractEvent,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import de.staticred.kia.inventory.KInventory
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType
import java.util.*
Expand All @@ -25,6 +26,8 @@ class RegisteredKItemImpl(
override var clickableInAnimation: Boolean = true

private val clickListeners = mutableListOf<KInventory.(RegisteredKItem, Player) -> Unit>()
private val leftClickListeners = mutableListOf<RegisteredKItem.(Player, PlayerInteractEvent) -> Unit>()
private val rightClickListeners = mutableListOf<RegisteredKItem.(Player, PlayerInteractEvent) -> Unit>()

companion object {
/**
Expand Down Expand Up @@ -70,5 +73,27 @@ class RegisteredKItemImpl(
parent?.let { clickListeners.forEach { listener -> listener(kInventory, this, player) } }
}

override fun onLeftClick(action: RegisteredKItem.(Player, PlayerInteractEvent) -> Unit) {
leftClickListeners += action
}

override fun onRightClick(action: RegisteredKItem.(Player, PlayerInteractEvent) -> Unit) {
rightClickListeners += action
}

override fun leftClicked(
player: Player,
event: PlayerInteractEvent,
) {
leftClickListeners.forEach { it(this, player, event) }
}

override fun rightClicked(
player: Player,
event: PlayerInteractEvent,
) {
rightClickListeners.forEach { it(this, player, event) }
}

override fun hasID(): Boolean = true
}

0 comments on commit 59e819a

Please sign in to comment.