From bfa423a5baebbfe5c585556bc1b9d4542c344cb4 Mon Sep 17 00:00:00 2001 From: Gabber235 Date: Fri, 12 Jan 2024 18:18:59 +0100 Subject: [PATCH] Add skills and cinematics for mythic mobs --- .../entries/cinematic/TitleCinematicEntry.kt | 12 +-- .../mythicmobs/MythicMobsAdapter.kt | 1 - .../entries/action/ExecuteSkillActionEntry.kt | 50 ++++++++++ .../cinematic/MythicMobCinematicEntry.kt | 96 +++++++++++++++++++ .../cinematic/MythicSkillCinematicEntry.kt | 82 ++++++++++++++++ .../MythicMobsAdapter/MythicMobsAdapter.mdx | 8 ++ .../action/execute_mythicmob_skill.mdx | 21 ++++ .../entries/cinematic/_category_.yml | 1 + .../entries/cinematic/mythicmob_cinematic.mdx | 18 ++++ .../cinematic/mythicskill_cinematic.mdx | 27 ++++++ 10 files changed, 309 insertions(+), 7 deletions(-) create mode 100644 adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt create mode 100644 adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt create mode 100644 adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt create mode 100644 documentation/docs/adapters/MythicMobsAdapter/entries/action/execute_mythicmob_skill.mdx create mode 100644 documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/_category_.yml create mode 100644 documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicmob_cinematic.mdx create mode 100644 documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicskill_cinematic.mdx diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt index 9f97117e91..412271f36d 100644 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt +++ b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt @@ -26,11 +26,11 @@ import java.time.Duration * This entry could be used to show a title during a cinematic, such as a title for a cutscene. */ class TitleCinematicEntry( - override val id: String, - override val name: String, - override val criteria: List, + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), @Segments(icon = Icons.PARAGRAPH) - val segments: List, + val segments: List = emptyList(), ) : CinematicEntry { override fun create(player: Player): CinematicAction { return TitleCinematicAction( @@ -41,8 +41,8 @@ class TitleCinematicEntry( } data class TitleSegment( - override val startFrame: Int, - override val endFrame: Int, + override val startFrame: Int = 0, + override val endFrame: Int = 0, @Help("The title to show") val title: String = "", @Help("The subtitle to show") diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt index 510c293db7..1a117b8cd3 100644 --- a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt +++ b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/MythicMobsAdapter.kt @@ -20,5 +20,4 @@ object MythicMobsAdapter : TypewriteAdapter() { return } } - } \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt new file mode 100644 index 0000000000..f1a9b8672f --- /dev/null +++ b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/action/ExecuteSkillActionEntry.kt @@ -0,0 +1,50 @@ +package me.ahdg6.typewriter.mythicmobs.entries.action + +import io.lumine.mythic.api.mobs.GenericCaster +import io.lumine.mythic.bukkit.BukkitAdapter +import io.lumine.mythic.bukkit.MythicBukkit +import io.lumine.mythic.core.skills.SkillMetadataImpl +import io.lumine.mythic.core.skills.SkillTriggers +import me.gabber235.typewriter.adapters.Colors +import me.gabber235.typewriter.adapters.Entry +import me.gabber235.typewriter.adapters.modifiers.Help +import me.gabber235.typewriter.entry.Criteria +import me.gabber235.typewriter.entry.Modifier +import me.gabber235.typewriter.entry.entries.ActionEntry +import me.gabber235.typewriter.logger +import me.gabber235.typewriter.utils.Icons +import org.bukkit.entity.Player + +@Entry("execute_mythicmob_skill", "Executes a MythicMobs skill", Colors.RED, Icons.BOLT_LIGHTNING) +/** + * The `Execute Skill Action` action executes a MythicMobs skill. + * + * ## How could this be used? + * Create fancy particle animations. + * For example, you can create a little animation when a player opens a door. + */ +class ExecuteSkillActionEntry( + override val id: String = "", + override val name: String = "", + override val triggers: List = emptyList(), + override val criteria: List = emptyList(), + override val modifiers: List = emptyList(), + @Help("The name of the skill to execute") + val skillName: String = "", +) : ActionEntry { + override fun execute(player: Player) { + super.execute(player) + + val skill = MythicBukkit.inst().skillManager.getSkill(skillName).orElseGet { + throw IllegalArgumentException("Skill $skillName not found") + } + val trigger = BukkitAdapter.adapt(player) + val caster = GenericCaster(trigger) + + val skillMeta = + SkillMetadataImpl(SkillTriggers.API, caster, trigger) + + if (skill.isUsable(skillMeta)) skill.execute(skillMeta) + else logger.warning("Skill $skillName is not usable at this time (cooldown, etc.)") + } +} \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt new file mode 100644 index 0000000000..99ec7ada29 --- /dev/null +++ b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicMobCinematicEntry.kt @@ -0,0 +1,96 @@ +package me.ahdg6.typewriter.mythicmobs.entries.cinematic + +import com.github.shynixn.mccoroutine.bukkit.minecraftDispatcher +import io.lumine.mythic.api.mobs.GenericCaster +import io.lumine.mythic.bukkit.BukkitAdapter +import io.lumine.mythic.bukkit.MythicBukkit +import io.lumine.mythic.core.mobs.ActiveMob +import io.lumine.mythic.core.skills.SkillMetadataImpl +import io.lumine.mythic.core.skills.SkillTriggers +import kotlinx.coroutines.withContext +import lirand.api.extensions.server.server +import me.gabber235.typewriter.adapters.Colors +import me.gabber235.typewriter.adapters.Entry +import me.gabber235.typewriter.adapters.modifiers.Help +import me.gabber235.typewriter.adapters.modifiers.Segments +import me.gabber235.typewriter.entry.Criteria +import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction +import me.gabber235.typewriter.entry.entries.CinematicAction +import me.gabber235.typewriter.entry.entries.CinematicEntry +import me.gabber235.typewriter.entry.entries.Segment +import me.gabber235.typewriter.plugin +import me.gabber235.typewriter.utils.Icons +import org.bukkit.Location +import org.bukkit.entity.Player + +@Entry("mythicmob_cinematic", "Spawn a MythicMob during a cinematic", Colors.PURPLE, Icons.DRAGON) +/** + * The `Spawn MythicMob Cinematic` cinematic entry spawns a MythicMob during a cinematic. + * + * ## How could this be used? + * + * This can be used to animate a MythicMob spawning during a cinematic. + */ +class MythicMobCinematicEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + @Segments(Colors.PURPLE, Icons.DRAGON) + val segments: List = emptyList(), +) : CinematicEntry { + override fun create(player: Player): CinematicAction { + return MobCinematicAction(player, this) + } +} + +data class MythicMobSegment( + override val startFrame: Int = 0, + override val endFrame: Int = 0, + @Help("The name of the mob to spawn") + val mobName: String = "", + @Help("The location to spawn the mob at") + val location: Location = Location(null, 0.0, 0.0, 0.0), +) : Segment + +class MobCinematicAction( + private val player: Player, + entry: MythicMobCinematicEntry, +) : SimpleCinematicAction() { + override val segments: List = entry.segments + + private var mob: ActiveMob? = null + + override suspend fun startSegment(segment: MythicMobSegment) { + super.startSegment(segment) + + withContext(plugin.minecraftDispatcher) { + val mob = MythicBukkit.inst().mobManager.spawnMob(segment.mobName, segment.location) + this@MobCinematicAction.mob = mob + val hideMechanic = MythicBukkit.inst().skillManager.getMechanic("hide") + + val targets = + server.onlinePlayers.filter { it.uniqueId != player.uniqueId }.map { BukkitAdapter.adapt(it) }.toSet() + + val skillMeta = SkillMetadataImpl( + SkillTriggers.API, + GenericCaster(mob.entity), + mob.entity, + mob.location, + targets, + null, + 1f + ) + + hideMechanic.execute(skillMeta) + } + } + + override suspend fun stopSegment(segment: MythicMobSegment) { + super.stopSegment(segment) + + mob?.let { + it.despawn() + mob = null + } + } +} \ No newline at end of file diff --git a/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt new file mode 100644 index 0000000000..1f3e6df554 --- /dev/null +++ b/adapters/MythicMobsAdapter/src/main/kotlin/me/ahdg6/typewriter/mythicmobs/entries/cinematic/MythicSkillCinematicEntry.kt @@ -0,0 +1,82 @@ +package me.ahdg6.typewriter.mythicmobs.entries.cinematic + +import io.lumine.mythic.api.mobs.GenericCaster +import io.lumine.mythic.bukkit.BukkitAdapter +import io.lumine.mythic.bukkit.MythicBukkit +import io.lumine.mythic.core.skills.SkillMetadataImpl +import io.lumine.mythic.core.skills.SkillTriggers +import me.gabber235.typewriter.adapters.Colors +import me.gabber235.typewriter.adapters.Entry +import me.gabber235.typewriter.adapters.modifiers.Help +import me.gabber235.typewriter.adapters.modifiers.InnerMax +import me.gabber235.typewriter.adapters.modifiers.Max +import me.gabber235.typewriter.adapters.modifiers.Segments +import me.gabber235.typewriter.entry.Criteria +import me.gabber235.typewriter.entry.cinematic.SimpleCinematicAction +import me.gabber235.typewriter.entry.entries.CinematicAction +import me.gabber235.typewriter.entry.entries.CinematicEntry +import me.gabber235.typewriter.entry.entries.Segment +import me.gabber235.typewriter.logger +import me.gabber235.typewriter.utils.Icons +import org.bukkit.entity.Player + +@Entry("mythicskill_cinematic", "Spawn a MythicMob during a cinematic", Colors.PURPLE, Icons.BOLT_LIGHTNING) +/** + * The `Mythic Skill Cinematic` cinematic entry triggers a skill during a cinematic. + * + * :::caution + * A skill itself needs to define the audience to be self using `audience=self` + * + * ### Example: + * ``` + * - effect:particlesphere{particle=flame;amount=200;radius=2;audience=self} @self + * ``` + * ::: + * + * ## How could this be used? + * + * This can be used to animate fancy particle effects during a cinematic. + */ +class MythicSkillCinematicEntry( + override val id: String = "", + override val name: String = "", + override val criteria: List = emptyList(), + @Segments(Colors.PURPLE, Icons.BOLT_LIGHTNING) + @InnerMax(Max(1)) + val segments: List = emptyList(), +) : CinematicEntry { + override fun create(player: Player): CinematicAction { + return SkillCinematicAction(player, this) + } +} + +data class MythicSkillSegment( + override val startFrame: Int = 0, + override val endFrame: Int = 0, + @Help("The name of the skill to trigger") + val skillName: String = "", +) : Segment + +class SkillCinematicAction( + private val player: Player, + entry: MythicSkillCinematicEntry, +) : SimpleCinematicAction() { + override val segments: List = entry.segments + + override suspend fun startSegment(segment: MythicSkillSegment) { + super.startSegment(segment) + + val skill = MythicBukkit.inst().skillManager.getSkill(segment.skillName).orElseGet { + throw IllegalArgumentException("Skill ${segment.skillName} not found") + } + + val trigger = BukkitAdapter.adapt(player) + val caster = GenericCaster(trigger) + + val skillMeta = + SkillMetadataImpl(SkillTriggers.API, caster, trigger) + + if (skill.isUsable(skillMeta)) skill.execute(skillMeta) + else logger.warning("Skill ${segment.skillName} is not usable at this time (cooldown, etc.)") + } +} diff --git a/documentation/docs/adapters/MythicMobsAdapter/MythicMobsAdapter.mdx b/documentation/docs/adapters/MythicMobsAdapter/MythicMobsAdapter.mdx index 77c019075a..d52a94e5f7 100644 --- a/documentation/docs/adapters/MythicMobsAdapter/MythicMobsAdapter.mdx +++ b/documentation/docs/adapters/MythicMobsAdapter/MythicMobsAdapter.mdx @@ -13,8 +13,16 @@ This adapter is untested. It may not work as expected. Please report any issues | Name | Description | | ---- | ----------- | | [Despawn Mob Action](MythicMobsAdapter/entries/action/despawn_mythicmobs_mob) | Despawn a mob from MythicMobs | +| [Execute Skill Action](MythicMobsAdapter/entries/action/execute_mythicmob_skill) | Executes a MythicMobs skill | | [Spawn Mob Action](MythicMobsAdapter/entries/action/spawn_mythicmobs_mob) | Spawn a mob from MythicMobs | +### Cinematics + +| Name | Description | +| ---- | ----------- | +| [Mythic Mob Cinematic](MythicMobsAdapter/entries/cinematic/mythicmob_cinematic) | Spawn a MythicMob during a cinematic | +| [Mythic Skill Cinematic](MythicMobsAdapter/entries/cinematic/mythicskill_cinematic) | Spawn a MythicMob during a cinematic | + ### Events | Name | Description | diff --git a/documentation/docs/adapters/MythicMobsAdapter/entries/action/execute_mythicmob_skill.mdx b/documentation/docs/adapters/MythicMobsAdapter/entries/action/execute_mythicmob_skill.mdx new file mode 100644 index 0000000000..3544aa70e8 --- /dev/null +++ b/documentation/docs/adapters/MythicMobsAdapter/entries/action/execute_mythicmob_skill.mdx @@ -0,0 +1,21 @@ +import * as fields from '@site/src/components/EntryField'; +import Admonition from '@theme/Admonition'; +import Link from '@docusaurus/Link'; + +# Execute Skill Action + +The `Execute Skill Action` action executes a MythicMobs skill. + +## How could this be used? +Create fancy particle animations. +For example, you can create a little animation when a player opens a door. + + +## Fields + + + + + + The name of the skill to execute + diff --git a/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/_category_.yml b/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/_category_.yml new file mode 100644 index 0000000000..fd78b117d4 --- /dev/null +++ b/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/_category_.yml @@ -0,0 +1 @@ +label: Cinematics \ No newline at end of file diff --git a/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicmob_cinematic.mdx b/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicmob_cinematic.mdx new file mode 100644 index 0000000000..af3a1e7f3d --- /dev/null +++ b/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicmob_cinematic.mdx @@ -0,0 +1,18 @@ +import * as fields from '@site/src/components/EntryField'; +import Admonition from '@theme/Admonition'; +import Link from '@docusaurus/Link'; + +# Mythic Mob Cinematic + +The `Spawn MythicMob Cinematic` cinematic entry spawns a MythicMob during a cinematic. + +## How could this be used? + +This can be used to animate a MythicMob spawning during a cinematic. + + +## Fields + + + + diff --git a/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicskill_cinematic.mdx b/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicskill_cinematic.mdx new file mode 100644 index 0000000000..a822fad6e1 --- /dev/null +++ b/documentation/docs/adapters/MythicMobsAdapter/entries/cinematic/mythicskill_cinematic.mdx @@ -0,0 +1,27 @@ +import * as fields from '@site/src/components/EntryField'; +import Admonition from '@theme/Admonition'; +import Link from '@docusaurus/Link'; + +# Mythic Skill Cinematic + +The `Mythic Skill Cinematic` cinematic entry triggers a skill during a cinematic. + +:::caution +A skill itself needs to define the audience to be self using `audience=self` + +### Example: +``` +- effect:particlesphere{particle=flame;amount=200;radius=2;audience=self} @self +``` +::: + +## How could this be used? + +This can be used to animate fancy particle effects during a cinematic. + + +## Fields + + + +