refactor: Replace SpecialItem with CustomItem interface and AbstractItem class.

This commit is contained in:
Kariya 2025-12-11 12:59:52 +00:00
parent 9bb631df74
commit b476368425
7 changed files with 46 additions and 38 deletions

View File

@ -5,12 +5,12 @@ import org.bukkit.NamespacedKey
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
abstract class SpecialItem(val id: String) { abstract class AbstractItem(override val id: String) : CustomItem {
open val maxTier: Int = 5 override val maxTier: Int = 5
open val minTier: Int = 1 override val minTier: Int = 1
fun createItemStack(tier: Tier = Tier.ONE): ItemStack { override fun createItemStack(tier: Tier): ItemStack {
val validTier = if (tier.level < minTier) Tier.fromLevel(minTier) val validTier = if (tier.level < minTier) Tier.fromLevel(minTier)
else if (tier.level > maxTier) Tier.fromLevel(maxTier) else if (tier.level > maxTier) Tier.fromLevel(maxTier)
else tier else tier
@ -27,23 +27,11 @@ abstract class SpecialItem(val id: String) {
protected abstract fun buildItem(tier: Tier): ItemStack protected abstract fun buildItem(tier: Tier): ItemStack
open fun onInteract(event: org.bukkit.event.player.PlayerInteractEvent) {}
open fun onFish(event: org.bukkit.event.player.PlayerFishEvent) {}
open fun onProjectileHit(event: org.bukkit.event.entity.ProjectileHitEvent) {}
open fun onProjectileLaunch(event: org.bukkit.event.entity.ProjectileLaunchEvent) {}
open fun onEntityDamage(event: org.bukkit.event.entity.EntityDamageEvent) {}
open fun onPlayerMove(event: org.bukkit.event.player.PlayerMoveEvent) {}
companion object { companion object {
val KEY_HCU_ITEM_ID = NamespacedKey("hcu_items", "id") val KEY_HCU_ITEM_ID = NamespacedKey("hcu_items", "id")
val KEY_HCU_ITEM_TIER = NamespacedKey("hcu_items", "tier") val KEY_HCU_ITEM_TIER = NamespacedKey("hcu_items", "tier")
fun isSpecialItem(item: ItemStack?): Boolean { fun isCustomItem(item: ItemStack?): Boolean {
if (item == null || item.type.isAir) return false if (item == null || item.type.isAir) return false
return item.itemMeta?.persistentDataContainer?.has(KEY_HCU_ITEM_ID, PersistentDataType.STRING) == true return item.itemMeta?.persistentDataContainer?.has(KEY_HCU_ITEM_ID, PersistentDataType.STRING) == true
} }

View File

@ -0,0 +1,19 @@
package net.hareworks.hcu.items.api.item
import net.hareworks.hcu.items.api.Tier
import org.bukkit.inventory.ItemStack
interface CustomItem {
val id: String
val maxTier: Int
val minTier: Int
fun createItemStack(tier: Tier = Tier.ONE): ItemStack
fun onInteract(event: org.bukkit.event.player.PlayerInteractEvent) {}
fun onFish(event: org.bukkit.event.player.PlayerFishEvent) {}
fun onProjectileHit(event: org.bukkit.event.entity.ProjectileHitEvent) {}
fun onProjectileLaunch(event: org.bukkit.event.entity.ProjectileLaunchEvent) {}
fun onEntityDamage(event: org.bukkit.event.entity.EntityDamageEvent) {}
fun onPlayerMove(event: org.bukkit.event.player.PlayerMoveEvent) {}
}

View File

@ -7,7 +7,7 @@ import net.hareworks.permits_lib.bukkit.MutationSession
import org.bukkit.permissions.PermissionDefault import org.bukkit.permissions.PermissionDefault
import org.bukkit.entity.Player import org.bukkit.entity.Player
import net.hareworks.hcu.items.registry.ItemRegistry import net.hareworks.hcu.items.registry.ItemRegistry
import net.hareworks.hcu.items.api.item.SpecialItem import net.hareworks.hcu.items.api.item.AbstractItem
import net.hareworks.hcu.items.api.Tier import net.hareworks.hcu.items.api.Tier
import net.hareworks.hcu.items.registry.ComponentRegistry import net.hareworks.hcu.items.registry.ComponentRegistry
@ -199,4 +199,5 @@ object CommandRegistrar {
} }
} }
} }
}
} }

