Add kit inventory

This commit is contained in:
TDSTOS
2025-12-11 19:47:45 +01:00
parent c741739cdd
commit 1acb5681fc
5 changed files with 271 additions and 104 deletions

View File

@@ -18,12 +18,14 @@ class KitsCommand(
label: String, label: String,
args: Array<out String> args: Array<out String>
): Boolean { ): Boolean {
if (sender !is Player) { if ( sender !is Player )
{
sender.sendMessage("§cOnly players can use this command.") sender.sendMessage("§cOnly players can use this command.")
return true return true
} }
kitInventoryManager.openKitInventory(sender, 1) kitInventoryManager.openKitInventory( sender, 1 )
return true return true
} }
} }

View File

@@ -3,13 +3,18 @@ package club.mcscrims.speedhg.kit
import org.bukkit.inventory.Inventory import org.bukkit.inventory.Inventory
import org.bukkit.inventory.InventoryHolder import org.bukkit.inventory.InventoryHolder
class KitInventoryHolder(val page: Int) : InventoryHolder { class KitInventoryHolder(
val page: Int
) : InventoryHolder {
private lateinit var inventory: Inventory private lateinit var inventory: Inventory
override fun getInventory(): Inventory = inventory override fun getInventory(): Inventory = inventory
fun setInventory(inventory: Inventory) { fun setInventory(
inventory: Inventory
) {
this.inventory = inventory this.inventory = inventory
} }
} }

View File

