feat: Implement component dependency management for custom and vanilla data components.

This commit is contained in:
Kariya 2025-12-11 15:26:14 +00:00
parent 23bb8559f2
commit 790e2f446c
4 changed files with 41 additions and 2 deletions

View File

@ -1,5 +1,6 @@
package net.hareworks.hcu.items.api.component package net.hareworks.hcu.items.api.component
import io.papermc.paper.datacomponent.DataComponentType
import net.hareworks.hcu.items.api.Tier import net.hareworks.hcu.items.api.Tier
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@ -10,6 +11,14 @@ interface CustomComponent {
val maxTier: Int val maxTier: Int
val minTier: Int val minTier: Int
/** 依存する他のCustomComponentNamespacedKeyで指定 */
val componentDependencies: List<NamespacedKey>
get() = emptyList()
/** 依存するバニラDataComponent値なしフラグタイプ用 */
val dataComponentDependencies: List<DataComponentType.NonValued>
get() = emptyList()
fun apply(item: ItemStack, tier: Tier? = null) fun apply(item: ItemStack, tier: Tier? = null)
fun has(item: ItemStack): Boolean fun has(item: ItemStack): Boolean
fun remove(item: ItemStack) fun remove(item: ItemStack)

View File

@ -161,7 +161,7 @@ object CommandRegistrar {
return@executes return@executes
} }
component.apply(item) ComponentRegistry.applyWithDependencies(component, item)
sender.sendMessage("Applied component '${component.displayName}' to held item.") sender.sendMessage("Applied component '${component.displayName}' to held item.")
} }
integer("tier", min = 1, max = 100) { integer("tier", min = 1, max = 100) {
@ -190,7 +190,7 @@ object CommandRegistrar {
} }
val tier = Tier.fromLevel(tierLevel) val tier = Tier.fromLevel(tierLevel)
component.apply(item, tier) ComponentRegistry.applyWithDependencies(component, item, tier)
sender.sendMessage("Applied component '${component.displayName}' (Tier ${tier.level}) to held item.") sender.sendMessage("Applied component '${component.displayName}' (Tier ${tier.level}) to held item.")
} }
} }

View File

@ -1,5 +1,7 @@
package net.hareworks.hcu.items.content.components package net.hareworks.hcu.items.content.components
import io.papermc.paper.datacomponent.DataComponentType
import io.papermc.paper.datacomponent.DataComponentTypes
import net.hareworks.hcu.items.App import net.hareworks.hcu.items.App
import net.hareworks.hcu.items.api.Tier import net.hareworks.hcu.items.api.Tier
import net.hareworks.hcu.items.api.component.AbstractComponent import net.hareworks.hcu.items.api.component.AbstractComponent
@ -20,6 +22,9 @@ class DoubleJumpComponent(private val plugin: App) : AbstractComponent(plugin, "
override val displayName: String = "Double Jump" override val displayName: String = "Double Jump"
override val maxTier: Int = 3 override val maxTier: Int = 3
override val dataComponentDependencies: List<DataComponentType.NonValued>
get() = listOf(DataComponentTypes.GLIDER)
override fun apply(item: ItemStack, tier: Tier?) { override fun apply(item: ItemStack, tier: Tier?) {
if (isBoots(item.type)) { if (isBoots(item.type)) {
super.apply(item, tier) super.apply(item, tier)

View File

@ -1,7 +1,9 @@
package net.hareworks.hcu.items.registry package net.hareworks.hcu.items.registry
import net.hareworks.hcu.items.api.Tier
import net.hareworks.hcu.items.api.component.CustomComponent import net.hareworks.hcu.items.api.component.CustomComponent
import net.hareworks.hcu.items.api.component.EquippableComponent import net.hareworks.hcu.items.api.component.EquippableComponent
import org.bukkit.inventory.ItemStack
object ComponentRegistry { object ComponentRegistry {
private val components = mutableMapOf<org.bukkit.NamespacedKey, CustomComponent>() private val components = mutableMapOf<org.bukkit.NamespacedKey, CustomComponent>()
@ -17,4 +19,27 @@ object ComponentRegistry {
fun getEquippableComponents(): List<EquippableComponent> { fun getEquippableComponents(): List<EquippableComponent> {
return components.values.filterIsInstance<EquippableComponent>() return components.values.filterIsInstance<EquippableComponent>()
} }
/**
* コンポーネントを依存関係を解決しながら適用する
*/
fun applyWithDependencies(component: CustomComponent, item: ItemStack, tier: Tier? = null) {
// 1. バニラDataComponent依存を適用
for (dataType in component.dataComponentDependencies) {
if (!item.hasData(dataType)) {
item.setData(dataType)
}
}
// 2. CustomComponent依存を再帰的に適用
for (depKey in component.componentDependencies) {
val dep = get(depKey)
if (dep != null && !dep.has(item)) {
applyWithDependencies(dep, item, null)
}
}
// 3. 本体を適用
component.apply(item, tier)
}
} }