ActionEntry
The ActionEntry defines an action to take. When it is triggered, it will run it's execute method.
After which it will trigger all the next entries in the chain.
It is important to stress that the entry must be immutable. It cannot have any mutable state.
Usage
@Entry("example_action", "An example action entry.", Colors.RED, "material-symbols:touch-app-rounded")
class ExampleActionEntry(
override val id: String = "",
override val name: String = "",
override val criteria: List<Criteria> = emptyList(),
override val modifiers: List<Modifier> = emptyList(),
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
) : ActionEntry {
override fun ActionTrigger.execute() {
// Do something with the player
}
}
Typewriter will automatically trigger the next entries in the chain after the execute method is called, and apply all the modifiers.
Sometimes you want to have a little more control over when the next triggers are triggered, or what triggers are triggered.
override fun ActionTrigger.execute() {
// This disables Typewriter's automatic triggering of the next entries,
// and disables the automatic apply of the modifiers.
disableAutomaticTriggering()
// Now you can manually trigger the next entries.
triggerManually()
// Or if you want to specify which triggers to trigger, you can do so.
triggers.filterIndexed { index, _ -> index % 2 == 0 }.triggerFor(player)
// You can also manually apply the modifiers.
applyModifiers()
}
Working with Interaction Context
Action entries can both read from and modify the interaction context, making them powerful tools for data manipulation and conditional logic.
Action entries can access data stored in the interaction context by previous entries or add/update values in the interaction context for use by subsequent entries:
enum class ExampleEntryContextKeys(override val klass: KClass<*>) : EntryContextKey {
// The two `String::class` have to be the same.
// The @KeyType is for the panel to know
@KeyType(String::class)
// The type here is for casting during runtime
TEXT(String::class),
@KeyType(Int::class)
NUMBER(Int::class),
// More complex types are also allowed.
@KeyType(Position::class)
POSITION(Position::class)
}
@GlobalKey(Int::class)
object LuckyNumberKey : GlobalContextKey<Int>(Int::class)
@Entry("example_action_with_context", "An action that reads/writes from/to interaction context", Colors.RED, "material-symbols:touch-app-rounded")
// This tells Typewriter that this entry exposes some context
@ContextKeys(ExampleEntryContextKeys::class)
class ExampleActionWithContextEntry(
override val id: String = "",
override val name: String = "",
override val criteria: List<Criteria> = emptyList(),
override val modifiers: List<Modifier> = emptyList(),
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
) : ActionEntry {
override fun ActionTrigger.execute() {
// Writing values to the context
context[ref(), ExampleEntryContextKeys.TEXT] = "Hey there"
context[ref(), ExampleEntryContextKeys.NUMBER] = 42
context[ref(), ExampleEntryContextKeys.POSITION] = Position.ORIGIN
context[LuckyNumberKey] = 69
// Reading values from the context
val text: String? = context[ref(), ExampleEntryContextKeys.TEXT]
val number: Int? = context[ref(), ExampleEntryContextKeys.NUMBER]
val position: Position? = context[ref(), ExampleEntryContextKeys.POSITION]
val luckyNumber = context[LuckyNumberKey]
player.sendMessage("$text, the number is $number at $position and the lucky number is $luckyNumber".asMini())
}
}
For more detailed information about interaction context, see the Interaction Context guide.