diff --git a/src/main/kotlin/net/hareworks/hcu/items/domain/ItemRegistry.kt b/src/main/kotlin/net/hareworks/hcu/items/domain/ItemRegistry.kt index a313ac1..1edf2b6 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/domain/ItemRegistry.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/domain/ItemRegistry.kt @@ -3,10 +3,6 @@ package net.hareworks.hcu.items.domain object ItemRegistry { private val items = mutableMapOf() - /** - * Registers a special item. - * @throws IllegalArgumentException if an item with the same ID is already registered. - */ fun register(item: SpecialItem) { if (items.containsKey(item.id)) { throw IllegalArgumentException("Item with id ${item.id} is already registered") @@ -14,16 +10,10 @@ object ItemRegistry { items[item.id] = item } - /** - * Gets a special item by its ID. - */ fun get(id: String): SpecialItem? { return items[id] } - /** - * Gets all registered special items. - */ fun getAll(): Collection { return items.values } diff --git a/src/main/kotlin/net/hareworks/hcu/items/domain/SpecialItem.kt b/src/main/kotlin/net/hareworks/hcu/items/domain/SpecialItem.kt index 773a755..f207068 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/domain/SpecialItem.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/domain/SpecialItem.kt @@ -5,23 +5,12 @@ import org.bukkit.NamespacedKey import org.bukkit.inventory.ItemStack import org.bukkit.persistence.PersistentDataType -/** - * Base class for all special HCU items. - * - * @property id The unique identifier for this special item. - */ abstract class SpecialItem(val id: String) { - /** - * Creates a new ItemStack for this special item. - * Subclasses should override [buildItem] to define the item's properties. - * @param tier The tier of the item to create. Defaults to [Tier.ONE]. - */ fun createItemStack(tier: Tier = Tier.ONE): ItemStack { val item = buildItem(tier) val meta = item.itemMeta ?: return item - // Tag the item as a special HCU item meta.persistentDataContainer.set(KEY_HCU_ITEM_ID, PersistentDataType.STRING, id) meta.persistentDataContainer.set(KEY_HCU_ITEM_TIER, PersistentDataType.INTEGER, tier.level) @@ -29,61 +18,32 @@ abstract class SpecialItem(val id: String) { return item } - /** - * Builds the base ItemStack. - * This method should configure the material, name, lore, etc. - * @param tier The tier of the item being built. - */ protected abstract fun buildItem(tier: Tier): ItemStack - /** - * Called when a player interacts with this item. - */ open fun onInteract(event: org.bukkit.event.player.PlayerInteractEvent) {} - /** - * Called when a player uses a fishing rod (casts, reels in, catches, etc). - */ open fun onFish(event: org.bukkit.event.player.PlayerFishEvent) {} - /** - * Called when a projectile from this item hits something. - */ open fun onProjectileHit(event: org.bukkit.event.entity.ProjectileHitEvent) {} - /** - * Called when a projectile from this item is launched. - */ open fun onProjectileLaunch(event: org.bukkit.event.entity.ProjectileLaunchEvent) {} - /** - * Called when the player holding this item takes damage. - */ open fun onEntityDamage(event: org.bukkit.event.entity.EntityDamageEvent) {} companion object { val KEY_HCU_ITEM_ID = NamespacedKey("hcu_items", "id") val KEY_HCU_ITEM_TIER = NamespacedKey("hcu_items", "tier") - /** - * Checks if the given item is a special HCU item. - */ fun isSpecialItem(item: ItemStack?): Boolean { if (item == null || item.type.isAir) return false return item.itemMeta?.persistentDataContainer?.has(KEY_HCU_ITEM_ID, PersistentDataType.STRING) == true } - /** - * Gets the HCU item ID from the given item, or null if it's not a special item. - */ fun getId(item: ItemStack?): String? { if (item == null || item.type.isAir) return null return item.itemMeta?.persistentDataContainer?.get(KEY_HCU_ITEM_ID, PersistentDataType.STRING) } - /** - * Gets the Tier of the given item. Defaults to [Tier.ONE] if not found/valid. - */ fun getTier(item: ItemStack?): Tier { if (item == null || item.type.isAir) return Tier.ONE val level = item.itemMeta?.persistentDataContainer?.get(KEY_HCU_ITEM_TIER, PersistentDataType.INTEGER) ?: return Tier.ONE diff --git a/src/main/kotlin/net/hareworks/hcu/items/domain/impl/GrapplingItem.kt b/src/main/kotlin/net/hareworks/hcu/items/domain/impl/GrapplingItem.kt index 5beec94..eda5adb 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/domain/impl/GrapplingItem.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/domain/impl/GrapplingItem.kt @@ -21,9 +21,6 @@ class GrapplingItem : SpecialItem("grappling_hook") { Component.text("Tier: ${tier.level}", tier.color) )) - // Optional: Make it unbreakable or have durability based on tier? - // meta.isUnbreakable = true - item.itemMeta = meta return item } @@ -31,10 +28,8 @@ class GrapplingItem : SpecialItem("grappling_hook") { override fun onFish(event: PlayerFishEvent) { val hook = event.hook - // Check if stuck via our custom PDC tag (meaning it hit a block and we anchored it) val isStuck = hook.persistentDataContainer.has(KEY_HOOK_STUCK, org.bukkit.persistence.PersistentDataType.BYTE) - - // If reeling in and it's stuck (anchored), pull the player + if (event.state == PlayerFishEvent.State.REEL_IN && isStuck) { val player = event.player val playerLoc = player.location @@ -50,12 +45,9 @@ class GrapplingItem : SpecialItem("grappling_hook") { val velocity = vector.normalize().multiply(speed) player.velocity = velocity - // "飛ぶ速度に比例して空腹になる" - // Cost based on speed (magnitude of velocity) - // Base cost multiplier + val hungerCostBase = 2.0 - // Tier reduces cost? Or just proportional to speed? - // Let's make higher tiers slightly more efficient per unit of speed. + val efficiency = 1.0 + (tier.level * 0.1) val hungerCost = (velocity.length() * hungerCostBase / efficiency).toInt().coerceAtLeast(1) @@ -63,10 +55,9 @@ class GrapplingItem : SpecialItem("grappling_hook") { player.foodLevel = (player.foodLevel - hungerCost).coerceAtLeast(0) } - // Cleanup anchor when reeling in or if the hook is removed if (event.state == PlayerFishEvent.State.REEL_IN || event.state == PlayerFishEvent.State.CAUGHT_ENTITY || - event.state == PlayerFishEvent.State.BITE) { // BITE might be too early? usually REEL_IN is the end + event.state == PlayerFishEvent.State.BITE) { val vehicle = hook.vehicle if (vehicle is org.bukkit.entity.ArmorStand && vehicle.persistentDataContainer.has(KEY_ANCHOR_ID, org.bukkit.persistence.PersistentDataType.STRING)) { @@ -80,8 +71,7 @@ class GrapplingItem : SpecialItem("grappling_hook") { val shooter = projectile.shooter if (shooter is org.bukkit.entity.Player) { - // "浮を投げるとき投げたプレイヤーの速度が慣性に乗るようにしてください" - // Add player's velocity to the projectile + projectile.velocity = projectile.velocity.add(shooter.velocity) } } @@ -90,11 +80,8 @@ class GrapplingItem : SpecialItem("grappling_hook") { if ((event.hitBlock != null || event.hitEntity != null) && event.hitBlock?.isCollidable() == true) { val hook = event.entity if (hook is org.bukkit.entity.FishHook) { - // Determine spawn location slightly adjusted to avoid clipping into the wall too much? - // Or just exactly at the hook. Hook collision box is small. val location = hook.location - - // Spawn anchor + val anchor = location.world.spawn(location, org.bukkit.entity.ArmorStand::class.java) { stand -> stand.isVisible = false stand.isMarker = true @@ -115,11 +102,6 @@ class GrapplingItem : SpecialItem("grappling_hook") { } override fun onEntityDamage(event: org.bukkit.event.entity.EntityDamageEvent) { - // "手に持っているときは落下ダメージ半減" - // "受けたダメージ分だけ空腹になる" - // "もし空腹で受けきれなかった場合は普通にダメージを受ける" - // "Tireによって空腹度合いが変わる" - if (event.cause == org.bukkit.event.entity.EntityDamageEvent.DamageCause.FALL) { val player = event.entity if (player is org.bukkit.entity.Player) { @@ -129,31 +111,21 @@ class GrapplingItem : SpecialItem("grappling_hook") { val originalDamage = event.damage val reducedDamage = originalDamage / 2.0 val damageToAbsorb = originalDamage - reducedDamage - - // Hunger cost: - // Base cost is equal to damage absorbed? Or some factor? - // "Tireによって空腹度合いが変わる" -> Higher tier = cheaper - // Example: Cost = Damage * (2.5 - (0.4 * Tier)) - // Tier 1: 2.1x damage, Tier 5: 0.5x damage + val costFactor = (3.0 - (0.5 * tier.level)).coerceAtLeast(0.5) val hungerCostPerDamage = costFactor val totalHungerCost = (damageToAbsorb * hungerCostPerDamage).toInt() if (player.foodLevel >= totalHungerCost) { - // "受けたダメージ分だけ空腹になる" (interpreted as paying the cost) player.foodLevel = (player.foodLevel - totalHungerCost).coerceAtLeast(0) event.damage = reducedDamage } else { - // "空腹で受けきれなかった場合はそのままダメージを受けるのではなく空腹で受けられる分のダメージは受けて余ったダメージを直接受けるようにしてください" - // Calculate how much damage we can absorb with available food val availableFood = player.foodLevel val damageWeCanAbsorb = availableFood / hungerCostPerDamage val damageWeCannotAbsorb = damageToAbsorb - damageWeCanAbsorb - // Consume all available food player.foodLevel = 0 - // Take reduced damage for what we could absorb, plus full damage for what we couldn't event.damage = reducedDamage + damageWeCannotAbsorb } } diff --git a/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt b/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt index 8a7d8b2..a2a8458 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt @@ -13,7 +13,6 @@ class EventListener(private val plugin: App) : Listener { @EventHandler fun onInteract(event: PlayerInteractEvent) { - // Only handle main hand interactions or when there's an item involved if (event.hand == EquipmentSlot.OFF_HAND) return val item = event.item ?: return diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 83cf02f..8b13789 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,15 +1 @@ -# Elevator Plugin Configuration -# The maximum distance (in blocks) the elevator will search for a valid destination. -maxHeight: 64 - -# Blocks that function as elevators -elevatorBlocks: - - minecraft:iron_block - - minecraft:gold_block - - minecraft:diamond_block - - minecraft:lapis_block - - minecraft:redstone_block - - minecraft:emerald_block - - minecraft:netherite_block - - minecraft:coal_block