Skip to content

Commit

Permalink
impl sound builder + fix future on scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt-MX committed May 25, 2024
1 parent 9589a66 commit c3ef25e
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 10 deletions.
5 changes: 5 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -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 {
Expand Down
10 changes: 2 additions & 8 deletions api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,8 @@ fun asyncDelayed(delay: Long, task: BukkitTask.() -> Unit): BukkitTask {
* @author MattMX
* @param block that returns our value
*/
fun <T> future(block: () -> T) : CompletableFuture<T> {
val future = CompletableFuture<T>()
async {
val result = block()
future.complete(result)
}
return future
}
fun <T> future(block: CompletableFuture<T>.() -> Unit): CompletableFuture<T> =
CompletableFuture<T>().apply(block)

/**
* Similar to [future], will return a [Future] with the type you want.
Expand Down
170 changes: 170 additions & 0 deletions api/src/main/kotlin/com/mattmx/ktgui/sound/ComplexSoundBuilder.kt
Original file line number Diff line number Diff line change
@@ -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<Supplier<Location>>()
private var steps = arrayListOf<Step>()

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<Location>) = 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<Supplier<Location>>()
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<Location>) = 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)
}
6 changes: 5 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ 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")
}

java {
withJavadocJar()
withSourcesJar()
}

tasks.assemble {
dependsOn("reobfJar")
}

}
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
kotlin.code.style=official

paper_version = 1.20.4-R0.1-SNAPSHOT
6 changes: 5 additions & 1 deletion plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@ 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/")
}

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 {
Expand Down
8 changes: 8 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down

0 comments on commit c3ef25e

Please sign in to comment.