diff --git a/documentation/docs/develop/02-extensions/04-entries/trigger/action.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/action.mdx index e316378b45..cb4816c4d4 100644 --- a/documentation/docs/develop/02-extensions/04-entries/trigger/action.mdx +++ b/documentation/docs/develop/02-extensions/04-entries/trigger/action.mdx @@ -13,5 +13,8 @@ It is important to stress that the entry must be immutable. ## Usage -Typewriter will automatically trigger the next entries in the chain after the `execute` method is called. -If you want to call the next entries in the chain manually, you can should the [CustomTriggeringActionEntry](./custom_triggering_action.mdx). +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. + + diff --git a/documentation/docs/develop/02-extensions/04-entries/trigger/custom_triggering_action.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/custom_triggering_action.mdx deleted file mode 100644 index 9cfaf98dd0..0000000000 --- a/documentation/docs/develop/02-extensions/04-entries/trigger/custom_triggering_action.mdx +++ /dev/null @@ -1,9 +0,0 @@ -import CodeSnippet from "@site/src/components/CodeSnippet"; - -# CustomTriggeringActionEntry - -The `CustomTriggeringActionEntry` is a specialised verion of the `ActionEntry` that allows you to trigger the next entries when you want. Or just call a subset of entries. - -## Usage - - diff --git a/documentation/docs/develop/02-extensions/04-entries/trigger/dialogue.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/dialogue.mdx index 9139189567..bd78f5ff6d 100644 --- a/documentation/docs/develop/02-extensions/04-entries/trigger/dialogue.mdx +++ b/documentation/docs/develop/02-extensions/04-entries/trigger/dialogue.mdx @@ -16,9 +16,6 @@ This is automatically handled by Typewriter. To define the messenger that will be used to display the dialogue to the player, you must create a class that implements the `DialogueMessenger` interface. -### Multiple Messengers -The `DialogueMessenger` has a `MessengerFilter` that is used to determine if the messenger should be used to display the dialogue to the player. When having multiple `MessageFilter`'s make sure that they are deterministic. So if you have some condition, such as if they are bedrock players. One message check that the player is a bedrock player and the other filter check that they are not. - ### Lifecycle The `state` of the messenger determines what happens to the messenger. - `MessengerState.FINISHED` - The dialogue is finished and the next dialogue in the chain will be triggered. diff --git a/documentation/docs/develop/02-extensions/04-entries/trigger/event.mdx b/documentation/docs/develop/02-extensions/04-entries/trigger/event.mdx index 90f9c5f825..f50666bdde 100644 --- a/documentation/docs/develop/02-extensions/04-entries/trigger/event.mdx +++ b/documentation/docs/develop/02-extensions/04-entries/trigger/event.mdx @@ -11,11 +11,10 @@ To listen to an event, you must create a function that is annotated with `@Entry The great thing about kotlin, is that this can be done in the same file as the entry. -:::warning Public Function -If the function is not scoped to be public, it will not be registered as a listener. -::: - The function will automatically be registered as a listener for the event by Typewriter and be called when the Bukkit event is trigger. An optional `Query` parameter can be added to easily fetch all the different event entries. +## Entry Context Variables +Sometimes you want to pass some information to the context so that subsequent entries can use it. + diff --git a/documentation/docs/develop/02-extensions/05-querying.mdx b/documentation/docs/develop/02-extensions/05-querying.mdx index 0d1bda4546..332d240b1a 100644 --- a/documentation/docs/develop/02-extensions/05-querying.mdx +++ b/documentation/docs/develop/02-extensions/05-querying.mdx @@ -1,35 +1,19 @@ +import CodeSnippet from "@site/src/components/CodeSnippet"; + # Query Entries Sometimes you need to find an entry by any of it's fields or by type. This can be done with the `Query` class. If you need to find all entries of a specific type: -```kotlin -val entries = Query.find() -``` - -Sometimes you need it by a specific criteria: -```kotlin -val entries = Query.findWhere { - it.someField == "some value" -} -``` - -You can also find a single entry: -```kotlin -val entry = Query.findFirstWhere { - it.someField == "some value" -} -``` + + +Sometimes you need it by a specific filter: + + Sometimes you need to find an entry by it's id: -```kotlin -val entry = Query.findById(id) -``` + Other times you need to find entries by their page: -```kotlin -val entries = Query.findWhereFromPage(pageId) { - it.someField == "some value" -} -``` + diff --git a/documentation/docs/develop/02-extensions/06-triggering.mdx b/documentation/docs/develop/02-extensions/06-triggering.mdx index 4303656aa0..de00ec66e6 100644 --- a/documentation/docs/develop/02-extensions/06-triggering.mdx +++ b/documentation/docs/develop/02-extensions/06-triggering.mdx @@ -1,3 +1,5 @@ +import CodeSnippet from "@site/src/components/CodeSnippet"; + # Triggering Entries There are easy ways to trigger all the next entries in a `TriggerEntry`. @@ -9,69 +11,36 @@ If criteria are not met, the entries are not triggered. ::: If you have a single `TriggerEntry`: -```kotlin -val triggerEntry: TriggerEntry = ... -val player: Player = ... -triggerEntry triggerAllFor player -``` - -If you have list of `TriggerEntry`: -```kotlin -val triggerEntries: List = ... -val player: Player = ... -triggerEntries triggerAllFor player -``` - -If you have a list of id's of `TriggerEntry`: -```kotlin -val triggerEntryIds: List = ... -val player: Player = ... -triggerEntryIds triggerEntriesFor player -``` - -Sometimes you don't want to trigger the entries when the player is in a dialogue. + + +Sometimes you don't want to trigger the entries when the player is in a dialogue. For example, when the player is in a dialogue with a NPC, you don't want to trigger the first entry of the NPC again. You expect when the player clicks on the NPC again, the next dialogue is triggered. To facilitate this, you can use the `startDialogueWithOrNextDialogue` function. -```kotlin -val triggerEntries: List = ... -val player: Player = ... -triggerEntries startDialogueWithOrNextDialogue player -``` + -Or if you want to trigger something completely different when the player is in a dialogue: -```kotlin -val triggerEntries: List = ... -val player: Player = ... -val customTrigger: EventTrigger = ... -triggerEntries.startDialogueWithOrTrigger(player, customTrigger) -``` +Previously, we triggered entries with a new fresh `context`, but sometimes we already have a context. +Then you need to make sure that you pass on the context to the trigger. + ## Custom triggers Typewriter triggers based on the `EventTrigger` interface. So all the entries that are triggered are wrapped in a `EntryTrigger`. -There are some triggers that are defined in Typewriter. -The two are `SystemTrigger` and `CinematicStartTrigger`. +### System Triggers + +For some interactions there are custom triggers that are defined in Typewriter. +These triggers allow you to do special things with the interaction. -### SystemTrigger + -`SystemTrigger`'s can be used to indicate to either the `DialogueSequence` or the `CinematicSequence` that something needs to happen. +#### Dialogue Interaction -- `SystemTrigger.DIALOGUE_NEXT` indicates that the next dialogue should be triggered. -- `SystemTrigger.DIALOGUE_END` indicates that the dialogue should end. -- `SystemTrigger.CINEMATIC_END` indicates that the cinematic should end. -### CinematicStartTrigger + -`CinematicStartTrigger`'s can be used to indicate to the `CinematicSequence` that a cinematic should start. +#### Temporal Interaction -It has several properties that can be set: -- `pageId: String` is the id of the cinematic page that should be shown. This is required. -- `triggers: List` is a list of trigger id's that should be triggered when the cinematic is finished. This is optional. -- `override: Boolean` indicates if the cinematic should override the current cinematic. This is optional and defaults to `false`. -- `simulate: Boolean` is used to run a cinematic for recording purposes. When this is enable it disables some entries from running. This is optional and defaults to `false`. -- `ignoreEntries: List` is a list of entry id's that should not be triggered. This is optional. -- `minEndTime: Optional` is the minimum amount of frames the cinematic should run. If the cinematic is shorter than this, it will be extended. This is optional. + diff --git a/documentation/docs/develop/02-extensions/07-api-changes/0.8.mdx b/documentation/docs/develop/02-extensions/07-api-changes/0.8.mdx index d3abf9f701..f8ed99cb17 100644 --- a/documentation/docs/develop/02-extensions/07-api-changes/0.8.mdx +++ b/documentation/docs/develop/02-extensions/07-api-changes/0.8.mdx @@ -20,7 +20,10 @@ Now the engine version is not specified in a seperate `engine` block, but in the import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { kotlin("jvm") version "2.0.21" - id("com.typewritermc.module-plugin") version "" + // highlight-red + id("com.typewritermc.module-plugin") version "1.0.1" + // highlight-green + id("com.typewritermc.module-plugin") version "1.1.0" } // Replace with your own information group = "me.yourusername" @@ -57,7 +60,10 @@ Now the engine version is not specified in a seperate `engine` block, but in the import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { kotlin("jvm") version "2.0.21" - id("com.typewritermc.module-plugin") version "" + // highlight-red + id("com.typewritermc.module-plugin") version "1.0.1" + // highlight-green + id("com.typewritermc.module-plugin") version "1.1.0" } // Replace with your own information group = "me.yourusername" @@ -93,3 +99,161 @@ Now the engine version is not specified in a seperate `engine` block, but in the ``` + +## `Initializable` Changes + +The way to register a `Initializable` has changed. + +```kotlin showLineNumbers +// highlight-red +@Initializer +// highlight-green +@Singleton +object ExampleInitializer : Initializable { + override suspend fun initialize() { + // Do something when the extension is initialized + } + + override suspend fun shutdown() { + // Do something when the extension is shutdown + } +} + +``` + +## Triggering Entries Changes + +Since Typewriter now has `InteractionContext`, this needs to be passed around when triggering entries. +As a lot changed, have a look at the [Triggering Entries](../triggering) page for more information. + +```kotlin showLineNumbers +val entries: List = ... + +// highlight-red +entries triggerAllFor player +// highlight-green +entries.triggerAllFor(player, context()) +``` + +## ActionEntry Changes + +As the `ActionEntry` now needs a `InteractionContext`, the `execute` function signature has changed. + +```kotlin showLineNumbers +@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 = emptyList(), + override val modifiers: List = emptyList(), + override val triggers: List> = emptyList(), +) : ActionEntry { + // highlight-red-start + override fun execute(player: Player) { + super.execute(player) // This will apply all the modifiers. + // highlight-red-end + // highlight-green-start + override fun ActionTrigger.execute() { + // Will now automatically apply all the modifiers. + // Do something with the player + } +} + +## Removal of `CustomTriggeringActionEntry` + +As the action entry now can specify itself how Typewriter should handle the triggering: + +```kotlin showLineNumbers +@Entry("example_action", "An example action entry.", Colors.RED, "material-symbols:touch-app-rounded") +class ExampleCustomTriggeringActionEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + override val modifiers: List = emptyList(), +// highlight-red-start + @SerializedName("triggers") + override val customTriggers: List> = emptyList(), +) : CustomTriggeringActionEntry { + override fun execute(player: Player) { + super.execute(player) // This will apply the modifiers. + // Do something with the player + player.triggerCustomTriggers() // Can be called later to trigger the next entries. + // highlight-red-end +// highlight-green-start + override val triggers: List> = emptyList(), +) : ActionEntry { + 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() + // highlight-green-end + } +} +``` + +## Dialogue Messenger Changes + +As it was the only place in Typewriter where you had to register something with an annotation, we changed it to allow the DialogueEntry to specify the messengers that it uses. +Additionally, we now need to forward the `context` parameter to the messengers. + +```kotlin showLineNumbers +@Entry("example_dialogue", "An example dialogue entry.", Colors.BLUE, "material-symbols:chat-rounded") +class ExampleDialogueEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + override val modifiers: List = emptyList(), + override val triggers: List> = emptyList(), + override val speaker: Ref = emptyRef(), + @MultiLine + @Placeholder + @Colored + @Help("The text to display to the player.") + val text: String = "", +) : DialogueEntry { + // highlight-green-start + // May return null to skip the dialogue + override fun messenger(player: Player, context: InteractionContext): DialogueMessenger<*>? { + // You can use if statements to return a different messenger depending on different conditions + return ExampleDialogueDialogueMessenger(player, context, this) + } + // highlight-green-end +} + +// highlight-red-start +@Messenger(ExampleDialogueEntry::class) +class ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) : + DialogueMessenger(player, entry) { + + companion object : MessengerFilter { + override fun filter(player: Player, entry: DialogueEntry): Boolean = true + } + // highlight-red-end +// highlight-green-start +class ExampleDialogueDialogueMessenger(player: Player, context: InteractionContext, entry: ExampleDialogueEntry) : + DialogueMessenger(player, context, entry) { +// highlight-green-end + + + // Called every game tick (20 times per second). + // The cycle is a parameter that is incremented every tick, starting at 0. + override fun tick(context: TickContext) { + super.tick(context) + if (state != MessengerState.RUNNING) return + + player.sendMessage("${entry.speakerDisplayName}: ${entry.text}".parsePlaceholders(player).asMini()) + + // When we want the dialogue to end, we can set the state to FINISHED. + state = MessengerState.FINISHED + } +} +``` diff --git a/documentation/plugins/code-snippets/snippets.json b/documentation/plugins/code-snippets/snippets.json index e2de89ffe1..6c3e154b93 100644 --- a/documentation/plugins/code-snippets/snippets.json +++ b/documentation/plugins/code-snippets/snippets.json @@ -1,7 +1,47 @@ { "initializer": { "file": "src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt", - "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Initializer\n\n@Initializer\nobject ExampleInitializer : Initializable {\n override suspend fun initialize() {\n // Do something when the extension is initialized\n }\n\n override suspend fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" + "content": "import com.typewritermc.core.extension.Initializable\nimport com.typewritermc.core.extension.annotations.Singleton\n\n@Singleton\nobject ExampleInitializer : Initializable {\n override suspend fun initialize() {\n // Do something when the extension is initialized\n }\n\n override suspend fun shutdown() {\n // Do something when the extension is shutdown\n }\n}" + }, + "query_multiple": { + "file": "src/main/kotlin/com/typewritermc/example/QueryExample.kt", + "content": " val entries = Query.find()" + }, + "query_multiple_with_filter": { + "file": "src/main/kotlin/com/typewritermc/example/QueryExample.kt", + "content": " val entries = Query.findWhere {\n it.someField == \"some value\"\n }" + }, + "query_by_id": { + "file": "src/main/kotlin/com/typewritermc/example/QueryExample.kt", + "content": " val id = \"some_id\"\n val entry = Query.findById(id)" + }, + "query_from_page": { + "file": "src/main/kotlin/com/typewritermc/example/QueryExample.kt", + "content": " val pageId = \"some_page_id\"\n val entries = Query.findWhereFromPage(pageId) {\n it.someField == \"some value\"\n }" + }, + "trigger_without_context": { + "file": "src/main/kotlin/com/typewritermc/example/TriggerExample.kt", + "content": " // If you only have one entry\n val triggerEntry: TriggerEntry = Query.findById(\"some_id\") ?: return\n // Triggers all the next entries in the sequence.\n triggerEntry.triggerAllFor(player, context())\n\n // If you have multiple entries\n val triggerEntries: Sequence = Query.find()\n // Triggers all the next entries for all entries.\n triggerEntries.triggerAllFor(player, context())" + }, + "start_dialogue_with_or_trigger": { + "file": "src/main/kotlin/com/typewritermc/example/TriggerExample.kt", + "content": " val triggerEntries: Sequence = Query.find()\n triggerEntries.startDialogueWithOrNextDialogue(player, context())\n\n // Or trigger something completely different when the player is in dialogue:\n val customTrigger: EventTrigger = InteractionEndTrigger\n triggerEntries.startDialogueWithOrTrigger(player, customTrigger, context())" + }, + "trigger_with_context": { + "file": "src/main/kotlin/com/typewritermc/example/TriggerExample.kt", + "content": " // The context that you have, most likely provided by Typewriter in some way.\n val context = player.interactionContext ?: context()\n // Triggers all the next entries in the sequence.\n triggerEntries.triggerAllFor(player, context)" + }, + "interaction_triggers": { + "file": "src/main/kotlin/com/typewritermc/example/TriggerExample.kt", + "content": " // Indicates that the current interaction should be ended\n InteractionEndTrigger.triggerFor(player, context())" + }, + "dialogue_triggers": { + "file": "src/main/kotlin/com/typewritermc/example/TriggerExample.kt", + "content": " // Next dialogue should be triggered or the current dialogue should complete its typing animation.\n DialogueTrigger.NEXT_OR_COMPLETE.triggerFor(player, context())\n\n // Forces the next dialogue to be triggered, even if the animation hasn't finished.\n DialogueTrigger.FORCE_NEXT.triggerFor(player, context())" + }, + "temporal_triggers": { + "file": "src/main/kotlin/com/typewritermc/example/TriggerExample.kt", + "content": " // To start a temporal sequence\n TemporalStartTrigger(\n pageId = \"some_id\",\n eventTriggers = listOf(),\n settings = TemporalSettings(\n blockChatMessages = true,\n blockActionBarMessages = true\n )\n ).triggerFor(player, context())\n\n // To stop the temporal sequence and trigger the following entries.\n TemporalStopTrigger.triggerFor(player, player.interactionContext ?: context())" }, "simple_placeholder_entry": { "file": "src/main/kotlin/com/typewritermc/example/entries/ExamplePlaceholderEntry.kt", @@ -37,7 +77,7 @@ }, "cinematic_simple_action": { "file": "src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt", - "content": "class ExampleSimpleTemporalAction(\n val player: Player,\n entry: ExampleCinematicEntry,\n) : SimpleTemporalAction() {\n override val segments: List = entry.segments\n\n override suspend fun startSegment(segment: ExampleSegment) {\n super.startSegment(segment) // Keep this\n // Called when a segment starts\n }\n\n override suspend fun tickSegment(segment: ExampleSegment, frame: Int) {\n super.tickSegment(segment, frame) // Keep this\n // Called every tick while the segment is active\n // Will always be called after startSegment and never after stopSegment\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n }\n\n override suspend fun stopSegment(segment: ExampleSegment) {\n super.stopSegment(segment) // Keep this\n // Called when the segment ends\n // Will also be called if the cinematic is stopped early\n }\n}" + "content": "class ExampleSimpleTemporalAction(\n val player: Player,\n entry: ExampleCinematicEntry,\n) : SimpleCinematicAction() {\n override val segments: List = entry.segments\n\n override suspend fun startSegment(segment: ExampleSegment) {\n super.startSegment(segment) // Keep this\n // Called when a segment starts\n }\n\n override suspend fun tickSegment(segment: ExampleSegment, frame: Int) {\n super.tickSegment(segment, frame) // Keep this\n // Called every tick while the segment is active\n // Will always be called after startSegment and never after stopSegment\n\n // The `frame` parameter is not necessarily next frame: `frame != old(frame)+1`\n }\n\n override suspend fun stopSegment(segment: ExampleSegment) {\n super.stopSegment(segment) // Keep this\n // Called when the segment ends\n // Will also be called if the cinematic is stopped early\n }\n}" }, "audience_entry": { "file": "src/main/kotlin/com/typewritermc/example/entries/manifest/ExampleAudienceEntry.kt", @@ -101,23 +141,23 @@ }, "variable_usage": { "file": "src/main/kotlin/com/typewritermc/example/entries/static/ExampleVariableEntry.kt", - "content": "@Entry(\"example_action_using_variable\", \"An example action that uses a variable.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionUsingVariableEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n val someString: Var = ConstVar(\"\"),\n val someInt: Var = ConstVar(0),\n) : ActionEntry {\n override fun execute(player: Player) {\n val someString = someString.get(player)\n val someInt = someInt.get(player)\n\n // Do something with the variables\n }\n}" + "content": "@Entry(\"example_action_using_variable\", \"An example action that uses a variable.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionUsingVariableEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n val someString: Var = ConstVar(\"\"),\n val someInt: Var = ConstVar(0),\n) : ActionEntry {\n override fun ActionTrigger.execute() {\n val someString = someString.get(player)\n val someInt = someInt.get(player)\n\n // Do something with the variables\n }\n}" }, "action_entry": { "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt", - "content": "@Entry(\"example_action\", \"An example action entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n) : ActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply all the modifiers.\n // Do something with the player\n }\n}" + "content": "@Entry(\"example_action\", \"An example action entry.\", Colors.RED, \"material-symbols:touch-app-rounded\")\nclass ExampleActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n) : ActionEntry {\n override fun ActionTrigger.execute() {\n // Do something with the player\n }\n}" }, - "custom_triggering_action_entry": { - "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt", - "content": "@Entry(\n \"example_custom_triggering_action\",\n \"An example custom triggering entry.\",\n Colors.RED,\n \"material-symbols:touch-app-rounded\"\n)\nclass ExampleCustomTriggeringActionEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n @SerializedName(\"triggers\")\n override val customTriggers: List> = emptyList(),\n) : CustomTriggeringActionEntry {\n override fun execute(player: Player) {\n super.execute(player) // This will apply the modifiers.\n // Do something with the player\n player.triggerCustomTriggers() // Can be called later to trigger the next entries.\n }\n}" + "action_entry_manual": { + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt", + "content": " override fun ActionTrigger.execute() {\n // This disables Typewriter's automatic triggering of the next entries,\n // and disables the automatic apply of the modifiers.\n disableAutomaticTriggering()\n\n // Now you can manually trigger the next entries.\n triggerManually()\n\n // Or if you want to specify which triggers to trigger, you can do so.\n triggers.filterIndexed { index, _ -> index % 2 == 0 }.triggerFor(player)\n\n // You can also manually apply the modifiers.\n applyModifiers()\n }" }, "dialogue_entry": { "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", - "content": "@Entry(\"example_dialogue\", \"An example dialogue entry.\", Colors.BLUE, \"material-symbols:chat-rounded\")\nclass ExampleDialogueEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n override val speaker: Ref = emptyRef(),\n @MultiLine\n @Placeholder\n @Colored\n @Help(\"The text to display to the player.\")\n val text: String = \"\",\n) : DialogueEntry" + "content": "@Entry(\"example_dialogue\", \"An example dialogue entry.\", Colors.BLUE, \"material-symbols:chat-rounded\")\nclass ExampleDialogueEntry(\n override val id: String = \"\",\n override val name: String = \"\",\n override val criteria: List = emptyList(),\n override val modifiers: List = emptyList(),\n override val triggers: List> = emptyList(),\n override val speaker: Ref = emptyRef(),\n @MultiLine\n @Placeholder\n @Colored\n @Help(\"The text to display to the player.\")\n val text: String = \"\",\n) : DialogueEntry {\n // May return null to skip the dialogue\n override fun messenger(player: Player, context: InteractionContext): DialogueMessenger<*>? {\n // You can use if statements to return a different messenger depending on different conditions\n return ExampleDialogueDialogueMessenger(player, context, this)\n }\n}" }, "dialogue_messenger": { "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt", - "content": "@Messenger(ExampleDialogueEntry::class)\nclass ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) :\n DialogueMessenger(player, entry) {\n\n companion object : MessengerFilter {\n override fun filter(player: Player, entry: DialogueEntry): Boolean = true\n }\n\n // Called every game tick (20 times per second).\n // The cycle is a parameter that is incremented every tick, starting at 0.\n override fun tick(context: TickContext) {\n super.tick(context)\n if (state != MessengerState.RUNNING) return\n\n player.sendMessage(\"${entry.speakerDisplayName}: ${entry.text}\".parsePlaceholders(player).asMini())\n\n // When we want the dialogue to end, we can set the state to FINISHED.\n state = MessengerState.FINISHED\n }\n}" + "content": "class ExampleDialogueDialogueMessenger(player: Player, context: InteractionContext, entry: ExampleDialogueEntry) :\n DialogueMessenger(player, context, entry) {\n\n // Called every game tick (20 times per second).\n // The cycle is a parameter that is incremented every tick, starting at 0.\n override fun tick(context: TickContext) {\n super.tick(context)\n if (state != MessengerState.RUNNING) return\n\n player.sendMessage(\"${entry.speakerDisplayName}: ${entry.text}\".parsePlaceholders(player).asMini())\n\n // When we want the dialogue to end, we can set the state to FINISHED.\n state = MessengerState.FINISHED\n }\n}" }, "event_entry": { "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", @@ -125,6 +165,10 @@ }, "event_entry_listener": { "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", - "content": "// Must be scoped to be public\n@EntryListener(ExampleEventEntry::class)\nfun onEvent(event: SomeBukkitEvent, query: Query) {\n // Do something\n val entries = query.find() // Find all the entries of this type, for more information see the Query section\n // Do something with the entries, for example trigger them\n entries triggerAllFor event.player\n}" + "content": "@EntryListener(ExampleEventEntry::class)\nfun onEvent(event: SomeBukkitEvent, query: Query) {\n // Do something\n val entries = query.find() // Find all the entries of this type, for more information see the Query section\n // Do something with the entries, for example trigger them\n entries.triggerAllFor(event.player, context())\n}" + }, + "event_entry_with_context_keys": { + "file": "src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt", + "content": "@Entry(\"example_event_with_context_keys\", \"An example event entry with context keys.\", Colors.YELLOW, \"material-symbols:bigtop-updates\")\n// This tells Typewriter that this entry exposes some context\n@ContextKeys(ExampleContextKeys::class)\nclass ExampleEventEntryWithContextKeys(\n override val id: String = \"\",\n override val name: String = \"\",\n override val triggers: List> = emptyList(),\n) : EventEntry\n\nenum class ExampleContextKeys(override val klass: KClass<*>) : EntryContextKey {\n // The two `String::class` have to be the same.\n // The @KeyType is for the panel to know\n @KeyType(String::class)\n // The type here is for casting during runtime\n TEXT(String::class),\n\n @KeyType(Int::class)\n NUMBER(Int::class),\n\n // More complex types are also allowed.\n @KeyType(Position::class)\n POSITION(Position::class)\n}\n\n@EntryListener(ExampleEventEntryWithContextKeys::class)\nfun onEventAddContext(event: SomeBukkitEvent, query: Query) {\n val entries = query.find()\n entries.triggerAllFor(event.player) {\n // Make sure these values are drawn from the event.\n // You MUST supply all the context keys.\n ExampleContextKeys.TEXT withValue \"Hello World\"\n ExampleContextKeys.NUMBER withValue 42\n ExampleContextKeys.POSITION withValue Position.ORIGIN\n }\n}" } } \ No newline at end of file diff --git a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/temporal/SimpleTemporalAction.kt b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/temporal/SimpleCinematicAction.kt similarity index 95% rename from engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/temporal/SimpleTemporalAction.kt rename to engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/temporal/SimpleCinematicAction.kt index 8918c0cb83..834ec27715 100644 --- a/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/temporal/SimpleTemporalAction.kt +++ b/engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/entry/temporal/SimpleCinematicAction.kt @@ -5,7 +5,7 @@ import com.typewritermc.engine.paper.entry.entries.Segment import com.typewritermc.engine.paper.entry.entries.activeSegmentAt import com.typewritermc.engine.paper.entry.entries.canFinishAt -abstract class SimpleTemporalAction : CinematicAction { +abstract class SimpleCinematicAction : CinematicAction { protected var lastFrame = 0 private set private var previousSegment: S? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt index 5a7f20131c..bcb6d5401d 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlindingCinematicEntry.kt @@ -10,7 +10,7 @@ import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.EmptyCinematicAction import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo import com.typewritermc.engine.paper.utils.isFloodgate import org.bukkit.entity.Player @@ -48,7 +48,7 @@ data class BlindingSegment( class BlindingCinematicAction( private val player: Player, entry: BlindingCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments override suspend fun tickSegment(segment: BlindingSegment, frame: Int) { diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlockCommandCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlockCommandCinematicEntry.kt index ae15490e74..7664edb323 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlockCommandCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/BlockCommandCinematicEntry.kt @@ -12,7 +12,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.CinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.interaction.InterceptionBundle import com.typewritermc.engine.paper.interaction.interceptPackets import com.typewritermc.engine.paper.utils.ThreadType @@ -49,7 +49,7 @@ data class BlockCommandSegment( class BlockCommandCinematicAction( private val player: Player, entry: BlockCommandCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var bundle: InterceptionBundle? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt index 46ad4a7504..20c9e21e26 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CameraCinematicEntry.kt @@ -14,7 +14,7 @@ import com.typewritermc.core.interaction.InteractionBoundStateOverrideSubscripti import com.typewritermc.core.utils.point.Position import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.packetevents.meta import com.typewritermc.engine.paper.extensions.packetevents.spectateEntity import com.typewritermc.engine.paper.extensions.packetevents.stopSpectatingEntity @@ -426,7 +426,7 @@ private class TeleportCameraAction( class SimulatedCameraCinematicAction( private val player: Player, private val entry: CameraCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private val paths = entry.segments.associateWith { segment -> diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt index b461244afc..0bbd05ecbe 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/CinematicCommandEntry.kt @@ -6,7 +6,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.CinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders import com.typewritermc.engine.paper.plugin import com.typewritermc.engine.paper.utils.ThreadType.SYNC @@ -94,7 +94,7 @@ class CommandAction( private val player: Player, entry: CinematicCommandEntry, private val run: (String) -> Unit, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments override suspend fun startSegment(segment: CommandSegment) { diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameTimeCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameTimeCinematicEntry.kt index c13dee83c4..d04d3bc580 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameTimeCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameTimeCinematicEntry.kt @@ -10,7 +10,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo import com.typewritermc.engine.paper.interaction.InterceptionBundle import com.typewritermc.engine.paper.interaction.interceptPackets @@ -60,7 +60,7 @@ data class GameTimeSegment( class GameTimeCinematicAction( val player: Player, entry: GameTimeCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var state: PlayerState? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameWeatherCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameWeatherCinematicEntry.kt index ca44f6af4f..19e403a273 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameWeatherCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/GameWeatherCinematicEntry.kt @@ -8,7 +8,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.CinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import org.bukkit.WeatherType import org.bukkit.entity.Player @@ -44,7 +44,7 @@ data class GameWeatherSegment( class GameWeatherCinematicAction( val player: Player, entry: GameWeatherCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments override suspend fun startSegment(segment: GameWeatherSegment) { diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt index 1729d8c5be..67c773e5ff 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PotionEffectCinematicEntry.kt @@ -7,7 +7,7 @@ import com.typewritermc.core.extension.annotations.Help import com.typewritermc.core.extension.annotations.Segments import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.interaction.interactionContext import com.typewritermc.engine.paper.utils.EffectStateProvider import com.typewritermc.engine.paper.utils.PlayerState @@ -62,7 +62,7 @@ data class PotionEffectSegment( class PotionEffectCinematicAction( private val player: Player, entry: PotionEffectCinematicEntry -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { private var state: PlayerState? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt index 9d7eca54b0..1c5a8c203a 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/PumpkinHatCinematicEntry.kt @@ -11,7 +11,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.PrimaryCinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo import com.typewritermc.engine.paper.extensions.packetevents.toPacketItem import com.typewritermc.engine.paper.interaction.InterceptionBundle @@ -54,7 +54,7 @@ data class PumpkinHatSegment( class PumpkinHatCinematicAction( private val player: Player, entry: PumpkinHatCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var interceptor: InterceptionBundle? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt index bd9419c4f7..3caa8708ee 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SetFakeBlockCinematicEntry.kt @@ -8,7 +8,7 @@ import com.typewritermc.core.extension.annotations.Segments import com.typewritermc.core.utils.point.Position import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.packetevents.sendPacketTo import com.typewritermc.engine.paper.interaction.interactionContext import com.typewritermc.engine.paper.utils.toBukkitLocation @@ -41,7 +41,7 @@ data class SetFakeBlockSegment( class SetFakeBlockCinematicAction( private val player: Player, entry: SetFakeBlockCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var lastLocation: Position? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SkipCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SkipCinematicEntry.kt index d47fc358b7..6147400008 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SkipCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SkipCinematicEntry.kt @@ -9,7 +9,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.CinematicEntry import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.entry.temporal.setTemporalFrame import com.typewritermc.engine.paper.interaction.InterceptionBundle import com.typewritermc.engine.paper.interaction.interceptPackets @@ -63,7 +63,7 @@ enum class SkipConfirmationKey(val keybind: String) { class SkipCinematicAction( private val player: Player, val entry: SkipCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var bundle: InterceptionBundle? = null private var listener: Listener? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt index 20471edf0f..4e5de256fc 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/SoundCinematicEntry.kt @@ -5,7 +5,7 @@ import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.core.extension.annotations.Entry import com.typewritermc.core.extension.annotations.Segments import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.utils.* import org.bukkit.entity.Player @@ -41,7 +41,7 @@ data class SoundSegment( class SoundCinematicAction( private val player: Player, entry: SoundCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var previousSound: Sound? = null diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt index 700898306a..fd9f59c540 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TitleCinematicEntry.kt @@ -7,7 +7,7 @@ import com.typewritermc.core.extension.annotations.Entry import com.typewritermc.core.extension.annotations.Segments import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders import com.typewritermc.engine.paper.interaction.interactionContext import com.typewritermc.engine.paper.utils.asMini @@ -52,7 +52,7 @@ data class TitleSegment( class TitleCinematicAction( private val player: Player, entry: TitleCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments diff --git a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt index 29e0c780fb..badf747ada 100644 --- a/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt +++ b/extensions/BasicExtension/src/main/kotlin/com/typewritermc/basic/entries/cinematic/TriggerSequenceCinematicEntry.kt @@ -15,7 +15,7 @@ import com.typewritermc.engine.paper.entry.entries.CinematicAction import com.typewritermc.engine.paper.entry.entries.CinematicEntry import com.typewritermc.engine.paper.entry.entries.EntryTrigger import com.typewritermc.engine.paper.entry.entries.Segment -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.interaction.interactionContext import org.bukkit.entity.Player @@ -57,7 +57,7 @@ data class TriggerSequenceSegment( class TriggerSequenceAction( val player: Player, entry: TriggerSequenceCinematicEntry -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments override suspend fun startSegment(segment: TriggerSequenceSegment) { diff --git a/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/cinematic/EntityCinematicEntry.kt b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/cinematic/EntityCinematicEntry.kt index 932ae4b1a1..0737edd01c 100644 --- a/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/cinematic/EntityCinematicEntry.kt +++ b/extensions/EntityExtension/src/main/kotlin/com/typewritermc/entity/entries/cinematic/EntityCinematicEntry.kt @@ -21,7 +21,7 @@ import com.typewritermc.engine.paper.entry.AssetManager import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entity.* import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.packetevents.ArmSwing import com.typewritermc.engine.paper.extensions.packetevents.toPacketItem import com.typewritermc.engine.paper.utils.toBukkitLocation @@ -95,7 +95,7 @@ class EntityCinematicAction( private val player: Player, private val entry: EntityCinematicEntry, ) : - SimpleTemporalAction() { + SimpleCinematicAction() { private val assetManager: AssetManager by KoinJavaComponent.inject(AssetManager::class.java) private val gson: Gson by KoinJavaComponent.inject(Gson::class.java, named("bukkitDataParser")) diff --git a/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt index 55967d3348..6689d8f540 100644 --- a/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt @@ -8,7 +8,7 @@ import com.typewritermc.core.extension.annotations.WithRotation import com.typewritermc.core.utils.point.Position import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders import com.typewritermc.engine.paper.utils.ThreadType.SYNC import com.typewritermc.engine.paper.utils.toBukkitLocation @@ -53,7 +53,7 @@ data class MythicMobSegment( class MobCinematicAction( private val player: Player, entry: MythicMobCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments private var mob: ActiveMob? = null diff --git a/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt index 5ef4ec090a..d1ea13b641 100644 --- a/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt +++ b/extensions/MythicMobsExtension/src/main/kotlin/com/typewritermc/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt @@ -7,7 +7,7 @@ import com.typewritermc.core.extension.annotations.Max import com.typewritermc.core.extension.annotations.Segments import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.entries.* -import com.typewritermc.engine.paper.entry.temporal.SimpleTemporalAction +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import com.typewritermc.engine.paper.logger import io.lumine.mythic.api.mobs.GenericCaster import io.lumine.mythic.bukkit.BukkitAdapter @@ -55,7 +55,7 @@ data class MythicSkillSegment( class SkillCinematicAction( private val player: Player, entry: MythicSkillCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments override suspend fun startSegment(segment: MythicSkillSegment) { diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt index 2d4a411e76..d99a53204f 100644 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/ExampleInitializer.kt @@ -2,9 +2,9 @@ package com.typewritermc.example // import com.typewritermc.core.extension.Initializable -import com.typewritermc.core.extension.annotations.Initializer +import com.typewritermc.core.extension.annotations.Singleton -@Initializer +@Singleton object ExampleInitializer : Initializable { override suspend fun initialize() { // Do something when the extension is initialized diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/QueryExample.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/QueryExample.kt new file mode 100644 index 0000000000..d75616f516 --- /dev/null +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/QueryExample.kt @@ -0,0 +1,40 @@ +package com.typewritermc.example + +import com.typewritermc.core.entries.Entry +import com.typewritermc.core.entries.Query + +fun queryExample() { + // + val entries = Query.find() + // +} + +fun queryExampleWithFilter() { + // + val entries = Query.findWhere { + it.someField == "some value" + } + // +} + +fun queryExampleWithoutFilter() { + // + val id = "some_id" + val entry = Query.findById(id) + // +} + +fun queryExampleFromPage() { + // + val pageId = "some_page_id" + val entries = Query.findWhereFromPage(pageId) { + it.someField == "some value" + } + // +} + +class MyEntry( + override val id: String = "", + override val name: String = "", + val someField: String = "", +) : Entry \ No newline at end of file diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/TriggerExample.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/TriggerExample.kt new file mode 100644 index 0000000000..534ffaf052 --- /dev/null +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/TriggerExample.kt @@ -0,0 +1,91 @@ +package com.typewritermc.example + +import com.typewritermc.core.entries.Query +import com.typewritermc.core.entries.Ref +import com.typewritermc.core.interaction.context +import com.typewritermc.engine.paper.entry.* +import com.typewritermc.engine.paper.entry.dialogue.DialogueTrigger +import com.typewritermc.engine.paper.entry.entries.EventTrigger +import com.typewritermc.engine.paper.entry.entries.InteractionEndTrigger +import com.typewritermc.engine.paper.entry.temporal.TemporalSettings +import com.typewritermc.engine.paper.entry.temporal.TemporalStartTrigger +import com.typewritermc.engine.paper.entry.temporal.TemporalStopTrigger +import com.typewritermc.engine.paper.interaction.interactionContext +import org.bukkit.entity.Player + +fun triggerSingleEntry(player: Player) { + // + // If you only have one entry + val triggerEntry: TriggerEntry = Query.findById("some_id") ?: return + // Triggers all the next entries in the sequence. + triggerEntry.triggerAllFor(player, context()) + + // If you have multiple entries + val triggerEntries: Sequence = Query.find() + // Triggers all the next entries for all entries. + triggerEntries.triggerAllFor(player, context()) + // +} + +fun startDialogueWithOrNextDialogue(player: Player) { + // + val triggerEntries: Sequence = Query.find() + triggerEntries.startDialogueWithOrNextDialogue(player, context()) + + // Or trigger something completely different when the player is in dialogue: + val customTrigger: EventTrigger = InteractionEndTrigger + triggerEntries.startDialogueWithOrTrigger(player, customTrigger, context()) + // +} + +fun triggerWithContext(player: Player) { + val triggerEntries: Sequence = Query.find() + // + // The context that you have, most likely provided by Typewriter in some way. + val context = player.interactionContext ?: context() + // Triggers all the next entries in the sequence. + triggerEntries.triggerAllFor(player, context) + // +} + +fun interactionTriggers(player: Player) { + // + // Indicates that the current interaction should be ended + InteractionEndTrigger.triggerFor(player, context()) + // +} + +fun dialogueTriggers(player: Player) { + // + // Next dialogue should be triggered or the current dialogue should complete its typing animation. + DialogueTrigger.NEXT_OR_COMPLETE.triggerFor(player, context()) + + // Forces the next dialogue to be triggered, even if the animation hasn't finished. + DialogueTrigger.FORCE_NEXT.triggerFor(player, context()) + // +} + +fun temporalTriggers(player: Player) { + // + // To start a temporal sequence + TemporalStartTrigger( + pageId = "some_id", + eventTriggers = listOf(), + settings = TemporalSettings( + blockChatMessages = true, + blockActionBarMessages = true + ) + ).triggerFor(player, context()) + + // To stop the temporal sequence and trigger the following entries. + TemporalStopTrigger.triggerFor(player, player.interactionContext ?: context()) + // +} + +class MyTriggerableEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + override val modifiers: List = emptyList(), + override val triggers: List> = emptyList(), +) : TriggerableEntry \ No newline at end of file diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt index f2c30b5dfe..c7ebc6287d 100644 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/cinematic/ExampleCinematicEntry.kt @@ -1,11 +1,10 @@ package com.typewritermc.example.entries.cinematic import com.typewritermc.core.books.pages.Colors -import com.typewritermc.core.extension.annotations.Entry import com.typewritermc.core.extension.annotations.* import com.typewritermc.engine.paper.entry.Criteria -import com.typewritermc.engine.paper.entry.cinematic.SimpleTemporalAction import com.typewritermc.engine.paper.entry.entries.* +import com.typewritermc.engine.paper.entry.temporal.SimpleCinematicAction import org.bukkit.entity.Player // @@ -97,7 +96,7 @@ class ExampleCinematicAction( class ExampleSimpleTemporalAction( val player: Player, entry: ExampleCinematicEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments override suspend fun startSegment(segment: ExampleSegment) { @@ -124,20 +123,20 @@ class ExampleSimpleTemporalAction( class DefaultCinematicAction( val player: Player, entry: ExampleWithSegmentSizesEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments } class SimulatedCinematicAction( val player: Player, entry: ExampleWithSegmentSizesEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments } class RecordingCinematicAction( val player: Player, entry: ExampleWithSegmentSizesEntry, -) : SimpleTemporalAction() { +) : SimpleCinematicAction() { override val segments: List = entry.segments } \ No newline at end of file diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleVariableEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleVariableEntry.kt index f21f17ed25..36680642ee 100644 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleVariableEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/static/ExampleVariableEntry.kt @@ -112,7 +112,7 @@ class ExampleActionUsingVariableEntry( val someString: Var = ConstVar(""), val someInt: Var = ConstVar(0), ) : ActionEntry { - override fun execute(player: Player) { + override fun ActionTrigger.execute() { val someString = someString.get(player) val someInt = someInt.get(player) diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt index fd5ed764a0..18cb6f74dc 100644 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleActionEntry.kt @@ -7,6 +7,7 @@ import com.typewritermc.engine.paper.entry.Modifier import com.typewritermc.core.entries.Ref import com.typewritermc.engine.paper.entry.TriggerableEntry import com.typewritermc.engine.paper.entry.entries.ActionEntry +import com.typewritermc.engine.paper.entry.entries.ActionTrigger import org.bukkit.entity.Player // @@ -18,9 +19,34 @@ class ExampleActionEntry( override val modifiers: List = emptyList(), override val triggers: List> = emptyList(), ) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) // This will apply all the modifiers. + override fun ActionTrigger.execute() { // Do something with the player } } -// \ No newline at end of file +// + +@Entry("example_action_manual_trigger", "An example action entry with a manual trigger.", Colors.RED, "material-symbols:touch-app-rounded") +class ExampleActionEntryManualTrigger( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + override val modifiers: List = emptyList(), + override val triggers: List> = emptyList(), +) : ActionEntry { + // + 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() + } + // +} \ No newline at end of file diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt deleted file mode 100644 index f1d674a419..0000000000 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleCustomTriggeringActionEntry.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.typewritermc.example.entries.trigger - -import com.google.gson.annotations.SerializedName -import com.typewritermc.core.books.pages.Colors -import com.typewritermc.core.entries.Ref -import com.typewritermc.core.extension.annotations.Entry -import com.typewritermc.engine.paper.entry.Criteria -import com.typewritermc.engine.paper.entry.Modifier -import com.typewritermc.engine.paper.entry.TriggerableEntry -import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry -import org.bukkit.entity.Player - -// -@Entry( - "example_custom_triggering_action", - "An example custom triggering entry.", - Colors.RED, - "material-symbols:touch-app-rounded" -) -class ExampleCustomTriggeringActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - @SerializedName("triggers") - override val customTriggers: List> = emptyList(), -) : CustomTriggeringActionEntry { - override fun execute(player: Player) { - super.execute(player) // This will apply the modifiers. - // Do something with the player - player.triggerCustomTriggers() // Can be called later to trigger the next entries. - } -} -// \ No newline at end of file diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt index be7f9f08b4..c66991b3c2 100644 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleDialogueEntry.kt @@ -4,11 +4,11 @@ import com.typewritermc.core.books.pages.Colors import com.typewritermc.core.entries.Ref import com.typewritermc.core.entries.emptyRef import com.typewritermc.core.extension.annotations.* +import com.typewritermc.core.interaction.InteractionContext import com.typewritermc.engine.paper.entry.Criteria import com.typewritermc.engine.paper.entry.Modifier import com.typewritermc.engine.paper.entry.TriggerableEntry import com.typewritermc.engine.paper.entry.dialogue.DialogueMessenger -import com.typewritermc.engine.paper.entry.dialogue.MessengerFilter import com.typewritermc.engine.paper.entry.dialogue.MessengerState import com.typewritermc.engine.paper.entry.dialogue.TickContext import com.typewritermc.engine.paper.entry.entries.DialogueEntry @@ -16,7 +16,6 @@ import com.typewritermc.engine.paper.entry.entries.SpeakerEntry import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders import com.typewritermc.engine.paper.utils.asMini import org.bukkit.entity.Player -import java.time.Duration // @Entry("example_dialogue", "An example dialogue entry.", Colors.BLUE, "material-symbols:chat-rounded") @@ -32,17 +31,18 @@ class ExampleDialogueEntry( @Colored @Help("The text to display to the player.") val text: String = "", -) : DialogueEntry +) : DialogueEntry { + // May return null to skip the dialogue + override fun messenger(player: Player, context: InteractionContext): DialogueMessenger<*>? { + // You can use if statements to return a different messenger depending on different conditions + return ExampleDialogueDialogueMessenger(player, context, this) + } +} // // -@Messenger(ExampleDialogueEntry::class) -class ExampleDialogueDialogueMessenger(player: Player, entry: ExampleDialogueEntry) : - DialogueMessenger(player, entry) { - - companion object : MessengerFilter { - override fun filter(player: Player, entry: DialogueEntry): Boolean = true - } +class ExampleDialogueDialogueMessenger(player: Player, context: InteractionContext, entry: ExampleDialogueEntry) : + DialogueMessenger(player, context, entry) { // Called every game tick (20 times per second). // The cycle is a parameter that is incremented every tick, starting at 0. diff --git a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt index efc6d194fe..5edeab5376 100644 --- a/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt +++ b/extensions/_DocsExtension/src/main/kotlin/com/typewritermc/example/entries/trigger/ExampleEventEntry.kt @@ -3,14 +3,20 @@ package com.typewritermc.example.entries.trigger import com.typewritermc.core.books.pages.Colors import com.typewritermc.core.entries.Query import com.typewritermc.core.entries.Ref +import com.typewritermc.core.extension.annotations.ContextKeys import com.typewritermc.core.extension.annotations.Entry import com.typewritermc.core.extension.annotations.EntryListener +import com.typewritermc.core.extension.annotations.KeyType +import com.typewritermc.core.interaction.EntryContextKey +import com.typewritermc.core.interaction.context +import com.typewritermc.core.utils.point.Position import com.typewritermc.engine.paper.entry.TriggerableEntry import com.typewritermc.engine.paper.entry.entries.EventEntry import com.typewritermc.engine.paper.entry.triggerAllFor import org.bukkit.entity.Player import org.bukkit.event.HandlerList import org.bukkit.event.player.PlayerEvent +import kotlin.reflect.KClass // @Entry("example_event", "An example event entry.", Colors.YELLOW, "material-symbols:bigtop-updates") @@ -22,16 +28,53 @@ class ExampleEventEntry( // // -// Must be scoped to be public @EntryListener(ExampleEventEntry::class) fun onEvent(event: SomeBukkitEvent, query: Query) { // Do something val entries = query.find() // Find all the entries of this type, for more information see the Query section // Do something with the entries, for example trigger them - entries triggerAllFor event.player + entries.triggerAllFor(event.player, context()) } // +// +@Entry("example_event_with_context_keys", "An example event entry with context keys.", Colors.YELLOW, "material-symbols:bigtop-updates") +// This tells Typewriter that this entry exposes some context +@ContextKeys(ExampleContextKeys::class) +class ExampleEventEntryWithContextKeys( + override val id: String = "", + override val name: String = "", + override val triggers: List> = emptyList(), +) : EventEntry + +enum class ExampleContextKeys(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) +} + +@EntryListener(ExampleEventEntryWithContextKeys::class) +fun onEventAddContext(event: SomeBukkitEvent, query: Query) { + val entries = query.find() + entries.triggerAllFor(event.player) { + // Make sure these values are drawn from the event. + // You MUST supply all the context keys. + ExampleContextKeys.TEXT withValue "Hello World" + ExampleContextKeys.NUMBER withValue 42 + ExampleContextKeys.POSITION withValue Position.ORIGIN + } +} +// + class SomeBukkitEvent(player: Player) : PlayerEvent(player) { override fun getHandlers(): HandlerList = HANDLER_LIST @@ -39,4 +82,4 @@ class SomeBukkitEvent(player: Player) : PlayerEvent(player) { @JvmStatic val HANDLER_LIST = HandlerList() } -} \ No newline at end of file +}