View File

@ -1,6 +1,6 @@
package net.hareworks.hcu.items.content.items package net.hareworks.hcu.items.content.items
import net.hareworks.hcu.items.api.item.SpecialItem import net.hareworks.hcu.items.api.item.AbstractItem
import net.hareworks.hcu.items.api.Tier import net.hareworks.hcu.items.api.Tier
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
@ -9,7 +9,7 @@ import org.bukkit.Material
import org.bukkit.event.player.PlayerFishEvent import org.bukkit.event.player.PlayerFishEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
class GrapplingItem : SpecialItem("grappling_hook") { class GrapplingItem : AbstractItem("grappling_hook") {
override fun buildItem(tier: Tier): ItemStack { override fun buildItem(tier: Tier): ItemStack {
val item = ItemStack(Material.FISHING_ROD) val item = ItemStack(Material.FISHING_ROD)
@ -53,7 +53,7 @@ class GrapplingItem : SpecialItem("grappling_hook") {
val vector = hookLoc.toVector().subtract(playerLoc.toVector()) val vector = hookLoc.toVector().subtract(playerLoc.toVector())
val item = player.inventory.itemInMainHand val item = player.inventory.itemInMainHand
val tier = SpecialItem.getTier(item) val tier = AbstractItem.getTier(item)
val speed = 1.0 + (tier.level * 0.4) val speed = 1.0 + (tier.level * 0.4)
@ -184,7 +184,7 @@ class GrapplingItem : SpecialItem("grappling_hook") {
else -> return else -> return
} }
val tier = SpecialItem.getTier(item) val tier = AbstractItem.getTier(item)
val originalDamage = event.damage val originalDamage = event.damage
val reducedDamage = originalDamage / 2.0 val reducedDamage = originalDamage / 2.0
@ -228,7 +228,7 @@ class GrapplingItem : SpecialItem("grappling_hook") {
} }
private fun isGrapplingHook(item: ItemStack): Boolean { private fun isGrapplingHook(item: ItemStack): Boolean {
return SpecialItem.getId(item) == "grappling_hook" return AbstractItem.getId(item) == "grappling_hook"
} }
companion object { companion object {

View File

@ -1,13 +1,13 @@
package net.hareworks.hcu.items.content.items package net.hareworks.hcu.items.content.items
import net.hareworks.hcu.items.api.item.SpecialItem import net.hareworks.hcu.items.api.item.AbstractItem
import net.hareworks.hcu.items.api.Tier import net.hareworks.hcu.items.api.Tier
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 org.bukkit.Material import org.bukkit.Material
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
class TestItem : SpecialItem("test_sword") { class TestItem : AbstractItem("test_sword") {
override fun buildItem(tier: Tier): ItemStack { override fun buildItem(tier: Tier): ItemStack {
val item = ItemStack(Material.DIAMOND_SWORD) val item = ItemStack(Material.DIAMOND_SWORD)
val meta = item.itemMeta ?: return item val meta = item.itemMeta ?: return item
@ -24,7 +24,7 @@ class TestItem : SpecialItem("test_sword") {
override fun onInteract(event: org.bukkit.event.player.PlayerInteractEvent) { override fun onInteract(event: org.bukkit.event.player.PlayerInteractEvent) {
val item = event.item val item = event.item
val tier = SpecialItem.getTier(item) val tier = AbstractItem.getTier(item)
event.player.sendMessage(Component.text("You used the Test Sword (Tier ${tier.level})!", tier.color)) event.player.sendMessage(Component.text("You used the Test Sword (Tier ${tier.level})!", tier.color))

View File

@ -1,7 +1,7 @@
package net.hareworks.hcu.items.listeners package net.hareworks.hcu.items.listeners
import net.hareworks.hcu.items.api.component.CustomComponent import net.hareworks.hcu.items.api.component.CustomComponent
import net.hareworks.hcu.items.api.item.SpecialItem import net.hareworks.hcu.items.api.item.AbstractItem
import net.hareworks.hcu.items.registry.ComponentRegistry import net.hareworks.hcu.items.registry.ComponentRegistry
import net.hareworks.hcu.items.registry.ItemRegistry import net.hareworks.hcu.items.registry.ItemRegistry
import org.bukkit.entity.Player import org.bukkit.entity.Player
@ -37,9 +37,9 @@ class EventListener : Listener {
val shooter = projectile.shooter val shooter = projectile.shooter
if (shooter is Player) { if (shooter is Player) {
// For ProjectileHitEvent, SpecialItems often need to check if the projectile belongs to them, // For ProjectileHitEvent, AbstractItems often need to check if the projectile belongs to them,
// which might not be the item currently held by the player. // which might not be the item currently held by the player.
// Therefore, we iterate through all registered SpecialItems. // Therefore, we iterate through all registered AbstractItems.
ItemRegistry.getAll().forEach { it.onProjectileHit(event) } ItemRegistry.getAll().forEach { it.onProjectileHit(event) }
// CustomComponent interface does not define onProjectileHit, so no dispatchToComponents here. // CustomComponent interface does not define onProjectileHit, so no dispatchToComponents here.
} }
@ -84,13 +84,13 @@ class EventListener : Listener {
val items = getEquipmentItems(player) val items = getEquipmentItems(player)
for (item in items) { for (item in items) {
// SpecialItem interface does not define onToggleSneak. // AbstractItem interface does not define onToggleSneak.
dispatchToComponents(item) { it.onToggleSneak(player, item, event) } dispatchToComponents(item) { it.onToggleSneak(player, item, event) }
} }
} }
private fun getEquipmentItems(player: Player): List<ItemStack> { private fun getEquipmentItems(player: Player): List<ItemStack> {
val equipment = player.equipment ?: return emptyList() val equipment = player.equipment
val items = mutableListOf<ItemStack>() val items = mutableListOf<ItemStack>()
items.addAll(equipment.armorContents.filterNotNull()) items.addAll(equipment.armorContents.filterNotNull())
items.add(equipment.itemInMainHand) items.add(equipment.itemInMainHand)
@ -98,9 +98,9 @@ class EventListener : Listener {
return items.filter { !it.type.isAir } return items.filter { !it.type.isAir }
} }
private fun dispatchToItem(item: ItemStack, action: (SpecialItem) -> Unit) { private fun dispatchToItem(item: ItemStack, action: (AbstractItem) -> Unit) {
if (item.type.isAir) return if (item.type.isAir) return
val id = SpecialItem.getId(item) ?: return val id = AbstractItem.getId(item) ?: return
val specialItem = ItemRegistry.get(id) ?: return val specialItem = ItemRegistry.get(id) ?: return
action(specialItem) action(specialItem)
} }

View File

@ -1,22 +1,22 @@
package net.hareworks.hcu.items.registry package net.hareworks.hcu.items.registry
import net.hareworks.hcu.items.api.item.SpecialItem import net.hareworks.hcu.items.api.item.AbstractItem
object ItemRegistry { object ItemRegistry {
private val items = mutableMapOf<String, SpecialItem>() private val items = mutableMapOf<String, AbstractItem>()
fun register(item: SpecialItem) { fun register(item: AbstractItem) {
if (items.containsKey(item.id)) { if (items.containsKey(item.id)) {
throw IllegalArgumentException("Item with id ${item.id} is already registered") throw IllegalArgumentException("Item with id ${item.id} is already registered")
} }
items[item.id] = item items[item.id] = item
} }
fun get(id: String): SpecialItem? { fun get(id: String): AbstractItem? {
return items[id] return items[id]
} }
fun getAll(): Collection<SpecialItem> { fun getAll(): Collection<AbstractItem> {
return items.values return items.values
} }
} }