跳到主要内容
 Warning: Beta Version
版本:Beta ⚠️(未翻译)

AudienceFilter

The AudienceFilterEntry is a specialized version of AudienceEntry designed to filter audience members based on specific criteria. It accepts a list of children that can include both AudienceEntry and AudienceFilterEntry components.

Basic Usage​

Static Filtering​

Here's an example of a filter that only allows players whose names start with 'g':

ExampleAudienceFilter.kt
class ExampleAudienceFilter(
ref: Ref<out AudienceFilterEntry>
) : AudienceFilter(ref) {
override fun filter(player: Player): Boolean {
return player.name.startsWith("g")
}
}

This filter is static because player names cannot be changed while on the server. Players are either filtered at the start or not at all.

Dynamic Filtering​

For more dynamic filtering, you can filter based on changing player attributes, such as health:

ExampleAudienceFilter.kt
class HealthAudienceFilter(
ref: Ref<out AudienceFilterEntry>,
private val healthRange: ClosedFloatingPointRange<Float> = 0f..20f
) : AudienceFilter(ref), TickableDisplay {
override fun filter(player: Player): Boolean {
return player.health in healthRange
}

// You can refresh the filters on events
@EventHandler
fun healthRegent(event: EntityRegainHealthEvent) {
val player = event.entity as? Player ?: return
// Reruns the filter
player.refresh()

// Or if you know the player should be filtered, you can update the filter directly
player.updateFilter(isFiltered = event.amount in healthRange)
}

// It is also possible to run the filter every tick
override fun tick() {
// Refresh the filter for all considered players
consideredPlayers.forEach { it.refresh() }
}
}

This example filters players based on their health value, which is provided as a parameter from the entry. Like AudienceDisplay, we can use both Bukkit events and TickableDisplay to update which players pass through the filter.

Invertible Filters​

Sometimes you may want to invert a filter's behavior. This is particularly useful when the opposite condition would be complex to define explicitly, such as filtering all players that are not in a specific world:

ExampleAudienceFilter.kt
@Entry("inverted_example_audience_filter", "An example audience filter.", Colors.MYRTLE_GREEN, "material-symbols:filter-alt")
class InvertedExampleAudienceFilterEntry(
override val id: String = "",
override val name: String = "",
override val children: List<Ref<out AudienceEntry>> = emptyList(),
override val inverted: Boolean = true,
) : AudienceFilterEntry, Invertible {
override fun display(): AudienceFilter = ExampleAudienceFilter(ref())
}

Simply implementing the Invertible interface enables this functionality in Typewriter.