feat: Introduce dispatchToComponentsWithDependencyCheck to conditionally dispatch events based on item data components and event handling status.
This commit is contained in:
parent
b5a51fad96
commit
e5d89e41b6
|
|
@ -94,7 +94,13 @@ class EventListener(private val plugin: Plugin) : Listener {
|
||||||
|
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
// AbstractItem interface does not define onToggleSneak.
|
// AbstractItem interface does not define onToggleSneak.
|
||||||
dispatchToComponents(item) { it.onToggleSneak(player, item, event) }
|
val handled = dispatchToComponentsWithDependencyCheck(
|
||||||
|
item = item,
|
||||||
|
isEventHandled = { event.isCancelled }
|
||||||
|
) { component ->
|
||||||
|
component.onToggleSneak(player, item, event)
|
||||||
|
}
|
||||||
|
if (handled) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +110,13 @@ class EventListener(private val plugin: Plugin) : Listener {
|
||||||
if (entity is Player) {
|
if (entity is Player) {
|
||||||
val items = getEquipmentItems(entity)
|
val items = getEquipmentItems(entity)
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
dispatchToComponents(item) { it.onToggleGlide(entity, item, event) }
|
val handled = dispatchToComponentsWithDependencyCheck(
|
||||||
|
item = item,
|
||||||
|
isEventHandled = { event.isCancelled }
|
||||||
|
) { component ->
|
||||||
|
component.onToggleGlide(entity, item, event)
|
||||||
|
}
|
||||||
|
if (handled) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,6 +150,52 @@ class EventListener(private val plugin: Plugin) : Listener {
|
||||||
action(abstractItem)
|
action(abstractItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches to components on an item, but only if the item satisfies
|
||||||
|
* the component's dataComponentDependencies.
|
||||||
|
*
|
||||||
|
* This prevents multiple components with the same trigger conditions
|
||||||
|
* (e.g., GLIDER) from firing simultaneously when only one item
|
||||||
|
* actually has the required data component active.
|
||||||
|
*
|
||||||
|
* @param item The item to dispatch to
|
||||||
|
* @param isEventHandled Lambda to check if the event has been handled (e.g., cancelled)
|
||||||
|
* @param action The action to perform on each eligible component
|
||||||
|
* @return true if the event was handled by any component, false otherwise
|
||||||
|
*/
|
||||||
|
private fun dispatchToComponentsWithDependencyCheck(
|
||||||
|
item: ItemStack,
|
||||||
|
isEventHandled: () -> Boolean,
|
||||||
|
action: (CustomComponent) -> Unit
|
||||||
|
): Boolean {
|
||||||
|
if (item.type.isAir) return false
|
||||||
|
val meta = item.itemMeta ?: return false
|
||||||
|
val pdc = meta.persistentDataContainer
|
||||||
|
|
||||||
|
for (key in pdc.keys) {
|
||||||
|
// Stop if event is already handled by a previous component
|
||||||
|
if (isEventHandled()) return true
|
||||||
|
|
||||||
|
val component = ComponentRegistry.get(key) ?: continue
|
||||||
|
|
||||||
|
// Check if this item has all required data component dependencies
|
||||||
|
// This ensures the component only triggers on items that
|
||||||
|
// actually have the necessary data components active
|
||||||
|
val hasAllDependencies = component.dataComponentDependencies.all { dep ->
|
||||||
|
item.hasData(dep)
|
||||||
|
}
|
||||||
|
if (!hasAllDependencies) continue
|
||||||
|
|
||||||
|
action(component)
|
||||||
|
}
|
||||||
|
|
||||||
|
return isEventHandled()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches to all components on an item without checking dependencies.
|
||||||
|
* Use this for events that don't rely on data component triggers.
|
||||||
|
*/
|
||||||
private fun dispatchToComponents(item: ItemStack, action: (CustomComponent) -> Unit) {
|
private fun dispatchToComponents(item: ItemStack, action: (CustomComponent) -> Unit) {
|
||||||
if (item.type.isAir) return
|
if (item.type.isAir) return
|
||||||
val meta = item.itemMeta ?: return
|
val meta = item.itemMeta ?: return
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user