@@ -1,6 +1,7 @@
package club.mcscrims.speedhg.kit package club.mcscrims.speedhg.kit
import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.SpeedHG.Companion.content
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.Sound import org.bukkit.Sound
import org.bukkit.entity.Player import org.bukkit.entity.Player
@@ -16,46 +17,49 @@ class KitInventoryListener(
) : Listener { ) : Listener {
@EventHandler @EventHandler
fun onInventoryClick(event: InventoryClickEvent) { fun onInventoryClick(
event: InventoryClickEvent
) {
val holder = event.inventory.holder val holder = event.inventory.holder
if (holder !is KitInventoryHolder) { if ( holder !is KitInventoryHolder )
return return
}
event.isCancelled = true event.isCancelled = true
val player = event.whoClicked as? Player ?: return val player = event.whoClicked as? Player ?: return
val clickedItem = event.currentItem ?: return val clickedItem = event.currentItem ?: return
if (clickedItem.type == Material.AIR) { if ( clickedItem.type == Material.AIR )
return return
}
when (event.rawSlot) { when( event.rawSlot )
{
45 -> { 45 -> {
if (holder.page > 1) { if ( holder.page > 1 )
player.playSound(player.location, Sound.UI_BUTTON_CLICK, 1f, 1f) {
kitInventoryManager.openKitInventory(player, holder.page - 1) player.playSound( player.location, Sound.UI_BUTTON_CLICK, 1f, 1f )
kitInventoryManager.openKitInventory( player, holder.page - 1 )
} }
} }
49 -> { 49 -> {
player.playSound(player.location, Sound.UI_BUTTON_CLICK, 1f, 0.8f) player.playSound( player.location, Sound.UI_BUTTON_CLICK, 1f, 0.8f )
player.closeInventory() player.closeInventory()
} }
53 -> { 53 -> {
val totalKits = kitManager.getAllKits().size val totalKits = kitManager.getAllKits().size
val totalPages = (totalKits + 27) / 28 val totalPages = ( totalKits + 27 ) / 28
if (holder.page < totalPages) { if ( holder.page < totalPages )
player.playSound(player.location, Sound.UI_BUTTON_CLICK, 1f, 1f) {
kitInventoryManager.openKitInventory(player, holder.page + 1) player.playSound( player.location, Sound.UI_BUTTON_CLICK, 1f, 1f )
kitInventoryManager.openKitInventory( player, holder.page + 1 )
} }
} }
in 10..43 -> { in 10..43 -> {
val allKits = kitManager.getAllKits().toList() val allKits = kitManager.getAllKits().toList()
val startIndex = (holder.page - 1) * 28 val startIndex = ( holder.page - 1 ) * 28
val endIndex = (startIndex + 28).coerceAtMost(allKits.size) val endIndex = ( startIndex + 28 ).coerceAtMost( allKits.size )
val kitsOnPage = allKits.subList(startIndex, endIndex) val kitsOnPage = allKits.subList( startIndex, endIndex )
val kitSlots = listOf( val kitSlots = listOf(
10, 11, 12, 13, 14, 15, 16, 10, 11, 12, 13, 14, 15, 16,
@@ -64,20 +68,22 @@ class KitInventoryListener(
37, 38, 39, 40, 41, 42, 43 37, 38, 39, 40, 41, 42, 43
) )
val slotIndex = kitSlots.indexOf(event.rawSlot) val slotIndex = kitSlots.indexOf( event.rawSlot )
if (slotIndex != -1 && slotIndex < kitsOnPage.size) { if ( slotIndex != -1 && slotIndex < kitsOnPage.size )
{
val selectedKit = kitsOnPage[slotIndex] val selectedKit = kitsOnPage[slotIndex]
if (kitManager.selectKit(player, selectedKit.id)) { if (kitManager.selectKit( player, selectedKit.id ))
player.playSound(player.location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1.2f) {
player.playSound( player.location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1.2f )
plugin.chatManager.sendMessage( plugin.chatManager.sendMessage(
player, player,
"kits.selected", "kits.selected",
"{kit}" to selectedKit.displayName.content() "{kit}" to selectedKit.displayName.content()
) )
kitInventoryManager.openKitInventory(player, holder.page) kitInventoryManager.openKitInventory( player, holder.page )
} else { } else {
player.playSound(player.location, Sound.ENTITY_VILLAGER_NO, 1f, 1f) player.playSound( player.location, Sound.ENTITY_VILLAGER_NO, 1f, 1f )
} }
} }
} }
@@ -85,11 +91,13 @@ class KitInventoryListener(
} }
@EventHandler @EventHandler
fun onInventoryDrag(event: InventoryDragEvent) { fun onInventoryDrag(
event: InventoryDragEvent
) {
val holder = event.inventory.holder val holder = event.inventory.holder
if (holder is KitInventoryHolder) { if ( holder is KitInventoryHolder )
event.isCancelled = true event.isCancelled = true
}
} }
} }

View File

@@ -1,7 +1,7 @@
package club.mcscrims.speedhg.kit package club.mcscrims.speedhg.kit
import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.SpeedHG.Companion.content import kotlinx.coroutines.runBlocking
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.text.format.TextDecoration import net.kyori.adventure.text.format.TextDecoration
@@ -11,7 +11,6 @@ import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemFlag import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
class KitInventoryManager( class KitInventoryManager(
private val plugin: SpeedHG, private val plugin: SpeedHG,
@@ -21,36 +20,39 @@ class KitInventoryManager(
private val kitsPerPage = 28 private val kitsPerPage = 28
private val rows = 6 private val rows = 6
fun openKitInventory(player: Player, page: Int = 1) { fun openKitInventory(
player: Player,
page: Int = 1
) {
val allKits = kitManager.getAllKits().toList() val allKits = kitManager.getAllKits().toList()
val totalPages = (allKits.size + kitsPerPage - 1) / kitsPerPage val totalPages = ( allKits.size + kitsPerPage - 1 ) / kitsPerPage
val validPage = page.coerceIn(1, totalPages.coerceAtLeast(1)) val validPage = page.coerceIn( 1, totalPages.coerceAtLeast( 1 ))
val holder = KitInventoryHolder(validPage) val holder = KitInventoryHolder( validPage )
val title = Component.text("Kits - Page $validPage/$totalPages") val title = Component.text("Kits - Page $validPage/$totalPages")
.color(NamedTextColor.DARK_PURPLE) .color( NamedTextColor.DARK_PURPLE )
.decoration(TextDecoration.BOLD, true) .decoration( TextDecoration.BOLD, true )
val inventory = Bukkit.createInventory(holder, rows * 9, title) val inventory = Bukkit.createInventory( holder, rows * 9, title )
holder.setInventory(inventory) holder.setInventory( inventory )
fillBorder(inventory) fillBorder( inventory )
fillKits(inventory, allKits, validPage, player) fillKits( inventory, allKits, validPage, player )
fillNavigationItems(inventory, validPage, totalPages) fillNavigationItems( inventory, validPage, totalPages )
player.openInventory(inventory) player.openInventory( inventory )
} }
private fun fillBorder(inventory: org.bukkit.inventory.Inventory) { private fun fillBorder(
inventory: org.bukkit.inventory.Inventory
) {
val borderItem = createBorderItem() val borderItem = createBorderItem()
for (i in 0..8) { for ( i in 0..8 )
inventory.setItem(i, borderItem) inventory.setItem( i, borderItem )
}
for (i in 45..53) { for ( i in 45..53 )
inventory.setItem(i, borderItem) inventory.setItem( i, borderItem )
}
} }
private fun fillKits( private fun fillKits(
@@ -59,11 +61,11 @@ class KitInventoryManager(
page: Int, page: Int,
player: Player player: Player
) { ) {
val startIndex = (page - 1) * kitsPerPage val startIndex = ( page - 1 ) * kitsPerPage
val endIndex = (startIndex + kitsPerPage).coerceAtMost(allKits.size) val endIndex = ( startIndex + kitsPerPage ).coerceAtMost( allKits.size )
val kitsOnPage = allKits.subList(startIndex, endIndex) val kitsOnPage = allKits.subList( startIndex, endIndex )
val selectedKit = kitManager.getSelectedKit(player) val selectedKit = kitManager.getSelectedKit( player )
val kitSlots = listOf( val kitSlots = listOf(
10, 11, 12, 13, 14, 15, 16, 10, 11, 12, 13, 14, 15, 16,
@@ -73,10 +75,11 @@ class KitInventoryManager(
) )
kitsOnPage.forEachIndexed { index, kit -> kitsOnPage.forEachIndexed { index, kit ->
if (index < kitSlots.size) { if ( index < kitSlots.size )
{
val isSelected = selectedKit?.id == kit.id val isSelected = selectedKit?.id == kit.id
val kitItem = createKitItem(kit, isSelected, player) val kitItem = createKitItem( kit, isSelected, player )
inventory.setItem(kitSlots[index], kitItem) inventory.setItem(kitSlots[ index ], kitItem )
} }
} }
} }
@@ -86,116 +89,135 @@ class KitInventoryManager(
page: Int, page: Int,
totalPages: Int totalPages: Int
) { ) {
if (page > 1) { if ( page > 1 )
inventory.setItem(45, createPreviousPageItem()) inventory.setItem( 45, createPreviousPageItem() )
}
inventory.setItem(49, createCloseItem()) inventory.setItem( 49, createCloseItem() )
if (page < totalPages) { if ( page < totalPages )
inventory.setItem(53, createNextPageItem()) inventory.setItem( 53, createNextPageItem() )
}
} }
private fun createBorderItem(): ItemStack { private fun createBorderItem(): ItemStack
val item = ItemStack(Material.GRAY_STAINED_GLASS_PANE) {
val item = ItemStack( Material.GRAY_STAINED_GLASS_PANE )
val meta = item.itemMeta val meta = item.itemMeta
meta.displayName(Component.text(" ")) meta.displayName(Component.text( " " ))
item.itemMeta = meta item.itemMeta = meta
return item return item
} }
private fun createKitItem(kit: AbstractKit, isSelected: Boolean, player: Player): ItemStack { private fun createKitItem(
val item = ItemStack(kit.icon) kit: AbstractKit,
isSelected: Boolean,
player: Player
): ItemStack
{
val item = ItemStack( kit.icon )
val meta = item.itemMeta val meta = item.itemMeta
meta.displayName(kit.displayName.decoration(TextDecoration.ITALIC, false)) meta.displayName(kit.displayName.decoration( TextDecoration.ITALIC, false ))
val lore = mutableListOf<Component>() val lore = mutableListOf<Component>()
if (isSelected) { if ( isSelected ) {
lore.add( lore.add(
Component.text("✔ Currently Selected") Component.text("✔ Currently Selected")
.color(NamedTextColor.GREEN) .color( NamedTextColor.GREEN )
.decoration(TextDecoration.ITALIC, false) .decoration( TextDecoration.ITALIC, false )
) )
} else { } else {
lore.add( lore.add(
Component.text("Click to select") Component.text("Click to select")
.color(NamedTextColor.YELLOW) .color( NamedTextColor.YELLOW )
.decoration(TextDecoration.ITALIC, false) .decoration( TextDecoration.ITALIC, false )
) )
} }
lore.add(Component.empty()) lore.add( Component.empty() )
kit.description.forEach { line -> kit.description.forEach { line ->
lore.add( lore.add(
Component.text(line) line.color( NamedTextColor.GRAY )
.color(NamedTextColor.GRAY) .decoration( TextDecoration.ITALIC, false )
.decoration(TextDecoration.ITALIC, false)
) )
} }
if (canUseKit(player, kit)) { if (canUseKit( player, kit )) {
if (isSelected) { if ( isSelected )
meta.addEnchant(Enchantment.UNBREAKING, 1, true) {
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS) meta.addEnchant( Enchantment.UNBREAKING, 1, true )
meta.addItemFlags( ItemFlag.HIDE_ENCHANTS )
} }
} else { } else {
lore.add(Component.empty()) lore.add( Component.empty() )
lore.add( lore.add(
Component.text("⚠ Locked") Component.text("⚠ Locked")
.color(NamedTextColor.RED) .color( NamedTextColor.RED )
.decoration(TextDecoration.ITALIC, false) .decoration( TextDecoration.ITALIC, false )
.decoration(TextDecoration.BOLD, true) .decoration( TextDecoration.BOLD, true )
) )
} }
meta.lore(lore) meta.lore( lore )
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES) meta.addItemFlags( ItemFlag.HIDE_ATTRIBUTES )
item.itemMeta = meta item.itemMeta = meta
return item return item
} }
private fun createPreviousPageItem(): ItemStack { private fun createPreviousPageItem(): ItemStack
val item = ItemStack(Material.ARROW) {
val item = ItemStack( Material.ARROW )
val meta = item.itemMeta val meta = item.itemMeta
meta.displayName( meta.displayName(
Component.text("← Previous Page") Component.text("← Previous Page")
.color(NamedTextColor.YELLOW) .color( NamedTextColor.YELLOW )
.decoration(TextDecoration.ITALIC, false) .decoration( TextDecoration.ITALIC, false )
) )
item.itemMeta = meta item.itemMeta = meta
return item return item
} }
private fun createNextPageItem(): ItemStack { private fun createNextPageItem(): ItemStack
val item = ItemStack(Material.ARROW) {
val item = ItemStack( Material.ARROW )
val meta = item.itemMeta val meta = item.itemMeta
meta.displayName( meta.displayName(
Component.text("Next Page →") Component.text("Next Page →")
.color(NamedTextColor.YELLOW) .color( NamedTextColor.YELLOW )
.decoration(TextDecoration.ITALIC, false) .decoration( TextDecoration.ITALIC, false )
) )
item.itemMeta = meta item.itemMeta = meta
return item return item
} }
private fun createCloseItem(): ItemStack { private fun createCloseItem(): ItemStack
val item = ItemStack(Material.BARRIER) {
val item = ItemStack( Material.BARRIER )
val meta = item.itemMeta val meta = item.itemMeta
meta.displayName( meta.displayName(
Component.text("Close") Component.text("Close")
.color(NamedTextColor.RED) .color( NamedTextColor.RED )
.decoration(TextDecoration.ITALIC, false) .decoration( TextDecoration.ITALIC, false )
) )
item.itemMeta = meta item.itemMeta = meta
return item return item
} }
private fun canUseKit(player: Player, kit: AbstractKit): Boolean { private fun canUseKit(
return true player: Player,
kit: AbstractKit
): Boolean
{
val unlockedKits = mutableListOf<String>()
runBlocking {
val kitPlayer = plugin.playerRepository.findByUuid( player.uniqueId )
if ( kitPlayer != null ) unlockedKits.addAll( kitPlayer.unlockedKits )
}
return unlockedKits.contains( kit.id )
} }
} }

View File

@@ -4,12 +4,16 @@ import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.game.GameManager import club.mcscrims.speedhg.game.GameManager
import club.mcscrims.speedhg.game.GameStateTypes import club.mcscrims.speedhg.game.GameStateTypes
import club.mcscrims.speedhg.util.DirectionUtil import club.mcscrims.speedhg.util.DirectionUtil
import club.mcscrims.spigot.chat.getDisplayName
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.Sound import org.bukkit.Sound
import org.bukkit.attribute.Attribute import org.bukkit.attribute.Attribute
import org.bukkit.entity.Entity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.entity.Projectile
import org.bukkit.entity.Tameable
import org.bukkit.event.Event import org.bukkit.event.Event
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
@@ -22,6 +26,7 @@ import org.bukkit.event.enchantment.EnchantItemEvent
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.entity.EntityDamageEvent import org.bukkit.event.entity.EntityDamageEvent
import org.bukkit.event.entity.FoodLevelChangeEvent import org.bukkit.event.entity.FoodLevelChangeEvent
import org.bukkit.event.entity.PlayerDeathEvent
import org.bukkit.event.inventory.ClickType import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.CraftItemEvent import org.bukkit.event.inventory.CraftItemEvent
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
@@ -542,4 +547,129 @@ class GameStateListener(
event.isCancelled = true event.isCancelled = true
} }
enum class DeathType {
PLAYER,
ENTITY,
WORLD
}
private val playerDeathMessages: Int = plugin.messageConfig.data.deathMessages["player"]!!.size
private val entityDeathMessages: Int = plugin.messageConfig.data.deathMessages["entity"]!!.size
private val worldDeathMessages: Int = plugin.messageConfig.data.deathMessages["world"]!!.size
@EventHandler
fun onDeath(
event: PlayerDeathEvent
) {
val player = event.entity
suppressEvent( event )
val lastDamageCause = player.lastDamageCause
var killer: Entity? = null
var deathType = DeathType.WORLD
if ( lastDamageCause is EntityDamageByEntityEvent )
{
val damager = lastDamageCause.damager
if ( damager !is Player )
{
if ( damager is Projectile )
{
if ( damager.shooter is Player )
{
deathType = DeathType.PLAYER
killer = damager.shooter as Player
}
else
{
deathType = DeathType.ENTITY
killer = damager.shooter as Entity
}
}
else if ( damager is Tameable && damager.isTamed && damager.owner is Player )
{
deathType = DeathType.PLAYER
killer = damager.owner as Player
}
else
{
deathType = DeathType.ENTITY
killer = damager
}
}
else
{
deathType = DeathType.PLAYER
killer = damager
}
}
if ( killer != null && killer is Player )
{
killer.exp += 0.5f
runBlocking { plugin.statsRepository.addKills( killer.uniqueId, 1 ) }
}
when( deathType )
{
DeathType.PLAYER ->
{
val random = this.random.nextInt( 0, playerDeathMessages )
val message = plugin.chatFormatter.formatList( "death.player",
"{player}" to player.getDisplayName, "{killer}" to (killer as Player).getDisplayName
)[ random ]
for ( p in Bukkit.getOnlinePlayers() )
plugin.chatManager.sendInteractiveMessage( p, message )
}
DeathType.ENTITY ->
{
val random = this.random.nextInt( 0, entityDeathMessages )
val message = plugin.chatFormatter.formatList( "death.entity",
"{player}" to player.getDisplayName, "{entity}" to killer!!.type.name
)[ random ]
for ( p in Bukkit.getOnlinePlayers() )
plugin.chatManager.sendInteractiveMessage( p, message )
}
DeathType.WORLD ->
{
val random = this.random.nextInt( 0, worldDeathMessages )
val message = plugin.chatFormatter.formatList( "death.world",
"{player}" to player.getDisplayName
)[ random ]
for ( p in Bukkit.getOnlinePlayers() )
plugin.chatManager.sendInteractiveMessage( p, message )
}
}
}
private fun suppressEvent(
event: PlayerDeathEvent
) {
val player = event.entity
event.deathMessage( null )
event.setShouldDropExperience( false )
event.setShouldPlayDeathSound( false )
player.world.strikeLightningEffect( player.location )
runBlocking {
plugin.statsRepository.addDeaths( player.uniqueId, 1 )
plugin.playerRepository.updateAliveStatus( player.uniqueId, false )
}
if ( player.isOnline )
player.kick(plugin.chatFormatter.format( "death.kick" ))
}
} }