diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 97aaee3..9972264 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -4,8 +4,11 @@ plugins { kotlin("jvm") version "1.7.10" id("com.github.johnrengelman.shadow") version "7.0.0" `maven-publish` + id("io.papermc.paperweight.userdev") version "1.7.1" } +val paper_version: String by rootProject + repositories { mavenCentral() } @@ -14,6 +17,8 @@ dependencies { // compileOnly(kotlin("reflect")) implementation(kotlin("reflect")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10") + + paperweight.paperDevBundle(paper_version) } tasks.test { diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt index cc6377d..3f6c04b 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt @@ -150,14 +150,8 @@ fun asyncDelayed(delay: Long, task: BukkitTask.() -> Unit): BukkitTask { * @author MattMX * @param block that returns our value */ -fun future(block: () -> T) : CompletableFuture { - val future = CompletableFuture() - async { - val result = block() - future.complete(result) - } - return future -} +fun future(block: CompletableFuture.() -> Unit): CompletableFuture = + CompletableFuture().apply(block) /** * Similar to [future], will return a [Future] with the type you want. diff --git a/api/src/main/kotlin/com/mattmx/ktgui/sound/ComplexSoundBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/sound/ComplexSoundBuilder.kt new file mode 100644 index 0000000..0c9219e --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/sound/ComplexSoundBuilder.kt @@ -0,0 +1,170 @@ +package com.mattmx.ktgui.sound + +import com.mattmx.ktgui.scheduling.TaskTracker +import com.mattmx.ktgui.scheduling.future +import com.mattmx.ktgui.utils.ticks +import net.kyori.adventure.audience.Audience +import net.kyori.adventure.key.Key +import net.kyori.adventure.sound.Sound.* +import org.bukkit.Location +import org.bukkit.Sound +import org.bukkit.entity.Player +import java.util.* +import java.util.function.Supplier + +class ComplexSoundBuilder { + private var defaultEmitter = EmitterType.SELF + private var location = Optional.empty>() + private var steps = arrayListOf() + + infix fun relative(value: Boolean) = apply { + defaultEmitter = if (value) EmitterType.SELF else EmitterType.LOCATION + } + + infix fun location(location: Location) = location { location } + + infix fun location(location: Supplier) = apply { + relative(false) + this.location = Optional.of(location) + } + + fun play(sound: Sound) = play(sound.key()) + + fun play(sound: Key) = + SoundBuilder(sound.key()).apply { steps.add(Step(Step.Type.SOUND, this)) } + + fun thenPlay(sound: Sound) = thenPlay(sound.key()) + + fun thenPlay(sound: Key) = thenPlay(SoundBuilder(sound)) + + fun thenPlay(sound: SoundBuilder) = apply { + steps.add(Step(Step.Type.SOUND, sound)) + } + + fun wait(ticks: Long) { + this.steps.add(Step(Step.Type.WAIT, ticks)) + } + + fun thenWait(ticks: Long) = apply { + wait(ticks) + } + + fun playFor(audience: Audience) = TaskTracker() + .apply { + runAsync { + val it = steps.iterator() + + while (it.hasNext()) { + val step = it.next() + + when (step.type) { + Step.Type.SOUND -> { + val wrapper = step.sound() + val sound = wrapper.build() + if (wrapper.emitter == EmitterType.LOCATION && wrapper.location.isPresent) { + val location = wrapper.location.get().get() + audience.playSound(sound, location.x, location.z, location.z) + } else { + audience.playSound(sound(wrapper.sound, wrapper.source, wrapper.volume, wrapper.pitch), Emitter.self()) + } + } + else -> { + val delay = step.delay() + + // todo this will lead to thread starvation - instead build to a chain of tasks + future { + runAsyncLater(delay) { + complete(Unit) + } + }.get() + } + } + } + } + } + + enum class EmitterType { + LOCATION, + SELF + } + + class Step( + val type: Type, + val value: Any + ) { + fun delay() = value as Long + fun sound() = value as SoundBuilder + + enum class Type { + SOUND, + WAIT + } + } + + class SoundBuilder( + val sound: Key + ) { + var emitter = EmitterType.SELF + private set + var location = Optional.empty>() + private set + var volume: Float = 1f + private set + var pitch: Float = 1f + private set + var source: Source = Source.MASTER + private set + + infix fun volume(vol: Float) = apply { + volume = vol + } + + infix fun pitch(pit: Float) = apply { + pitch = pit + } + + infix fun source(src: Source) = apply { + this.source = src + } + + infix fun relative(value: Boolean) = apply { + emitter = if (value) EmitterType.SELF else EmitterType.LOCATION + } + + infix fun location(location: Location) = location { location } + + infix fun location(location: Supplier) = apply { + relative(false) + this.location = Optional.of(location) + } + + fun build() = net.kyori.adventure.sound.Sound.sound(sound, source, volume, pitch) + } +} + +fun soundBuilder(block: ComplexSoundBuilder.() -> Unit) = + ComplexSoundBuilder().apply(block) + +fun sound(sound: Sound) = sound(sound.key()) + +fun sound(key: Key) = ComplexSoundBuilder.SoundBuilder(key) + +fun Audience.playSound(sound: ComplexSoundBuilder) = sound.playFor(this) + +fun main(player: Player) { + val custom = soundBuilder { + location { player.location.clone().add(0.0, 100.0, 0.0) } + + play(Sound.ENTITY_ENDER_DRAGON_DEATH) volume 1f pitch 2f relative true + wait(1.ticks) + play(Sound.BLOCK_NOTE_BLOCK_BANJO) volume 2f pitch 0f relative true + } + + val builder = ComplexSoundBuilder() + .relative(true) + .thenPlay(Sound.ENTITY_ENDER_DRAGON_DEATH) + .thenWait(100) + .thenPlay(sound(Sound.BLOCK_NOTE_BLOCK_BANJO) volume 0.4f) + + player.playSound(custom) +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 39abe71..0708dcb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,6 @@ subprojects { } dependencies { compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.7.10") - compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.1") } @@ -26,4 +25,9 @@ subprojects { withJavadocJar() withSourcesJar() } + + tasks.assemble { + dependsOn("reobfJar") + } + } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 7fc6f1f..a3df16f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,3 @@ kotlin.code.style=official + +paper_version = 1.20.4-R0.1-SNAPSHOT \ No newline at end of file diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 384dfc0..e2c5626 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -5,12 +5,14 @@ plugins { id("com.github.johnrengelman.shadow") version "7.1.2" `maven-publish` id("org.ajoberstar.grgit") version "4.1.0" + id("io.papermc.paperweight.userdev") version "1.7.1" } +val paper_version: String by rootProject + repositories { mavenCentral() maven("https://maven.pvphub.me/releases") - maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.dmulloy2.net/repository/public/") } @@ -18,6 +20,8 @@ dependencies { shadow(implementation(project(":api"))!!) shadow(implementation("co.pvphub:ProtocolLibDsl:-SNAPSHOT")!!) compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0") + + paperweight.paperDevBundle(paper_version) } tasks.test { diff --git a/settings.gradle.kts b/settings.gradle.kts index 6b9cb00..d42e78b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,14 @@ rootProject.name = "ktgui" include("api") include("plugin") +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://repo.papermc.io/repository/maven-public/") + } +} + plugins { id("com.gradle.enterprise") version("3.15") }