diff --git a/.github/actions/build-adapter/action.yml b/.github/actions/build-adapter/action.yml deleted file mode 100644 index 7513c89ea7..0000000000 --- a/.github/actions/build-adapter/action.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "Build Adapter" -description: "Builds the adapter and runs tests" - -inputs: - adapter: - required: true - description: "Name of the adapter to build" - -runs: - using: "composite" - steps: - - name: Test Adapter - uses: gradle/gradle-build-action@v2 - with: - arguments: :${{ inputs.adapter }}:test --scan - build-root-directory: ./adapters - - name: Build Adapter - uses: gradle/gradle-build-action@v2 - with: - arguments: :${{ inputs.adapter }}:buildRelease --scan - build-root-directory: ./adapters - diff --git a/.github/actions/build-engine/action.yml b/.github/actions/build-engine/action.yml new file mode 100644 index 0000000000..a53007bc96 --- /dev/null +++ b/.github/actions/build-engine/action.yml @@ -0,0 +1,37 @@ +name: Build Paper Engine +description: "Builds the plugin and runs tests" + +runs: + using: "composite" + steps: + - name: Setup Flutter + uses: subosito/flutter-action@v2 + with: + channel: "beta" + - name: Get Flutter dependencies + run: flutter pub get + shell: bash + working-directory: ./app + - name: Run Lint + run: flutter analyze + shell: bash + working-directory: ./app + - name: Run tests + run: flutter test + shell: bash + working-directory: ./app + - name: Build web app + run: flutter build web --release + shell: bash + working-directory: ./app + - name: Test Paper Engine + uses: gradle/gradle-build-action@v2 + with: + arguments: engine-paper:test --scan + build-root-directory: ./engine + - name: Build Plugin + uses: gradle/gradle-build-action@v2 + with: + arguments: engine-paper:buildRelease --scan + build-root-directory: ./engine + diff --git a/.github/actions/build-extension/action.yml b/.github/actions/build-extension/action.yml new file mode 100644 index 0000000000..ce702b8962 --- /dev/null +++ b/.github/actions/build-extension/action.yml @@ -0,0 +1,22 @@ +name: "Build Extension" +description: "Builds the extension" + +inputs: + extension: + required: true + description: "Name of the extension to build" + +runs: + using: "composite" + steps: + - name: Test extension + uses: gradle/gradle-build-action@v2 + with: + arguments: :${{ inputs.extension }}:test --scan + build-root-directory: ./extensions + - name: Build Adapter + uses: gradle/gradle-build-action@v2 + with: + arguments: :${{ inputs.extension }}:buildRelease --scan + build-root-directory: ./extensions + diff --git a/.github/actions/build-plugin/action.yml b/.github/actions/build-plugin/action.yml deleted file mode 100644 index 2a460b490c..0000000000 --- a/.github/actions/build-plugin/action.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build Plugin -description: "Builds the plugin and runs tests" - -runs: - using: "composite" - steps: - - name: Setup Flutter - uses: subosito/flutter-action@v2 - with: - channel: "beta" - - name: Get Flutter dependencies - run: flutter pub get - shell: bash - working-directory: ./app - - name: Run Lint - run: flutter analyze - shell: bash - working-directory: ./app - - name: Run tests - run: flutter test - shell: bash - working-directory: ./app - - name: Build web app - run: flutter build web --release - shell: bash - working-directory: ./app - - name: Test Plugin - uses: gradle/gradle-build-action@v2 - with: - arguments: test --scan - build-root-directory: ./plugin - - name: Build Plugin - uses: gradle/gradle-build-action@v2 - with: - arguments: buildRelease --scan - build-root-directory: ./plugin - diff --git a/.github/runners/Dockerfile b/.github/runners/Dockerfile new file mode 100644 index 0000000000..2fa4ac92e8 --- /dev/null +++ b/.github/runners/Dockerfile @@ -0,0 +1,3 @@ +FROM ghcr.io/actions/actions-runner:latest + +RUN sudo apt update && sudo apt install git libvips-dev -y diff --git a/.github/workflows/build-adapter.yml b/.github/workflows/build-adapter.yml deleted file mode 100644 index 2f7502217f..0000000000 --- a/.github/workflows/build-adapter.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Build Specified Adapter - -on: - workflow_call: - inputs: - adapter: - required: true - type: string - description: The name of the adapter to build - -jobs: - build-adapter: - name: Build ${{ inputs.adapter }} Adapter - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 21 - - name: Build Adapter - uses: ./.github/actions/build-adapter - with: - adapter: ${{ inputs.adapter }} - - name: Upload Adapter - uses: actions/upload-artifact@v2 - with: - name: ${{ inputs.adapter }}.jar - path: adapters/${{ inputs.adapter }}/build/libs/${{ inputs.adapter }}.jar diff --git a/.github/workflows/build-development-jars-and-publish.yml b/.github/workflows/build-development-jars-and-publish.yml index 0b53429ad8..bdd761edd8 100644 --- a/.github/workflows/build-development-jars-and-publish.yml +++ b/.github/workflows/build-development-jars-and-publish.yml @@ -24,44 +24,38 @@ jobs: full_version="${version}-beta-${run_number}" echo $full_version > version.txt echo "version=$full_version" >> $GITHUB_OUTPUT - - name: Build Plugin - uses: ./.github/actions/build-plugin - - name: Build Basic Adapter - uses: ./.github/actions/build-adapter - with: - adapter: BasicAdapter - - name: Build Citizens Adapter - uses: ./.github/actions/build-adapter - with: - adapter: CitizensAdapter - - name: Build CombatLogX Adapter - uses: ./.github/actions/build-adapter - with: - adapter: CombatLogXAdapter - - name: Build MythicMobs Adapter - uses: ./.github/actions/build-adapter - with: - adapter: MythicMobsAdapter - - name: Build EntityAdapter - uses: ./.github/actions/build-adapter + - name: Build Engine + uses: ./.github/actions/build-engine +# ---------------------------------------------------------------------------------------------------- + - name: Test Extensions + uses: gradle/gradle-build-action@v2 with: - adapter: EntityAdapter - - name: Build RPGRegions Adapter - uses: ./.github/actions/build-adapter + arguments: test --scan + build-root-directory: ./extensions +# ---------------------------------------------------------------------------------------------------- + - name: Publish Engine to Beta Maven Repository + uses: gradle/gradle-build-action@v2 with: - adapter: RPGRegionsAdapter - - name: Build SuperiorSkyblock Adapter - uses: ./.github/actions/build-adapter + arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan + build-root-directory: ./engine + - name: Publish All Extensions to Beta Maven Repository + uses: gradle/gradle-build-action@v2 with: - adapter: SuperiorSkyblockAdapter - - name: Build Vault Adapter - uses: ./.github/actions/build-adapter + arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan + build-root-directory: ./extensions + - name: Publish Module-Plugin to Beta Maven Repository + uses: gradle/gradle-build-action@v2 with: - adapter: VaultAdapter - - name: Build WorldGuard Adapter - uses: ./.github/actions/build-adapter + arguments: publishAllPublicationsToTypewriterBetaRepository -PTypewriterBetaUsername=${{ secrets.MAVEN_USERNAME }} -PTypewriterBetaPassword=${{ secrets.MAVEN_PASSWORD }} --scan + build-root-directory: ./module-plugin +# ---------------------------------------------------------------------------------------------------- + # Has to be after the publish, because it needs to delete the slim jars and only keep the shadowed jars for the modrinth upload + - name: Build Extensions + uses: gradle/gradle-build-action@v2 with: - adapter: WorldGuardAdapter + arguments: buildRelease --scan + build-root-directory: ./extensions +# ---------------------------------------------------------------------------------------------------- - name: Publish Modrinth uses: Kir-Antipov/mc-publish@v3.3 id: publish @@ -70,16 +64,15 @@ jobs: modrinth-token: ${{ secrets.MODRINTH_TOKEN }} modrinth-featured: false files: | - plugin/build/libs/typewriter.jar - adapters/**/build/libs/*.jar - name: "Typewriter v${{ steps.vars.outputs.version }} Development Build" + engine/engine-paper/build/libs/Typewriter.jar + extensions/**/build/libs/*.jar + name: "Typewriter v${{ steps.vars.outputs.version }} Build" version: "${{ steps.vars.outputs.version }}" version-type: "beta" loaders: | paper - purpur game-versions: | - [1.21] + [1.21, 1.21.1] dependencies: | packetevents @@ -89,22 +82,23 @@ jobs: env: HANGAR_API_TOKEN: ${{ secrets.HANGAR_API_TOKEN }} with: - arguments: publishPluginPublicationToHangar --scan - build-root-directory: ./plugin + arguments: engine-paper:publishPluginPublicationToHangar --scan + build-root-directory: ./engine - name: Add Tag - uses: laputansoft/github-tag-action@v4.6 + uses: mathieudutour/github-tag-action@v6.2 with: - github_token: ${{ env.github-token }} + github_token: ${{ secrets.GITHUB_TOKEN }} default_bump: false - tag: "v${{ steps.vars.outputs.version }}" + custom_tag: "${{ steps.vars.outputs.version }}" + release_branches: develop - name: Notify Discord uses: sarisia/actions-status-discord@v1 with: webhook: ${{ secrets.DISCORD_WEBHOOK }} nodetail: true - title: Published Development Build + title: Published Beta Build description: | - I have published a development build of Typewriter. + I have published a beta build of Typewriter. Version: ${{ steps.vars.outputs.version }} [Download](https://modrinth.com/plugin/typewriter/version/${{ steps.publish.outputs.modrinth-version }}) - name: Notify Winston diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml index a2a47f3176..8949e5ed5f 100644 --- a/.github/workflows/build-documentation.yml +++ b/.github/workflows/build-documentation.yml @@ -1,4 +1,4 @@ -name: Deploy to GitHub Pages +name: Deploy Documentation on: [workflow_dispatch] @@ -8,6 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - run: sudo apt update && sudo apt install libvips-dev -y - uses: actions/setup-node@v3 with: node-version: 18 diff --git a/.github/workflows/build-engine.yml b/.github/workflows/build-engine.yml new file mode 100644 index 0000000000..83df9fd503 --- /dev/null +++ b/.github/workflows/build-engine.yml @@ -0,0 +1,21 @@ +name: Build Typewriter Engine + +on: [workflow_call,workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 21 + - name: Build Engine + uses: ./.github/actions/build-engine + - name: Upload Plugin + uses: actions/upload-artifact@v2 + with: + name: Typewriter.jar + path: engine/engine-paper/build/libs/Typewriter.jar diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml new file mode 100644 index 0000000000..b3cf8f851e --- /dev/null +++ b/.github/workflows/build-extension.yml @@ -0,0 +1,30 @@ +name: Build Specified Extension + +on: + workflow_call: + inputs: + extension: + required: true + type: string + description: The name of the extension to build + +jobs: + build-adapter: + name: Build ${{ inputs.extension }} Extension + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 21 + - name: Build Adapter + uses: ./.github/actions/build-extension + with: + extension: ${{ inputs.extension }} + - name: Upload Extension + uses: actions/upload-artifact@v2 + with: + name: ${{ inputs.extension }}.jar + path: adapters/${{ inputs.extension }}/build/libs/${{ inputs.extension }}.jar diff --git a/.github/workflows/build-jars-on-push.yml b/.github/workflows/build-jars-on-push.yml deleted file mode 100644 index 39549ef9cb..0000000000 --- a/.github/workflows/build-jars-on-push.yml +++ /dev/null @@ -1,135 +0,0 @@ -name: Build Jars on Push - -on: [workflow_dispatch] - -jobs: - changes: - runs-on: ubuntu-latest - outputs: - plugin: ${{ steps.changes.outputs.plugin }} - steps: - - uses: actions/checkout@v3 - - uses: dorny/paths-filter@v2 - id: changes - with: - filters: | - plugin: - - plugin/** - - app/** - basic_adapter: - - adapters/BasicAdapter/** - citizens_adapter: - - adapters/CitizensAdapter/** - combat_log_x_adapter: - - adapters/CombatLogXAdapter/** - entity_adapter: - - adapters/EntityAdapter/** - mythic_mobs_adapter: - - adapters/MythicMobsAdapter/** - rpg_regions_adapter: - - adapters/RPGRegionsAdapter/** - superior_skyblock_adapter: - - adapters/SuperiorSkyblockAdapter/** - vault_adapter: - - adapters/VaultAdapter/** - worldguard_adapter: - - adapters/WorldGuardAdapter/** - znpcs_adapter: - - adapters/ZNPCsPlusAdapter/** - fancynpcs_adapter: - - adapters/FancyNpcsAdapter/** - - build-plugin: - name: Build Typewriter Plugin - needs: changes - if: needs.changes.outputs.plugin == 'true' - uses: ./.github/workflows/build-plugin.yml - - build-adapter-basic: - name: Build Basic Adapter - needs: changes - if: needs.changes.outputs.basic_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: BasicAdapter - - build-adapter-citizens: - name: Build Citizens Adapter - needs: changes - if: needs.changes.outputs.citizens_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: CitizensAdapter - - - build-adapter-combat-log-x: - name: Build CombatLogX Adapter - needs: changes - if: needs.changes.outputs.combat_log_x_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: CombatLogXAdapter - - build-adapter-entity: - name: Build EntityAdapter - needs: changes - if: needs.changes.outputs.entity_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: EntityAdapter - - build-adapter-mythic-mobs: - name: Build MythicMobs Adapter - needs: changes - if: needs.changes.outputs.mythic_mobs_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: MythicMobsAdapter - - build-adapter-rpg-regions: - name: Build RPGRegions Adapter - needs: changes - if: needs.changes.outputs.rpg_regions_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: RPGRegionsAdapter - - build-adapter-superior-skyblock: - name: Build SuperiorSkyblock Adapter - needs: changes - if: needs.changes.outputs.superior_skyblock_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: SuperiorSkyblockAdapter - - build-adapter-vault: - name: Build Vault Adapter - needs: changes - if: needs.changes.outputs.vault_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: VaultAdapter - - build-adapter-worldguard: - name: Build WorldGuard Adapter - needs: changes - if: needs.changes.outputs.world_guard_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: WorldGuardAdapter - - build-adapter-znpcs: - name: Build ZNPCsPlus Adapter - needs: changes - if: needs.changes.outputs.znpcs_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: ZNPCsPlusAdapter - - build-adapter-fancynpcs: - name: Build FancyNpcs Adapter - needs: changes - if: needs.changes.outputs.fancynpcs_adapter == 'true' - uses: ./.github/workflows/build-adapter.yml - with: - adapter: FancyNpcsAdapter diff --git a/.github/workflows/build-jars-on-request.yml b/.github/workflows/build-jars-on-request.yml index 75bdf6eaa4..9dc7dad3d8 100644 --- a/.github/workflows/build-jars-on-request.yml +++ b/.github/workflows/build-jars-on-request.yml @@ -3,73 +3,61 @@ name: Build Jars on Request on: [workflow_dispatch] jobs: - build-plugin: - name: Build Typewriter Plugin - uses: ./.github/workflows/build-plugin.yml + build-engine: + name: Build Typewriter Engine + uses: ./.github/workflows/build-engine.yml - build-adapter-basic: - name: Build Basic Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-basic: + name: Build Basic Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: BasicAdapter + extension: BasicExtension - build-adapter-citizens: - name: Build Citizens Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-citizens: + name: Build Citizens Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: CitizensAdapter + extension: CitizensExtension - build-adapter-combat-log-x: - name: Build CombatLogX Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-combat-log-x: + name: Build CombatLogX Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: CombatLogXAdapter + extension: CombatLogXExtension - build-adapter-entity: - name: Build EntityAdapter - uses: ./.github/workflows/build-adapter.yml + build-extension-entity: + name: Build EntityExtension + uses: ./.github/workflows/build-extension.yml with: - adapter: EntityAdapter + extension: EntityExtension - build-adapter-mythic-mobs: - name: Build MythicMobs Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-mythic-mobs: + name: Build MythicMobs Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: MythicMobsAdapter + extension: MythicMobsExtension - build-adapter-rpg-regions: - name: Build RPGRegions Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-rpg-regions: + name: Build RPGRegions Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: RPGRegionsAdapter + extension: RPGRegionsExtension - build-adapter-superior-skyblock: - name: Build SuperiorSkyblock Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-superior-skyblock: + name: Build SuperiorSkyblock Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: SuperiorSkyblockAdapter + extension: SuperiorSkyblockExtension - build-adapter-vault: - name: Build Vault Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-vault: + name: Build Vault Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: VaultAdapter + extension: VaultExtension - build-adapter-worldguard: - name: Build WorldGuard Adapter - uses: ./.github/workflows/build-adapter.yml + build-extension-worldguard: + name: Build WorldGuard Extension + uses: ./.github/workflows/build-extension.yml with: - adapter: WorldGuardAdapter - - build-adapter-znpcs: - name: Build ZNPCsPlus Adapter - uses: ./.github/workflows/build-adapter.yml - with: - adapter: ZNPCsPlusAdapter - - build-adapter-fancynpcs: - name: Build FancyNpcs Adapter - uses: ./.github/workflows/build-adapter.yml - with: - adapter: FancyNpcsAdapter + extension: WorldGuardExtension diff --git a/.github/workflows/build-plugin.yml b/.github/workflows/build-plugin.yml deleted file mode 100644 index 620600a5fa..0000000000 --- a/.github/workflows/build-plugin.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Build Typewriter Plugin - -on: [workflow_call,workflow_dispatch] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 21 - - name: Build Plugin - uses: ./.github/actions/build-plugin - - name: Upload Plugin - uses: actions/upload-artifact@v2 - with: - name: typewriter.jar - path: plugin/build/libs/typewriter.jar diff --git a/.github/workflows/build-runner-image.yml b/.github/workflows/build-runner-image.yml new file mode 100644 index 0000000000..0765e0469a --- /dev/null +++ b/.github/workflows/build-runner-image.yml @@ -0,0 +1,51 @@ +# +name: Create and publish a Docker image + +on: + push: + branches: + - develop + paths: + - .github/workflows/build-runner-image.yml + - .github/runners/Dockerfile + +env: + REGISTRY: ghcr.io + IMAGE_NAME: typewriter-runner + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ github.actor }}/${{ env.IMAGE_NAME }} + - name: Build and push Docker image + id: push + uses: docker/build-push-action@v6 + with: + context: .github/runners + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ github.actor }}/${{ env.IMAGE_NAME }}:latest + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ github.actor }}/${{ env.IMAGE_NAME }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true diff --git a/.gitignore b/.gitignore index 7daffb3298..56b9e96749 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,7 @@ run/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar -/plugin/server +/server/ .DS_Store # Rust diff --git a/README.md b/README.md index cd193e4b1d..f1b05f0008 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Typewriter 的强大之处在于它可以通过适配器进行扩展。 没有他们的支持,这个项目是不可能实现的。 如果你在服务器上使用 Typewriter 并从中获利,请考虑 [赞助](https://github.com/sponsors/gabber235) 该项目。 -PixelPioneer + ### 示例 diff --git a/adapters/BasicAdapter/build.gradle.kts b/adapters/BasicAdapter/build.gradle.kts deleted file mode 100644 index 0cda5ef4ab..0000000000 --- a/adapters/BasicAdapter/build.gradle.kts +++ /dev/null @@ -1,2 +0,0 @@ -repositories { } -dependencies { } \ No newline at end of file diff --git a/adapters/BasicAdapter/settings.gradle.kts b/adapters/BasicAdapter/settings.gradle.kts deleted file mode 100644 index 8b09043a96..0000000000 --- a/adapters/BasicAdapter/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -rootProject.name = "BasicAdapter" - -includeBuild("../../plugin") - -plugins { - id("com.gradle.enterprise") version ("3.13.3") -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt deleted file mode 100644 index 9557057296..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/BasicAdapter.kt +++ /dev/null @@ -1,19 +0,0 @@ -package me.gabber235.typewriter - -import App -import me.gabber235.typewriter.adapters.Adapter -import me.gabber235.typewriter.adapters.TypewriterAdapter - -@Adapter("Basic", "对于所有最基本的条目", App.VERSION) -/** - * The Basic Adapter contains all the essential entries for Typewriter. - * In most cases, it should be installed with Typewriter. - * If you haven't installed Typewriter or the adapter yet, - * please follow the [Installation Guide](../../docs/02-getting-started/01-installation.mdx) - * first. - */ -object BasicAdapter : TypewriterAdapter() { - override fun initialize() { - - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/AddPotionEffectActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/AddPotionEffectActionEntry.kt deleted file mode 100644 index 47e791f627..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/AddPotionEffectActionEntry.kt +++ /dev/null @@ -1,54 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.toTicks -import org.bukkit.entity.Player -import org.bukkit.potion.PotionEffect -import org.bukkit.potion.PotionEffectType -import java.time.Duration - -@Entry("add_potion_effect", "为玩家添加药水效果", Colors.RED, "fa6-solid:flask-vial") -/** - * The `Add Potion Effect Action` is an action that adds a potion effect to the player. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to provide players with buffs or debuffs, such as speed or slowness, or to create custom effects. - */ -class AddPotionEffectActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("要添加的药水效果。") - val potionEffect: PotionEffectType = PotionEffectType.SPEED, - @Help("药水效果的持续时间。") - val duration: Duration = Duration.ofSeconds(1), - @Help("药水效果的等级。") - val amplifier: Int = 1, - @Help("效果是否是环境效果") - val ambient: Boolean = false, - @Help("是否显示药水效果粒子。") - val particles: Boolean = true, - @Help("是否在玩家的物品栏中显示药水效果图标。") - val icon: Boolean = true, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - val potion = PotionEffect(potionEffect, duration.toTicks().toInt(), amplifier, ambient, particles, icon) - SYNC.launch { - player.addPotionEffect(potion) - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ApplyVelocityActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ApplyVelocityActionEntry.kt deleted file mode 100644 index efcd36af47..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ApplyVelocityActionEntry.kt +++ /dev/null @@ -1,36 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Vector -import org.bukkit.entity.Player - -@Entry("apply_velocity", "对玩家应用速度", Colors.RED, "fa-solid:wind") -/** - * The `ApplyVelocityActionEntry` is an action that applies a velocity to the player. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to simulate wind, explosions, or any other force that would move the player. - */ -class ApplyVelocityActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("强制应用到玩家") - val force: Vector = Vector(0.0, 0.0, 0.0), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - player.velocity = player.velocity.add(force.toBukkitVector()) - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/CinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/CinematicEntry.kt deleted file mode 100644 index 4cafd5fc94..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/CinematicEntry.kt +++ /dev/null @@ -1,43 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.annotations.SerializedName -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.Page -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.CinematicStartTrigger -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import org.bukkit.entity.Player - - -@Entry("cinematic", "开始新的过场动画", Colors.RED, "fa-solid:camera-retro") -/** - * The `Cinematic` action is used to start a new cinematic. - * - * A cinematic can only be overridden - * if another cinematic is triggered with a higher page priority than the current one. - * - * ## How could this be used? - * - * This action can be useful in situations where you want to start a cinematic. - * See the [Cinematic](/docs/creating-stories/cinematics) tutorial for more information. - */ -class CinematicEntry( - 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(), - @SerializedName("page") - @Page(PageType.CINEMATIC) - @Help("过场动画页面开始。") - val pageId: String = "", -) : CustomTriggeringActionEntry { - override fun execute(player: Player) { - super.execute(player) - - CinematicStartTrigger(pageId, customTriggers) triggerFor player - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ConsoleCommandActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ConsoleCommandActionEntry.kt deleted file mode 100644 index 1b855ab31e..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ConsoleCommandActionEntry.kt +++ /dev/null @@ -1,49 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import lirand.api.extensions.server.commands.dispatchCommand -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.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Bukkit -import org.bukkit.entity.Player - -@Entry("console_run_command", "从控制台运行命令", Colors.RED, "mingcute:terminal-fill") -/** - * The Console Command Action is an action that sends a command to the server console. This action provides you with the ability to execute console commands on the server in response to specific events. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to perform administrative tasks, such as sending a message to all players on the server, or to automate server tasks, such as setting the time of day or weather conditions. The possibilities are endless! - */ -class ConsoleCommandActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Placeholder - @MultiLine - @Help("要运行的命令。") - // Every line is a different command. Commands should not be prefixed with /. - private val command: String = "", -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - // Run in the main thread - SYNC.launch { - val commands = command.parsePlaceholders(player).lines() - for (cmd in commands) { - Bukkit.getConsoleSender().dispatchCommand(cmd) - } - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DelayedActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DelayedActionEntry.kt deleted file mode 100644 index b9d40f9f43..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DelayedActionEntry.kt +++ /dev/null @@ -1,47 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.annotations.SerializedName -import kotlinx.coroutines.delay -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.DISPATCHERS_ASYNC -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.entity.Player -import java.time.Duration - -@Entry("delayed_action", "将动作延迟一定时间", Colors.RED, "fa-solid:hourglass") -/** - * The `Delayed Action Entry` is an entry that fires its triggers after a specified duration. This entry provides you with the ability to create time-based actions and events. - * - * ## How could this be used? - * - * This entry can be useful in a variety of situations where you need to delay an action or event. - * You can use it to create countdown timers, to perform actions after a certain amount of time has elapsed, or to schedule events in the future. - */ -class DelayedActionEntry( - 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(), - @Help("延迟动作的时间。") - // The duration before the next triggers are fired. - private val duration: Duration = Duration.ZERO, -) : CustomTriggeringActionEntry { - - override fun execute(player: Player) { - DISPATCHERS_ASYNC.launch { - delay(duration.toMillis()) - super.execute(player) - player.triggerCustomTriggers() - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt deleted file mode 100644 index 0c6b089b1e..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/DropItemActionEntry.kt +++ /dev/null @@ -1,74 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.optional -import org.bukkit.Location -import org.bukkit.Material -import org.bukkit.entity.Player -import java.util.* - -@Entry("drop_item", "将物品掉落到某个位置或玩家身上", Colors.RED, "fa-brands:dropbox") -/** - * The `Drop Item Action` is an action that drops an item in the world. - * This action provides you with the ability to drop an item with a specified Minecraft material, amount, display name, lore, and location. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. - * You can use it to create treasure chests with randomized items, drop loot from defeated enemies, or spawn custom items in the world. - * The possibilities are endless! - */ -class DropItemActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("要掉落的物品。") - val item: Item = Item.Empty, - @Help("掉落物品的位置。 (默认为玩家所在位置)") - // The location to drop the item at. If this field is left blank, the item will be dropped at the location of the player triggering the action. - private val location: Optional = Optional.empty(), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - // Run on main thread - SYNC.launch { - if (location.isPresent) { - location.get().world.dropItem(location.get(), item.build(player)) - } else { - player.location.world.dropItem(player.location, item.build(player)) - } - } - } -} - -@EntryMigration(DropItemActionEntry::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "amount", "displayName", "lore"]) -fun migrate040DropItemAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "amount", "displayName", "lore") - - val material = json.getAndParse("material", context.gson).optional - val amount = json.getAndParse("amount", context.gson).optional - val displayName = json.getAndParse("displayName", context.gson).optional - val lore = json.getAndParse("lore", context.gson).optional - - val item = Item( - material = material, - amount = amount, - name = displayName, - lore = lore, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/FireworkActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/FireworkActionEntry.kt deleted file mode 100644 index ad3daadf32..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/FireworkActionEntry.kt +++ /dev/null @@ -1,91 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityStatus -import lirand.api.extensions.inventory.meta -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toPacketItem -import me.gabber235.typewriter.extensions.packetevents.toPacketLocation -import me.gabber235.typewriter.utils.Color -import me.tofaa.entitylib.EntityLib -import me.tofaa.entitylib.meta.Metadata -import me.tofaa.entitylib.meta.other.FireworkRocketMeta -import me.tofaa.entitylib.wrapper.WrapperEntity -import org.bukkit.FireworkEffect -import org.bukkit.Location -import org.bukkit.Material -import org.bukkit.entity.Player -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.meta.FireworkMeta -import java.util.* - -private const val FIREWORK_EXPLOSION_STATUS = 17 - -@Entry("firework", "生成一个烟花火箭", Colors.RED, "streamline:fireworks-rocket-solid") -/** - * The `Firework Action Entry` is an action that spawns a firework. - * - * ## How could this be used? - * This could be used to create a firework that displays a specific effect. - */ -class FireworkActionEntry( - override val id: String = "", - override val name: String = "", - override val triggers: List> = emptyList(), - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - @Help("生成烟花火箭的位置。") - val location: Location = Location(null, 0.0, 0.0, 0.0), - @Help("烟花火箭上显示的效果。") - val effects: List = emptyList(), - @Help("烟花火箭的威力。") - val power: Int = 0, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - val item = ItemStack(Material.FIREWORK_ROCKET).meta { - this@FireworkActionEntry.effects.forEach { effect -> - addEffect(effect.toBukkitEffect()) - } - power = this@FireworkActionEntry.power - } - - val uuid = UUID.randomUUID() - val entityId = EntityLib.getPlatform().entityIdProvider.provide(uuid, EntityTypes.FIREWORK_ROCKET) - val meta = FireworkRocketMeta(entityId, Metadata(entityId)).apply { - fireworkItem = item.toPacketItem() - } - val entity = WrapperEntity(entityId, uuid, EntityTypes.FIREWORK_ROCKET, meta) - entity.addViewer(player.uniqueId) - entity.spawn(location.toPacketLocation()) - WrapperPlayServerEntityStatus(entityId, FIREWORK_EXPLOSION_STATUS) sendPacketTo player - entity.despawn() - } -} - -class FireworkEffectConfig( - val type: FireworkEffect.Type = FireworkEffect.Type.BALL, - val flicker: Boolean = false, - val trail: Boolean = false, - val colors: List = emptyList(), - val fadeColors: List = emptyList(), -) { - fun toBukkitEffect(): FireworkEffect { - return FireworkEffect.builder() - .with(type) - .trail(trail) - .flicker(flicker) - .withColor(colors.map { it.toBukkitColor() }) - .withFade(fadeColors.map { it.toBukkitColor() }) - .build() - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt deleted file mode 100644 index 0bc1a511ef..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GiveItemActionEntry.kt +++ /dev/null @@ -1,63 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.optional -import org.bukkit.Material -import org.bukkit.entity.Player - -@Entry("give_item", "给予玩家一个物品", Colors.RED, "streamline:give-gift-solid") -/** - * The `Give Item Action` is an action that gives a player an item. This action provides you with the ability to give an item with a specified Minecraft material, amount, display name, and lore. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to give players rewards for completing quests, unlockables for reaching certain milestones, or any other custom items you want to give players. The possibilities are endless! - */ -class GiveItemActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("要给予的物品。") - val item: Item = Item.Empty, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - SYNC.launch { - player.inventory.addItem(item.build(player)) - } - } -} - -@EntryMigration(GiveItemActionEntry::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "amount", "displayName", "lore"]) -fun migrate040GiveItemAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "amount", "displayName", "lore") - - val material = json.getAndParse("material", context.gson).optional - val amount = json.getAndParse("amount", context.gson).optional - val displayName = json.getAndParse("displayName", context.gson).optional - val lore = json.getAndParse("lore", context.gson).optional - - val item = Item( - material = material, - amount = amount, - name = displayName, - lore = lore, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GroupTriggerActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GroupTriggerActionEntry.kt deleted file mode 100644 index d966763af2..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/GroupTriggerActionEntry.kt +++ /dev/null @@ -1,56 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.GroupId -import org.bukkit.entity.Player -import java.util.* - -@Entry( - "group_trigger_action", - "触发与玩家同一组中每个人的下一个条目", - Colors.RED, - "fluent:globe-arrow-forward-16-filled" -) -/** - * The `Group Trigger Action` is an action that triggers the next entries for everyone in the same group as the player. - * - * :::caution - * The modifiers will only be applied to the player that triggered the action. - * If you want to modify the other players, you will need to do it in the next entries. - * ::: - * - * ## How could this be used? - * This could be used to trigger the next entries for everyone in the same group as the player, - * when a player joins a faction, all the other players in the same faction could be notified. - */ -class GroupTriggerActionEntry( - 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(), - val group: Ref = emptyRef(), - @Help("需要触发下一个条目的组。如果没有设置,动作会触发该玩家所在的组。") - val forceGroup: Optional = Optional.empty(), -) : CustomTriggeringActionEntry { - override fun execute(player: Player) { - super.execute(player) - - val groupEntry = group.get() ?: return - - val group = forceGroup - .map { groupEntry.group(GroupId(it)) } - .orElseGet { groupEntry.group(player) } ?: return - - group.players.forEach { - it.triggerCustomTriggers() - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/MessageActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/MessageActionEntry.kt deleted file mode 100644 index d8c261daa6..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/MessageActionEntry.kt +++ /dev/null @@ -1,67 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.dialogue.playSpeakerSound -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.snippets.snippet -import me.gabber235.typewriter.utils.sendMiniWithResolvers -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed -import org.bukkit.entity.Player - -val messageFormat: String by snippet( - "action.message.format", - "\n [ ]\n \n" -) - -@Entry("send_message", "向玩家发送消息", Colors.RED, "flowbite:message-dots-solid") -/** - * The `Send Message Action` is an action that sends a message to a player. - * You can specify the speaker, and the message to send. - * - * This should not be confused with the (Message Dialogue)[../dialogue/message]. - * (Message Dialogue)[../dialogue/message] will replace the current dialogue with the message, while this action will not. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. - * You can use it to create text effects in response to specific events, such as completing actions or anything else. - * The possibilities are endless! - */ -class MessageActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("消息的发言者") - val speaker: Ref = emptyRef(), - @Help("要发送的消息") - @Placeholder - @MultiLine - val message: String = "", -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - val speakerEntry = speaker.get() - player.playSpeakerSound(speakerEntry) - player.sendMiniWithResolvers( - messageFormat, - parsed( - "speaker", - speakerEntry?.displayName ?: "" - ), - parsed( - "message", - message.parsePlaceholders(player).replace("\n", "\n ") - ) - ) - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt deleted file mode 100644 index 05e154ce50..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlaySoundActionEntry.kt +++ /dev/null @@ -1,61 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.* -import org.bukkit.Location -import org.bukkit.entity.Player -import java.util.* -import kotlin.jvm.optionals.getOrDefault - -@Entry("play_sound", "在玩家或某个位置播放声音", Colors.RED, "fa6-solid:volume-high") -/** - * The `Play Sound Action` is an action that plays a sound for the player. This action provides you with the ability to play any sound that is available in Minecraft, at a specified location. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to provide audio feedback to players, such as when they successfully complete a challenge, or to create ambiance in your Minecraft world, such as by playing background music or sound effects. The possibilities are endless! - */ -class PlaySoundActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("要播放的声音。") - val sound: Sound = Sound.EMPTY, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - player.playSound(sound) - } -} - -@EntryMigration(PlaySoundActionEntry::class, "0.4.0") -@NeedsMigrationIfNotParsable -fun migrate040PlaySoundAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "sound", "location", "volume", "pitch") - - val soundString = json.getAndParse("sound", context.gson).optional - val location = json.getAndParse>("location", context.gson).optional - val volume = json.getAndParse("volume", context.gson).optional - val pitch = json.getAndParse("pitch", context.gson).optional - - val sound = Sound( - soundId = soundString.map(::DefaultSoundId).getOrDefault(SoundId.EMPTY), - soundSource = location.map(::LocationSoundSource).getOrDefault(SelfSoundSource), - volume = volume.orElse(1.0f), - pitch = pitch.orElse(1.0f), - ) - - data["sound"] = context.gson.toJsonTree(sound) - - return data -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlayerCommandActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlayerCommandActionEntry.kt deleted file mode 100644 index 91192de2e1..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/PlayerCommandActionEntry.kt +++ /dev/null @@ -1,54 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import lirand.api.extensions.server.commands.dispatchCommand -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.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.entity.Player - -@Entry("player_run_command", "让玩家运行命令", Colors.RED, "mingcute:terminal-fill") -/** - * The `Player Command Action` is an action that runs a command as if the player entered it. - * This action provides you with the ability to execute commands on behalf of the player in response to specific events. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. - * You can use it to provide players with a custom command that triggers a specific action, - * such as teleporting the player to a specific location or giving them an item. - * You can also use it to automate repetitive tasks, - * such as sending a message to the player when they complete a quest or achievement. - * The possibilities are endless! - */ -class PlayerCommandActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Placeholder - @MultiLine - @Help("要运行的命令。") - // Every line is a different command. Commands should not be prefixed with /. - private val command: String = "", -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - // Run in main thread - SYNC.launch { - val commands = command.parsePlaceholders(player).lines() - for (cmd in commands) { - player.dispatchCommand(cmd) - } - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RandomTriggerGateEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RandomTriggerGateEntry.kt deleted file mode 100644 index 8f1e5d9af5..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RandomTriggerGateEntry.kt +++ /dev/null @@ -1,43 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.annotations.SerializedName -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import org.bukkit.entity.Player - -@Entry("random_trigger", "随机选择其连接的触发器", Colors.PINK, "mdi:clover") -/** - * The `Random Trigger Gate` is a gate that triggers a specified number of entries randomly. This gate provides you with the ability to randomly select and trigger a set number of entries in response to a specific event. - * - * ## How could this be used? - * - * This gate can be useful in a variety of situations. You can use it to create a mini-game that randomly selects events to occur, or to trigger a set number of actions randomly in response to a specific event. The possibilities are endless! - */ -class RandomTriggerGateEntry( - override val id: String, - override val name: String, - @SerializedName("triggers") - override val customTriggers: List> = emptyList(), - override val criteria: List, - override val modifiers: List, - @Help("触发的触发次数。") - private val amount: Int = 1, -) : CustomTriggeringActionEntry { - - override fun execute(player: Player) { - val selectedTriggers = mutableListOf>() - - if (customTriggers.isNotEmpty()) { - val randomIndices = (customTriggers.indices).shuffled().take(amount) - for (index in randomIndices) { - selectedTriggers.add(customTriggers[index]) - } - } - - super.execute(player) - selectedTriggers triggerEntriesFor player - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RemoveItemActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RemoveItemActionEntry.kt deleted file mode 100644 index 07c80a3db1..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/RemoveItemActionEntry.kt +++ /dev/null @@ -1,93 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.optional -import org.bukkit.Material -import org.bukkit.entity.Player -import java.util.* - -@Entry("remove_item", "从玩家物品栏中移除物品", Colors.RED, "icomoon-free:user-minus") -/** - * The `Remove Item Action` is an action that removes an item from the player's inventory. - * This action provides you with the ability to remove items from the player's inventory in response to specific events. - * - * This action will try to remove "as much as possible" but does not verify if the player has enough items in their inventory. - * If you want to guarantee that the player has enough items in their inventory, add an - * Inventory Item Count Fact to the criteria. - * - * - * ## How could this be used? - * - * This can be used when `giving` an NPC an item, and you want to remove the item from the player's inventory. - * Or when you want to remove a key from the player's inventory after they use it to unlock a door. - */ -class RemoveItemActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("要删除的物品。") - val item: Item = Item.Empty, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - // Because item.build() can return a identical looking item but with different data, - // we need to compare the items - - val itemWithoutAmount = item.copy(amount = Optional.empty()) - - val items = player.inventory.contents.withIndex().filter { - itemWithoutAmount.isSameAs(player, it.value) - }.iterator() - - var toRemove = item.amount.orElse(1) - - ThreadType.SYNC.launch { - while (toRemove > 0 && items.hasNext()) { - val (index, item) = items.next() - if (item == null) continue - val amount = item.amount - if (amount > toRemove) { - item.amount = amount - toRemove - player.inventory.setItem(index, item) - break - } else { - toRemove -= amount - player.inventory.setItem(index, null) - } - } - } - } -} - -@EntryMigration(RemoveItemActionEntry::class, "0.4.0") -@NeedsMigrationIfContainsAny(["material", "amount", "itemName"]) -fun migrate040RemoveItemAction(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "material", "amount", "itemName") - - val material = json.getAndParse("material", context.gson).optional - val amount = json.getAndParse("amount", context.gson).optional - val displayName = json.getAndParse>("itemName", context.gson).optional - - val item = Item( - material = material, - amount = amount, - name = displayName, - ) - data["item"] = context.gson.toJsonTree(item) - - return data -} - - diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetBlockActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetBlockActionEntry.kt deleted file mode 100644 index 731bcc2908..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetBlockActionEntry.kt +++ /dev/null @@ -1,47 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Location -import org.bukkit.Material -import org.bukkit.entity.Player - -@Entry("set_block", "在某个位置设置一个方块", Colors.RED, "fluent:cube-add-20-filled") -/** - * The `SetBlockActionEntry` is an action that sets a block at a specific location. - * - * :::caution - * This will set the block for all the players on the server, not just the player who triggered the action. - * It will modify the world, so be careful when using this action. - * ::: - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to create structures, set traps, or any other custom block placements you want to make. The possibilities are endless! - */ -class SetBlockActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("设置方块的材质。") - val material: Material = Material.AIR, - @Help("设置方块的位置。") - val location: Location = Location(null, 0.0, 0.0, 0.0), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - SYNC.launch { - location.block.type = material - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetItemActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetItemActionEntry.kt deleted file mode 100644 index 8a23916ce0..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SetItemActionEntry.kt +++ /dev/null @@ -1,42 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.entity.Player - -@Entry("set_item", "在特定槽位中设置物品", Colors.RED, "fluent:tray-item-add-24-filled") -/** - * The `Set Item Action` is an action that sets an item in a specific slot in the player's inventory. - * - * ## How could this be used? - * - * This can be used to equip a player with an elytra, or give them a weapon. - */ -class SetItemActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("设置的物品。") - val item: Item = Item.Empty, - @Help("设置物品的槽位。") - val slot: Int = 0, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - SYNC.launch { - player.inventory.setItem(slot, item.build(player)) - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ShowTitleActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ShowTitleActionEntry.kt deleted file mode 100644 index 5ef6a1e7ce..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/ShowTitleActionEntry.kt +++ /dev/null @@ -1,78 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini -import net.kyori.adventure.title.Title -import org.bukkit.entity.Player -import java.time.Duration -import java.util.* - -@Entry("show_title", "向玩家显示标题", Colors.RED, "fluent:align-center-vertical-32-filled") -/** - * The `Show Title Action` is an action that shows a title to a player. You can specify the subtitle, and durations if needed. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to create text effects in response to specific events, such as completing questions or anything else. The possibilities are endless! - */ -class ShowTitleActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Placeholder - @Colored - @Help("要显示的标题文本。") - val title: String = "", - @Placeholder - @Colored - @Help("要显示的副标题文字。") - val subtitle: String = "", - @Help("标题的可选持续时间设置。") - // Duration of the title: Fade in, how long it stays, fade out. - val durations: Optional = Optional.empty(), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - val adventureTitle: Title = durations.map { durations -> - Title.title( - title.parsePlaceholders(player).asMini(), - subtitle.parsePlaceholders(player).asMini(), - - Title.Times.times( - Duration.ofMillis(durations.fadeIn.toMillis()), - Duration.ofMillis(durations.stay.toMillis()), - Duration.ofMillis(durations.fadeOut.toMillis()) - ) - ) - }.orElseGet { - Title.title( - title.parsePlaceholders(player).asMini(), - subtitle.parsePlaceholders(player).asMini(), - ) - } - - player.showTitle(adventureTitle) - } -} - -data class TitleDurations( - @Help("淡入效果的时间。") - val fadeIn: Duration, - @Help("保持显示的时间。") - val stay: Duration, - @Help("淡出效果的时间。") - val fadeOut: Duration -) \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SimpleActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SimpleActionEntry.kt deleted file mode 100644 index b0ffb3b5fb..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SimpleActionEntry.kt +++ /dev/null @@ -1,26 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry - -@Entry("simple_action", "修改变量的简单动作", Colors.RED, "heroicons:bolt-16-solid") -/** - * The `Simple Action` is an empty action that can be used to modify facts. - * - * ## How could this be used? - * - * This action can be useful in situations where you need to modify facts, or want to filter different actions based om some criteria, - * but don't need to perform any additional actions. - */ -class SimpleActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), -) : ActionEntry \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SpawnParticleActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SpawnParticleActionEntry.kt deleted file mode 100644 index f76df5a37f..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SpawnParticleActionEntry.kt +++ /dev/null @@ -1,58 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.Negative -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import org.bukkit.Location -import org.bukkit.Particle -import org.bukkit.entity.Player -import java.util.* - -@Entry("spawn_particles", "在指定位置生成粒子", Colors.RED, "fa6-solid:fire-flame-simple") -/** - * The `Spawn Particle Action` is an action that spawns a specific particle at a given location. This action provides you with the ability to spawn particles with a specified type, count, and location. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to create visual effects in response to specific events, such as explosions or magical spells. The possibilities are endless! - */ -class SpawnParticleActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("生成粒子的位置。 (默认为玩家所在位置)") - val location: Optional = Optional.empty(), - @Help("要生成的粒子。") - val particle: Particle = Particle.FLAME, - @Help("生成的粒子数量。") - val count: Int = 1, - @Negative - @Help("距 X 轴位置的偏移量。") - val offsetX: Double = 0.0, - @Negative - @Help("距 Y 轴位置的偏移量。") - val offsetY: Double = 0.0, - @Negative - @Help("距 Z 轴位置的偏移量。") - val offsetZ: Double = 0.0, - @Help("粒子的速度。对于某些粒子,这是控制粒子行为的“额外”数据值。") - val speed: Double = 0.0, -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - if (location.isPresent) { - location.get().world?.spawnParticle(particle, location.get(), count, offsetX, offsetY, offsetZ, speed) - } else { - player.world.spawnParticle(particle, player.location, count, offsetX, offsetY, offsetZ, speed) - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/StopSoundActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/StopSoundActionEntry.kt deleted file mode 100644 index d73942770e..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/StopSoundActionEntry.kt +++ /dev/null @@ -1,47 +0,0 @@ -package me.gabber235.typewriter.entries.action - -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.utils.SoundId -import net.kyori.adventure.sound.SoundStop -import org.bukkit.entity.Player -import java.util.* - -@Entry("stop_sound", "停止某个玩家的一个或所有声音", Colors.RED, "teenyicons:sound-off-solid") -/** - * The `Stop Sound` action is used to stop a or all sounds for a player. - * - * ## How could this be used? - * - * This action can be useful in situations where you want to stop a sound for a player. - * For example, when leaving a certain area, you might want to stop the music that was playing. - */ -class StopSoundActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - @Help("要停止的声音。") - // The sound to stop. If this field is left blank, all sounds will be stopped. - val sound: Optional = Optional.empty(), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - if (sound.isPresent) { - val sound = sound.get() - val soundStop = sound.namespacedKey?.let { SoundStop.named(it) } ?: return - - player.stopSound(soundStop) - } else { - player.stopAllSounds() - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SwitchServerActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SwitchServerActionEntry.kt deleted file mode 100644 index 37546f6fd0..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/SwitchServerActionEntry.kt +++ /dev/null @@ -1,44 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.common.io.ByteStreams -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.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.plugin -import org.bukkit.entity.Player - -@Entry("switch_server_action", "将玩家切换到另一个服务器", Colors.RED, "fluent:server-link-16-filled") -/** - * The `Switch Server Action` is an action that switches the player to another server. - * - * ## How could this be used? - * - * This could be used to switch a player from one server to another when interacting with an entity, maybe clicking a button. - */ -class SwitchServerActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List, - override val modifiers: List, - override val triggers: List> = emptyList(), - @Help("玩家切换的服务器") - val server: String = "", -): ActionEntry { - override fun execute(player: Player) { - super.execute(player) - - plugin.server.messenger.registerOutgoingPluginChannel(plugin, "BungeeCord") - - val out = ByteStreams.newDataOutput() - out.writeUTF("Connect") - out.writeUTF(server) - player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray()) - - plugin.server.messenger.unregisterOutgoingPluginChannel(plugin, "BungeeCord") - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TeleportActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TeleportActionEntry.kt deleted file mode 100644 index 2fab7c8131..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TeleportActionEntry.kt +++ /dev/null @@ -1,44 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import com.google.gson.annotations.SerializedName -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.WithRotation -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.Modifier -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.entry.entries.CustomTriggeringActionEntry -import me.gabber235.typewriter.utils.ThreadType.SYNC -import org.bukkit.Location -import org.bukkit.entity.Player - -@Entry("teleport", "传送玩家", Colors.RED, "teenyicons:google-streetview-solid") -/** - * The `Teleport Action` entry is used to teleport a player to a location. - * - * ## How could this be used? - * This could be used to teleport a player to a location when they click a button. - * Or it could be used for a fast travel system where players talk to an NPC and are teleported to a location. - */ -class TeleportActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - @SerializedName("triggers") - override val customTriggers: List>, - @WithRotation - @Help("将玩家传送到的位置。") - val location: Location = Location(null, 0.0, 0.0, 0.0), -) : CustomTriggeringActionEntry { - override fun execute(player: Player) { - SYNC.launch { - player.teleport(location) - super.execute(player) - player.triggerCustomTriggers() - } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TrackQuestActionEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TrackQuestActionEntry.kt deleted file mode 100644 index 69b49686c7..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/action/TrackQuestActionEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.entries.action - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.ActionEntry -import me.gabber235.typewriter.entry.entries.QuestEntry -import me.gabber235.typewriter.entry.quest.trackQuest -import org.bukkit.entity.Player - -@Entry("track_quest", "开始追踪玩家的任务", Colors.RED, "material-symbols:bookmark") -/** - * The `Track Quest Action` is an action that tracks a quest when triggered. - * - * Though quests are tracked automatically, this action can force a quest to be tracked. - * - * ## How could this be used? - * - * Start tacking a quest, so it displays in the player's quest tracker. - */ -class TrackQuestActionEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - override val modifiers: List = emptyList(), - override val triggers: List> = emptyList(), - val quest: Ref = emptyRef(), -) : ActionEntry { - override fun execute(player: Player) { - super.execute(player) - player trackQuest quest - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CinematicAudienceEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CinematicAudienceEntry.kt deleted file mode 100644 index c4310063ba..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/CinematicAudienceEntry.kt +++ /dev/null @@ -1,72 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import com.google.gson.annotations.SerializedName -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.Page -import me.gabber235.typewriter.entry.PageType -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.cinematic.isPlayingCinematic -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.AudienceFilterEntry -import me.gabber235.typewriter.entry.entries.Invertible -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.events.AsyncCinematicEndEvent -import me.gabber235.typewriter.events.AsyncCinematicStartEvent -import org.bukkit.entity.Player -import org.bukkit.event.EventHandler - -@Entry( - "cinematic_audience", - "根据观众是否在过场动画中来过滤他们", - Colors.MEDIUM_SEA_GREEN, - "mdi:movie" -) -/** - * The `Cinematic Audience` entry filters an audience based on if they are in a cinematic. - * - * If no cinematic is referenced, it will filter based on if any cinematic is active. - * - * ## How could this be used? - * This could be used to hide the sidebar or boss bar when a cinematic is playing. - */ -class CinematicAudienceEntry( - override val id: String = "", - override val name: String = "", - override val children: List> = emptyList(), - @Help("当未设置时,它将根据是否有任何过场动画处于活动状态进行过滤。") - @Page(PageType.CINEMATIC) - @SerializedName("cinematic") - val pageId: String = "", - override val inverted: Boolean = false -) : AudienceFilterEntry, Invertible { - override fun display(): AudienceFilter = CinematicAudienceFilter( - ref(), - pageId, - ) -} - -class CinematicAudienceFilter( - ref: Ref, - private val pageId: String, -) : AudienceFilter(ref) { - override fun filter(player: Player): Boolean { - val inCinematic = if (pageId.isNotBlank()) player.isPlayingCinematic(pageId) else player.isPlayingCinematic() - return inCinematic - } - - @EventHandler - fun onCinematicStart(event: AsyncCinematicStartEvent) { - if (pageId.isNotBlank() && event.pageId != pageId) return - event.player.updateFilter(true) - } - - @EventHandler - fun onCinematicEnd(event: AsyncCinematicEndEvent) { - if (pageId.isNotBlank() && event.pageId != pageId) return - event.player.updateFilter(false) - } -} - diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ClosestGroupMemberPathStream.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ClosestGroupMemberPathStream.kt deleted file mode 100644 index 92de7269ef..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ClosestGroupMemberPathStream.kt +++ /dev/null @@ -1,46 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.PathStreamDisplay - -@Entry( - "closest_group_member_path_stream", - "到最近组成员的路径流", - Colors.GREEN, - "material-symbols:conversion-path" -) -/** - * The `Closest Group Member Path Stream` entry is a path stream that shows the path to the closest group member. - * The 'Closest Group Member' is determined by the group member that is closest to the player geographically, - * **Not based on the path distance.** - * - * When the group is not set, the path stream will not display anything. - * Players must be in the same world for the path stream to consider them. - * - * ## How could this be used? - * This could be used to show a path to the closest group member in a group of players. - * When a player is lost, they can follow the path to the closest group member. - */ -class ClosestGroupMemberPathStream( - override val id: String = "", - override val name: String = "", - val road: Ref = emptyRef(), - val group: Ref = emptyRef(), -) : AudienceEntry { - override fun display(): AudienceDisplay = PathStreamDisplay(road) { player -> - group.get()?.group(player)?.players - ?.asSequence() - ?.filter { it != player } - ?.filter { player.world == it.world } - ?.minByOrNull { it.location.distanceSquared(player.location) } - ?.location - ?: player.location - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt deleted file mode 100644 index 06059a1ca6..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/DirectLocationPathStream.kt +++ /dev/null @@ -1,32 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.PathStreamDisplay -import org.bukkit.Location - -@Entry( - "direct_location_path_stream", - "通向直接位置的路径流", - Colors.GREEN, - "material-symbols:conversion-path" -) -/** - * The `Direct Location Path Stream` entry is a path stream that shows the path to a specific location. - * When the player has this entry, a path stream will be displayed to the specified location. - * - * ## How could this be used? - * This could be used to show a path to a specific location in the world. - */ -class DirectLocationPathStream( - override val id: String = "", - override val name: String = "", - val road: Ref = emptyRef(), - val targetLocation: Location = Location(null, 0.0, 0.0, 0.0), -) : AudienceEntry { - override fun display(): AudienceDisplay = PathStreamDisplay(road, endLocation = { targetLocation }) -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GroupMembersPathStream.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GroupMembersPathStream.kt deleted file mode 100644 index 2c5ba0587f..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/GroupMembersPathStream.kt +++ /dev/null @@ -1,41 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.GroupEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.MultiPathStreamDisplay - -@Entry( - "group_members_path_stream", - "组成员的路径流", - Colors.GREEN, - "material-symbols:conversion-path" -) -/** - * The `Group Members Path Stream` entry is a path stream that shows the path to each group member. - * The 'Group Members' are determined by the group members that are in the same group as the player. - * - * When the group is not set, the path stream will not display anything. - * - * ## How could this be used? - * This could be used to show a path to each group member in a group of players. - * When a player wants to find any other group member, they can follow the respective path. - */ -class GroupMembersPathStream( - override val id: String = "", - override val name: String = "", - val road: Ref = emptyRef(), - val group: Ref = emptyRef(), -) : AudienceEntry { - override fun display(): AudienceDisplay = MultiPathStreamDisplay(road, endLocations = { player -> - group.get()?.group(player)?.players - ?.filter { it != player } - ?.map { it.location } - ?: emptyList() - }) -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInInventoryAudienceEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInInventoryAudienceEntry.kt deleted file mode 100644 index 52785cb552..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInInventoryAudienceEntry.kt +++ /dev/null @@ -1,55 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import com.github.shynixn.mccoroutine.bukkit.ticks -import kotlinx.coroutines.delay -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.Item -import me.gabber235.typewriter.utils.ThreadType -import org.bukkit.entity.Player -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.entity.EntityPickupItemEvent -import org.bukkit.event.inventory.* -import org.bukkit.event.player.PlayerDropItemEvent -import org.bukkit.event.player.PlayerPickupItemEvent - -@Entry( - "item_in_inventory_audience", - "根据玩家的物品栏中是否拥有特定的物品来过滤观众", - Colors.MEDIUM_SEA_GREEN, - "mdi:bag-personal" -) -/** - * The `Item In Inventory Audience` entry filters an audience based on if they have a specific item in their inventory. - * - * ## How could this be used? - * This could show a boss bar or sidebar based on if a player has a specific item in their inventory. - */ -class ItemInInventoryAudienceEntry( - override val id: String = "", - override val name: String = "", - override val children: List> = emptyList(), - @Help("在物品栏中检查的物品。") - val item: Item = Item.Empty, - override val inverted: Boolean = false, -) : AudienceFilterEntry, Invertible { - override fun display(): AudienceFilter = ItemInInventoryAudienceFilter(ref(), item) -} - -class ItemInInventoryAudienceFilter( - ref: Ref, - private val item: Item, -) : AudienceFilter(ref), TickableDisplay { - override fun filter(player: Player): Boolean { - return player.inventory.contents.any { it != null && item.isSameAs(player, it) } || item.isSameAs(player, player.itemOnCursor) - } - - override fun tick() { - consideredPlayers.forEach { it.refresh() } - } -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInSlotAudienceEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInSlotAudienceEntry.kt deleted file mode 100644 index 0d44740736..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/ItemInSlotAudienceEntry.kt +++ /dev/null @@ -1,58 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import io.papermc.paper.event.player.PlayerPickItemEvent -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.* -import me.gabber235.typewriter.entry.ref -import me.gabber235.typewriter.utils.Item -import org.bukkit.entity.Player -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.entity.EntityPickupItemEvent -import org.bukkit.event.inventory.* -import org.bukkit.event.inventory.InventoryAction.* -import org.bukkit.event.player.PlayerDropItemEvent -import org.bukkit.event.player.PlayerSwapHandItemsEvent - -@Entry( - "item_in_slot_audience", - "根据玩家在特定槽位中是否拥有特定的物品来过滤观众", - Colors.MEDIUM_SEA_GREEN, - "mdi:hand" -) -/** - * The `Item In Slot Audience` entry filters an audience based on if they have a specific item in a specific slot. - * - * ## How could this be used? - * It can be used to have magnet boots which allow players to move in certain areas. - */ -class ItemInSlotAudienceEntry( - override val id: String = "", - override val name: String = "", - override val children: List> = emptyList(), - @Help("要检查的物品。") - val item: Item = Item.Empty, - @Help("要检查的槽位。") - val slot: Int = 0, - override val inverted: Boolean = false, -) : AudienceFilterEntry, Invertible { - override fun display(): AudienceFilter = ItemInSlotAudienceFilter(ref(), item, slot) -} - -class ItemInSlotAudienceFilter( - ref: Ref, - private val item: Item, - private val slot: Int, -) : AudienceFilter(ref), TickableDisplay { - override fun filter(player: Player): Boolean { - val itemInSlot = player.inventory.getItem(slot) ?: return false - return item.isSameAs(player, itemInSlot) - } - - override fun tick() { - consideredPlayers.forEach { it.refresh() } - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LocationObjectivesPathStream.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LocationObjectivesPathStream.kt deleted file mode 100644 index 095bb1eb0a..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/LocationObjectivesPathStream.kt +++ /dev/null @@ -1,36 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.entry.entries.trackedShowingObjectives - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.RoadNetworkEntry -import me.gabber235.typewriter.entry.roadnetwork.gps.MultiPathStreamDisplay -import me.gabber235.typewriter.entries.quest.LocationObjectiveEntry - -@Entry( - "location_objectives_path_stream", - "跟踪位置目标的路径流", - Colors.GREEN, - "material-symbols:conversion-path" -) -/** - * The `Location Objectives Path Stream` entry is a path stream that shows the path to each tracked location objective. - * When the player has a location objective, and the quest for the objective is tracked, a path stream will be displayed. - * - * ## How could this be used? - * This could be used to show a path to each location objective in a quest. - */ -class LocationObjectivesPathStream( - override val id: String = "", - override val name: String = "", - val road: Ref = emptyRef(), -) : AudienceEntry { - override fun display(): AudienceDisplay = MultiPathStreamDisplay(road, endLocations = { player -> - player.trackedShowingObjectives().filterIsInstance().map { it.targetLocation }.toList() - }) -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SidebarEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SidebarEntry.kt deleted file mode 100644 index 6ee871a1e1..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SidebarEntry.kt +++ /dev/null @@ -1,28 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.entries.AudienceFilter -import me.gabber235.typewriter.entry.entries.PassThroughFilter -import me.gabber235.typewriter.entry.entries.SidebarEntry -import me.gabber235.typewriter.entry.ref -import java.util.* - -@Entry("sidebar", "为玩家显示侧边栏", Colors.DARK_ORANGE, "mdi:page-layout-sidebar-right") -/** - * The `SidebarEntry` is a display that shows a sidebar to players. - * - * To display lines on the sidebar, use the `SidebarLinesEntry` as its descendants. - * - * ## How could this be used? - * This could be used to show a list of objectives, or the region a player is in. - */ -class SimpleSidebarEntry( - override val id: String = "", - override val name: String = "", - override val children: List> = emptyList(), - override val title: String = "", - override val priorityOverride: Optional = Optional.empty(), -) : SidebarEntry \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SimpleLinesEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SimpleLinesEntry.kt deleted file mode 100644 index 60c116ba75..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/SimpleLinesEntry.kt +++ /dev/null @@ -1,33 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.entries.LinesEntry -import org.bukkit.entity.Player -import java.util.* - -@Entry("simple_lines", "静态确定的文本行", Colors.ORANGE_RED, "bi:layout-text-sidebar") -/** - * The `SimpleSidebarLinesEntry` is a display that shows lines. - * - * Separating lines with a newline character will display them on separate lines. - * - * ## How could this be used? - * This could be used to show a list of objectives, or the region a player is in. - */ -class SimpleLinesEntry( - override val id: String = "", - override val name: String = "", - @Help("要在侧边栏上显示的行。使用换行符分隔行。") - @Colored - @Placeholder - @MultiLine - val lines: String = "", - override val priorityOverride: Optional = Optional.empty(), -) : LinesEntry { - override fun lines(player: Player): String = lines -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TimerAudienceEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TimerAudienceEntry.kt deleted file mode 100644 index 2c9ee38fbc..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TimerAudienceEntry.kt +++ /dev/null @@ -1,64 +0,0 @@ -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.triggerFor -import me.gabber235.typewriter.logger -import me.gabber235.typewriter.utils.ThreadType -import org.bukkit.entity.Player -import java.time.Duration -import java.util.* - -@Entry( - "timer_audience", - "当玩家在观众中时,每隔指定时间触发一次动作", - Colors.GREEN, - "mdi:timer-outline" -) -/** - * The `Timer Audience` entry is an audience filter that triggers an action every specified duration when the player is in the audience. - * - * :::caution - * Very short durations can cause performance issues, and may be inaccurate. - * ::: - * - * ## How could this be used? - * This can be used to trigger a sequence every few seconds. - */ -class TimerAudienceEntry( - override val id: String = "", - override val name: String = "", - val duration: Duration = Duration.ofSeconds(1), - val onTimer: Ref = emptyRef(), -) : AudienceEntry { - override fun display(): AudienceDisplay = TimerAudienceDisplay(duration, onTimer) -} - -class TimerAudienceDisplay( - private val duration: Duration, - private val onTimer: Ref, -) : AudienceDisplay() { - private val jobs = mutableMapOf() - - override fun onPlayerAdd(player: Player) { - if (duration.isZero || duration.isNegative) { - logger.warning("计时器持续时间必须为正,否则将无限触发。") - return - } - jobs[player.uniqueId] = ThreadType.DISPATCHERS_ASYNC.launch { - while (player in this) { - delay(duration.toMillis()) - onTimer triggerFor player - } - } - } - - override fun onPlayerRemove(player: Player) { - jobs[player.uniqueId]?.cancel() - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TriggerAudienceEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TriggerAudienceEntry.kt deleted file mode 100644 index ca78c6e7ef..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/audience/TriggerAudienceEntry.kt +++ /dev/null @@ -1,48 +0,0 @@ -package me.gabber235.typewriter.entries.audience - -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.entry.Ref -import me.gabber235.typewriter.entry.TriggerableEntry -import me.gabber235.typewriter.entry.emptyRef -import me.gabber235.typewriter.entry.entries.AudienceDisplay -import me.gabber235.typewriter.entry.entries.AudienceEntry -import me.gabber235.typewriter.entry.triggerFor -import org.bukkit.entity.Player - -@Entry( - "trigger_audience", - "当玩家进入或退出观众时触发一个序列", - Colors.GREEN, - "mdi:account-arrow-right" -) -/** - * The `Trigger Audience` entry is an audience filter that triggers a sequence when the player enters or exits the audience. - * - * ## How could this be used? - * This can be used to bridge the gap between audiences and sequence pages. - */ -class TriggerAudienceEntry( - override val id: String = "", - override val name: String = "", - @Help("玩家进入观众时触发的序列。") - val onEnter: Ref = emptyRef(), - @Help("玩家退出观众时触发的序列。") - val onExit: Ref = emptyRef(), -) : AudienceEntry { - override fun display(): AudienceDisplay = TriggerAudienceDisplay(onEnter, onExit) -} - -class TriggerAudienceDisplay( - private val onEnter: Ref, - private val onExit: Ref, -) : AudienceDisplay() { - override fun onPlayerAdd(player: Player) { - onEnter triggerFor player - } - - override fun onPlayerRemove(player: Player) { - onExit triggerFor player - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/BlindingCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/BlindingCinematicEntry.kt deleted file mode 100644 index 7fd2b3e614..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/BlindingCinematicEntry.kt +++ /dev/null @@ -1,73 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChangeGameState -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCloseWindow -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -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.EmptyCinematicAction -import me.gabber235.typewriter.entry.entries.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.utils.isFloodgate -import org.bukkit.entity.Player - -@Entry("blinding_cinematic", "使玩家失明,使屏幕变黑", Colors.CYAN, "heroicons-solid:eye-off") -/** - * The `Blinding Cinematic` entry is used to blind the player so the screen looks black. - * - * ## How could this be used? - * Make the screen look black for the player during a cinematic. - */ -class BlindingCinematicEntry( - override val id: String, - override val name: String, - override val criteria: List, - @Segments(icon = "heroicons-solid:eye-off") - val segments: List, -) : PrimaryCinematicEntry { - override fun createSimulating(player: Player): CinematicAction? = null - override fun create(player: Player): CinematicAction { - // Disable for bedrock players as it doesn't give the desired effect - if (player.isFloodgate) return EmptyCinematicAction - return BlindingCinematicAction( - player, - this, - ) - } -} - -data class BlindingSegment( - override val startFrame: Int, - override val endFrame: Int, -) : Segment - -class BlindingCinematicAction( - private val player: Player, - entry: BlindingCinematicEntry, -) : SimpleCinematicAction() { - override val segments: List = entry.segments - - override suspend fun tickSegment(segment: BlindingSegment, frame: Int) { - super.tickSegment(segment, frame) - - val packet = WrapperPlayServerChangeGameState(WrapperPlayServerChangeGameState.Reason.WIN_GAME, 1f) - packet.sendPacketTo(player) - } - - override suspend fun stopSegment(segment: BlindingSegment) { - super.stopSegment(segment) - val packet = WrapperPlayServerCloseWindow(0) - packet.sendPacketTo(player) - } - - - override suspend fun teardown() { - super.teardown() - val packet = WrapperPlayServerCloseWindow(0) - packet.sendPacketTo(player) - } -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ParticleCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ParticleCinematicEntry.kt deleted file mode 100644 index 209bb6bf77..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ParticleCinematicEntry.kt +++ /dev/null @@ -1,84 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -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.Negative -import me.gabber235.typewriter.adapters.modifiers.Segments -import me.gabber235.typewriter.entry.Criteria -import me.gabber235.typewriter.entry.entries.* -import org.bukkit.Location -import org.bukkit.Particle -import org.bukkit.entity.Player - -@Entry("particle_cinematic", "为过场动画生成粒子", Colors.CYAN, "fa6-solid:fire-flame-simple") -/** - * The `Particle Cinematic` entry is used to spawn particles for a cinematic. - * - * ## How could this be used? - * - * This can be used to add dramatic effects to a cinematic. - * Like, blowing up a building and spawning a bunch of particles. - * Or, adding focus to a certain area by spawning particles around it. - */ -class ParticleCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - @Help("生成粒子的位置。") - val location: Location = Location(null, 0.0, 0.0, 0.0), - @Help("要生成的粒子。") - val particle: Particle = Particle.FLAME, - @Help("生成的粒子数量。") - val count: Int = 1, - @Negative - @Help("距 X 轴位置的偏移量。") - val offsetX: Double = 0.0, - @Negative - @Help("距 Y 轴位置的偏移量。") - val offsetY: Double = 0.0, - @Negative - @Help("距 Z 轴位置的偏移量。") - val offsetZ: Double = 0.0, - @Help("粒子的速度。") - // The speed of the particles. For some particles, this is the "extra" data value to control particle behavior. - val speed: Double = 0.0, - @Segments(icon = "fa6-solid:fire-flame-simple") - val segments: List = emptyList(), -) : CinematicEntry { - override fun create(player: Player): CinematicAction { - return ParticleCinematicAction( - player, - this, - ) - } -} - - -data class ParticleSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, -) : Segment - -class ParticleCinematicAction( - private val player: Player, - private val entry: ParticleCinematicEntry, -) : CinematicAction { - override suspend fun tick(frame: Int) { - super.tick(frame) - (entry.segments activeSegmentAt frame) ?: return - - player.spawnParticle( - entry.particle, - entry.location, - entry.count, - entry.offsetX, - entry.offsetY, - entry.offsetZ, - entry.speed - ) - - } - - override fun canFinish(frame: Int): Boolean = entry.segments canFinishAt frame -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PotionEffectCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PotionEffectCinematicEntry.kt deleted file mode 100644 index f6c0ebb0a1..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PotionEffectCinematicEntry.kt +++ /dev/null @@ -1,113 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -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.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.utils.EffectStateProvider -import me.gabber235.typewriter.utils.PlayerState -import me.gabber235.typewriter.utils.ThreadType.SYNC -import me.gabber235.typewriter.utils.restore -import me.gabber235.typewriter.utils.state -import org.bukkit.entity.Player -import org.bukkit.potion.PotionEffect -import org.bukkit.potion.PotionEffectType - -@Entry( - "potion_effect_cinematic", - "在过场动画期间对玩家应用不同的药水效果", - Colors.CYAN, - "fa6-solid:flask-vial" -) -/** - * The `PotionEffectCinematicEntry` is used to apply different potion effects to the player during a cinematic. - * - * ## How could this be used? - * This can be used to dynamically apply effects like blindness, slowness, etc., at different times - * during a cinematic, enhancing the storytelling or gameplay experience. - */ -class PotionEffectCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - @Segments(icon = "heroicons-solid:status-offline") - val segments: List = emptyList() -) : PrimaryCinematicEntry { - override fun createSimulating(player: Player): CinematicAction? = null - override fun create(player: Player): CinematicAction { - return PotionEffectCinematicAction( - player, - this - ) - } -} - -data class PotionEffectSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - @Help("要应用的药水效果类型") - val potionEffectType: PotionEffectType = PotionEffectType.BLINDNESS, - @Help("药水效果的强度") - val strength: Int = 1, - @Help("药水效果是否为环境效果") - val ambient: Boolean = false, - @Help("药水效果是否有粒子效果") - val particles: Boolean = false, - @Help("药水效果是否显示图标") - val icon: Boolean = false, -) : Segment - -class PotionEffectCinematicAction( - private val player: Player, - entry: PotionEffectCinematicEntry -) : SimpleCinematicAction() { - - private var state: PlayerState? = null - - override val segments: List = entry.segments - - override suspend fun startSegment(segment: PotionEffectSegment) { - super.startSegment(segment) - state = player.state(EffectStateProvider(segment.potionEffectType)) - - SYNC.switchContext { - player.addPotionEffect( - PotionEffect( - segment.potionEffectType, - 10000000, - segment.strength, - segment.ambient, - segment.particles, - segment.icon - ) - ) - } - } - - override suspend fun stopSegment(segment: PotionEffectSegment) { - super.stopSegment(segment) - restoreState() - } - - private suspend fun restoreState() { - val state = state ?: return - this.state = null - SYNC.switchContext { - player.restore(state) - } - } - - override suspend fun teardown() { - super.teardown() - - if (state != null) { - restoreState() - } - } -} diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PumpkinHatCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PumpkinHatCinematicEntry.kt deleted file mode 100644 index 0b6d61f354..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/PumpkinHatCinematicEntry.kt +++ /dev/null @@ -1,90 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.github.retrooper.packetevents.protocol.player.Equipment -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment -import lirand.api.extensions.inventory.meta -import me.gabber235.typewriter.adapters.Colors -import me.gabber235.typewriter.adapters.Entry -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.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toPacketItem -import me.gabber235.typewriter.utils.name -import me.gabber235.typewriter.utils.unClickable -import org.bukkit.Material -import org.bukkit.enchantments.Enchantment -import org.bukkit.entity.Player -import org.bukkit.inventory.ItemFlag -import org.bukkit.inventory.ItemStack - -@Entry("pumpkin_hat_cinematic", "在过场动画播放期间佩戴雕刻南瓜", Colors.CYAN, "mingcute:hat-fill") -/** - * The `Pumpkin Hat Cinematic` is a cinematic that shows a pumpkin hat on the player's head. - * - * ## How could this be used? - * When you have a resource pack, you can re-texture the pumpkin overlay to make it look like cinematic black bars. - */ -class PumpkinHatCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - @Segments(icon = "mingcute:hat-fill") - val segments: List = emptyList(), - ) : PrimaryCinematicEntry { - override fun create(player: Player): CinematicAction { - return PumpkinHatCinematicAction( - player, - this, - ) - } -} - -data class PumpkinHatSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, -) : Segment - -class PumpkinHatCinematicAction( - private val player: Player, - entry: PumpkinHatCinematicEntry, -) : SimpleCinematicAction() { - override val segments: List = entry.segments - - override suspend fun startSegment(segment: PumpkinHatSegment) { - super.startSegment(segment) - - WrapperPlayServerEntityEquipment( - player.entityId, - listOf( - Equipment( - com.github.retrooper.packetevents.protocol.player.EquipmentSlot.HELMET, - ItemStack(Material.CARVED_PUMPKIN) - .meta { - name = " " - unClickable() - } - .toPacketItem() - ) - ) - ) sendPacketTo player - } - - override suspend fun stopSegment(segment: PumpkinHatSegment) { - super.stopSegment(segment) - WrapperPlayServerEntityEquipment( - player.entityId, - listOf( - Equipment( - com.github.retrooper.packetevents.protocol.player.EquipmentSlot.HELMET, - player.inventory.helmet?.toPacketItem() - ?: com.github.retrooper.packetevents.protocol.item.ItemStack.EMPTY - ) - ) - ) sendPacketTo player - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ScreenShakeCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ScreenShakeCinematicEntry.kt deleted file mode 100644 index 504165ddf0..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/ScreenShakeCinematicEntry.kt +++ /dev/null @@ -1,65 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerHurtAnimation -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.entries.* -import me.gabber235.typewriter.extensions.packetevents.sendPacketTo -import org.bukkit.entity.Player -import kotlin.random.Random - -@Entry( - "screen_shake_cinematic", - "屏幕震动", - Colors.CYAN, - "ant-design:shake-outlined" -) -/** - * The `Screen Shake Cinematic` entry is used to shake the screen. - * - * ## How could this be used? - * It could be used to simulate an earthquake or a sudden impact. - */ -class ScreenShakeCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - @Segments(icon = "ant-design:shake-outlined") - val segments: List -) : PrimaryCinematicEntry { - override fun create(player: Player): CinematicAction { - return ScreenShakeCinematicAction( - player, - this - ) - } -} - -data class ScreenShakeSegment( - override val startFrame: Int, - override val endFrame: Int, - @Help("下一次震动前等待的帧数。") - val frameDelay: Int, -) : Segment - -class ScreenShakeCinematicAction( - private val player: Player, - private val entry: ScreenShakeCinematicEntry, -) : CinematicAction { - - override suspend fun tick(frame: Int) { - super.tick(frame) - - val segment = (entry.segments activeSegmentAt frame) ?: return - val baseFrame = frame - segment.startFrame - if (segment.frameDelay > 0 && baseFrame % segment.frameDelay != 0) return - - val packet = WrapperPlayServerHurtAnimation(player.entityId, Random.nextFloat() * 360 - 180) - packet.sendPacketTo(player) - } - - override fun canFinish(frame: Int): Boolean = entry.segments canFinishAt frame -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SetFakeBlockCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SetFakeBlockCinematicEntry.kt deleted file mode 100644 index 2037260445..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SetFakeBlockCinematicEntry.kt +++ /dev/null @@ -1,63 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState -import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockChange -import io.github.retrooper.packetevents.util.SpigotConversionUtil -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.extensions.packetevents.sendPacketTo -import me.gabber235.typewriter.extensions.packetevents.toVector3i -import org.bukkit.Location -import org.bukkit.Material -import org.bukkit.entity.Player - -@Entry("set_fake_block_cinematic", "设置一个假方块", Colors.CYAN, "mingcute:cube-3d-fill") -class SetFakeBlockCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - @Segments(icon = "mingcute:cube-3d-fill") - @Help("将在过场动画中的片段显示") - val segments: List = emptyList(), -) : CinematicEntry { - override fun create(player: Player): CinematicAction { - return SetFakeBlockCinematicAction(player, this) - } -} - -data class SetFakeBlockSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - val location: Location = Location(null, 0.0, 0.0, 0.0), - val block: Material = Material.AIR, -) : Segment - -class SetFakeBlockCinematicAction( - private val player: Player, - entry: SetFakeBlockCinematicEntry, -) : SimpleCinematicAction() { - override val segments: List = entry.segments - - override suspend fun startSegment(segment: SetFakeBlockSegment) { - super.startSegment(segment) - - val state = SpigotConversionUtil.fromBukkitBlockData(segment.block.createBlockData()) - val packet = WrapperPlayServerBlockChange(segment.location.toVector3i(), state.globalId) - packet.sendPacketTo(player) - } - - override suspend fun stopSegment(segment: SetFakeBlockSegment) { - super.stopSegment(segment) - - player.sendBlockChange(segment.location, segment.location.block.blockData) - } -} - diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt deleted file mode 100644 index ebbba996eb..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/SoundCinematicEntry.kt +++ /dev/null @@ -1,116 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import com.google.gson.JsonArray -import com.google.gson.JsonObject -import lirand.api.extensions.other.set -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.* -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.* -import org.bukkit.entity.Player -import kotlin.jvm.optionals.getOrDefault -import net.kyori.adventure.sound.Sound as AdventureSound - -@Entry("sound_cinematic", "在过场动画播放期间播放声音", Colors.YELLOW, "fa6-solid:music") -/** - * The `Sound Cinematic` entry plays a sound during a cinematic. - * - * ## How could this be used? - * - * This entry could be used to play a sound during a cinematic, such as a sound effect for a cutscene. - */ -class SoundCinematicEntry( - override val id: String, - override val name: String, - override val criteria: List, - @Segments(icon = "fa6-solid:music", color = Colors.YELLOW) - val segments: List, -) : CinematicEntry { - override fun create(player: Player): CinematicAction { - return SoundCinematicAction( - player, - this, - ) - } -} - -data class SoundSegment( - override val startFrame: Int, - override val endFrame: Int, - @Help("要播放的声音") - val sound: Sound, -) : Segment - -class SoundCinematicAction( - private val player: Player, - private val entry: SoundCinematicEntry, -) : SimpleCinematicAction() { - - override val segments: List = entry.segments - - override suspend fun startSegment(segment: SoundSegment) { - super.startSegment(segment) - player.playSound(segment.sound) - } - - override suspend fun stopSegment(segment: SoundSegment) { - super.stopSegment(segment) - player.stopSound(segment.sound) - } - -} - -@EntryMigration(SoundCinematicEntry::class, "0.4.0") -@NeedsMigrationIfNotParsable -fun migrate040SoundCinematic(json: JsonObject, context: EntryMigratorContext): JsonObject { - val data = JsonObject() - data.copyAllBut(json, "segments", "channel") - - val channel = json.getAndParse("channel", context.gson).optional - - val segmentsJson = json["segments"] - if (segmentsJson?.isJsonArray == true) { - logger.severe("尝试迁移声音过场动画条目 ${json["name"]},但片段不是数组。") - return data - } - - val segmentsArray = segmentsJson?.asJsonArray ?: JsonArray() - - val segments = segmentsArray.mapNotNull { - if (!it.isJsonObject) { - logger.severe("尝试迁移声音过场动画条目 ${json["name"]},但片段不是对象。") - return@mapNotNull null - } - - val segmentJson = it.asJsonObject - val startFrame = segmentJson.getAndParse("startFrame", context.gson).optional - val endFrame = segmentJson.getAndParse("endFrame", context.gson).optional - val sound = segmentJson.getAndParse("sound", context.gson).optional - val volume = segmentJson.getAndParse("volume", context.gson).optional - val pitch = segmentJson.getAndParse("pitch", context.gson).optional - - SoundSegment( - startFrame = startFrame.getOrDefault(0), - endFrame = endFrame.getOrDefault(0), - sound = Sound( - soundId = sound.map(::DefaultSoundId).getOrDefault(SoundId.EMPTY), - soundSource = SelfSoundSource, - track = channel.getOrDefault(AdventureSound.Source.MASTER), - volume = volume.getOrDefault(1.0f), - pitch = pitch.getOrDefault(1.0f), - ) - ) - } - - data["segments"] = context.gson.toJsonTree(segments) - - - return data -} \ No newline at end of file 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 deleted file mode 100644 index d4fb5ccad8..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TitleCinematicEntry.kt +++ /dev/null @@ -1,88 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -import io.papermc.paper.util.Tick -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.PrimaryCinematicEntry -import me.gabber235.typewriter.entry.entries.Segment -import me.gabber235.typewriter.extensions.placeholderapi.parsePlaceholders -import me.gabber235.typewriter.utils.asMini -import net.kyori.adventure.title.Title -import org.bukkit.entity.Player -import java.time.Duration - -@Entry("title_cinematic", "在过场动画播放期间显示标题", Colors.CYAN, "fluent:align-center-vertical-32-filled") -/** - * The `Title Cinematic` entry shows a title during a cinematic. - * - * ## How could this be used? - * - * 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 = emptyList(), - @Segments(icon = "fluent:align-center-vertical-32-filled") - val segments: List = emptyList(), -) : PrimaryCinematicEntry { - override fun create(player: Player): CinematicAction { - return TitleCinematicAction( - player, - this, - ) - } -} - -data class TitleSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - @Help("要显示的标题") - val title: String = "", - @Help("要显示的副标题") - val subtitle: String = "", - @Help("淡入时间") - val fadeIn: Long = 20, - @Help("淡出时间") - val fadeOut: Long = 20, -) : Segment - -class TitleCinematicAction( - private val player: Player, - entry: TitleCinematicEntry, -) : SimpleCinematicAction() { - - override val segments: List = entry.segments - - override suspend fun startSegment(segment: TitleSegment) { - super.startSegment(segment) - - val totalDuration: Int = segment.endFrame - segment.startFrame - val adjustedDuration: Long = (totalDuration - segment.fadeIn - segment.fadeOut).coerceAtLeast(0) - - val times: Title.Times = Title.Times.times( - Duration.of(segment.fadeIn, Tick.tick()), - Duration.of(adjustedDuration, Tick.tick()), - Duration.of(segment.fadeOut, Tick.tick()) - ) - - val title: Title = Title.title( - segment.title.parsePlaceholders(player).asMini(), - segment.subtitle.parsePlaceholders(player).asMini(), - times - ) - - player.showTitle(title) - } - - override suspend fun stopSegment(segment: TitleSegment) { - super.stopSegment(segment) - player.resetTitle() - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TriggerSequenceCinematicEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TriggerSequenceCinematicEntry.kt deleted file mode 100644 index 60364ed44f..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/cinematic/TriggerSequenceCinematicEntry.kt +++ /dev/null @@ -1,65 +0,0 @@ -package me.gabber235.typewriter.entries.cinematic - -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.* -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.EntryTrigger -import me.gabber235.typewriter.entry.entries.Segment -import org.bukkit.entity.Player - -@Entry("trigger_sequence_cinematic", "一系列要运行的触发器", Colors.PURPLE, "fa-solid:play") -/** - * The `Trigger Sequence Cinematic` entry that runs a sequence of triggers. It is very powerful but also very dangerous. - * - * :::caution - * Be aware of which triggers are running. If you run a trigger that is viewable by everyone, it will be visible to everyone. - * Also, **never trigger dialogues**, they should not be triggered from a cinematic. - * If you want to trigger a dialogue after the cinematic, connect it to the [CinematicEntry](../action/cinematic.mdx) - * ::: - * - * ## How could this be used? - * When you want to use any triggerable entry. Like giving an item to the player at a specific frame. - */ -class TriggerSequenceCinematicEntry( - override val id: String = "", - override val name: String = "", - override val criteria: List = emptyList(), - @Segments - @InnerMax(Max(1)) - @Help("要运行的触发器序列") - val segments: List = emptyList(), -) : CinematicEntry { - override fun create(player: Player): CinematicAction { - return TriggerSequenceAction( - player, - this - ) - } -} - -data class TriggerSequenceSegment( - override val startFrame: Int = 0, - override val endFrame: Int = 0, - val trigger: Ref = emptyRef() -) : Segment - -class TriggerSequenceAction( - val player: Player, - entry: TriggerSequenceCinematicEntry -) : SimpleCinematicAction() { - override val segments: List = entry.segments - - override suspend fun startSegment(segment: TriggerSequenceSegment) { - super.startSegment(segment) - - val entry = segment.trigger.get() ?: return - EntryTrigger(entry) triggerFor player - } -} \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/MessageDialogue.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/MessageDialogue.kt deleted file mode 100644 index d3aae88a7b..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/MessageDialogue.kt +++ /dev/null @@ -1,32 +0,0 @@ -package me.gabber235.typewriter.entries.dialogue - -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.MultiLine -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry - -@Entry("message", "向玩家显示一条消息", "#1c4da3", "ic:baseline-comment-bank") -/** - * The `Message Dialogue Action` is an action that displays a single message to the player. This action provides you with the ability to show a message to the player in response to specific events. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations. You can use it to give the player information about their surroundings, provide them with tips, or add flavor to your adventure. The possibilities are endless! - */ -class MessageDialogueEntry( - 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("显示给玩家的文本。") - val text: String = "", -) : DialogueEntry \ No newline at end of file diff --git a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/OptionDialogueEntry.kt b/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/OptionDialogueEntry.kt deleted file mode 100644 index 85c50b1df9..0000000000 --- a/adapters/BasicAdapter/src/main/kotlin/me/gabber235/typewriter/entries/dialogue/OptionDialogueEntry.kt +++ /dev/null @@ -1,46 +0,0 @@ -package me.gabber235.typewriter.entries.dialogue - -import me.gabber235.typewriter.adapters.Entry -import me.gabber235.typewriter.adapters.modifiers.Colored -import me.gabber235.typewriter.adapters.modifiers.Help -import me.gabber235.typewriter.adapters.modifiers.Placeholder -import me.gabber235.typewriter.entry.* -import me.gabber235.typewriter.entry.entries.DialogueEntry -import me.gabber235.typewriter.entry.entries.SpeakerEntry -import java.time.Duration - -@Entry("option", "向玩家显示选项列表", "#4CAF50", "fa6-solid:list") -/** - * The `Option Dialogue` action displays a list of options to the player to choose from. This action provides you with the ability to give players choices that affect the outcome of the game. - * - * ## How could this be used? - * - * This action can be useful in a variety of situations, such as presenting the player with dialogue choices that determine the course of a story or offering the player a choice of rewards for completing a quest. - */ -class OptionDialogueEntry( - 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(), - @Placeholder - @Colored - @Help("显示给玩家的文本。") - val text: String = "", - @Help("供玩家选择的选项。") - val options: List