Skip to content

Commit

Permalink
Make Entries allow for Variables
Browse files Browse the repository at this point in the history
  • Loading branch information
gabber235 committed Nov 10, 2024
1 parent 534d2db commit bdde68d
Show file tree
Hide file tree
Showing 128 changed files with 776 additions and 483 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package com.typewritermc.core.extension.annotations
import kotlin.reflect.KClass

@Target(AnnotationTarget.CLASS)
@Repeatable
annotation class GenericConstraint(val type: KClass<*>)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.typewritermc.core.utils.point

import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.qualifier.named
Expand All @@ -10,6 +11,10 @@ import kotlin.reflect.KClass
class Generic(
val data: JsonElement,
) : KoinComponent {
companion object {
val Empty = Generic(JsonObject())
}

private val gson: Gson by inject(named("dataSerializer"))

fun <T> get(klass: Class<T>): T? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ package com.typewritermc.core.utils.point

data class World(
val identifier: String,
)
) {
companion object {
val Empty = World("")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface DialogueEntry : TriggerableEntry {
@Help("The speaker of the dialogue")
val speaker: Ref<SpeakerEntry>

val speakerDisplayName: String
get() = speaker.get()?.displayName ?: ""
val speakerDisplayName: Var<String>
get() = speaker.get()?.displayName ?: ConstVar("")
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import com.typewritermc.core.entries.Ref
import com.typewritermc.core.entries.ref
import com.typewritermc.core.extension.annotations.*
import com.typewritermc.core.utils.point.Position
import com.typewritermc.engine.paper.entry.*
import com.typewritermc.engine.paper.entry.ManifestEntry
import com.typewritermc.engine.paper.entry.PlaceholderEntry
import com.typewritermc.engine.paper.entry.entity.*
import com.typewritermc.engine.paper.utils.EmitterSoundSource
import com.typewritermc.engine.paper.entry.findDisplay
import com.typewritermc.engine.paper.entry.inAudience
import com.typewritermc.engine.paper.utils.Sound
import org.bukkit.entity.Player
import kotlin.reflect.KClass
Expand All @@ -17,12 +19,12 @@ interface SpeakerEntry : PlaceholderEntry {
@Colored
@Placeholder
@Help("The name of the entity that will be displayed in the chat (e.g. 'Steve' or 'Alex').")
val displayName: String
val displayName: Var<String>

@Help("The sound that will be played when the entity speaks.")
val sound: Sound

override fun display(player: Player?): String? = displayName
override fun display(player: Player?): String? = displayName.get(player)
}

/**
Expand Down Expand Up @@ -90,9 +92,14 @@ interface SharedEntityActivityEntry : EntityActivityEntry {
context: ActivityContext,
currentLocation: PositionProperty
): EntityActivity<ActivityContext> {
if (context !is SharedActivityContext) throw WrongActivityContextException(context, SharedActivityContext::class, this)
if (context !is SharedActivityContext) throw WrongActivityContextException(
context,
SharedActivityContext::class,
this
)
return create(context, currentLocation) as EntityActivity<ActivityContext>
}

fun create(context: SharedActivityContext, currentLocation: PositionProperty): EntityActivity<SharedActivityContext>
}

Expand All @@ -102,10 +109,18 @@ interface IndividualEntityActivityEntry : EntityActivityEntry {
context: ActivityContext,
currentLocation: PositionProperty
): EntityActivity<ActivityContext> {
if (context !is IndividualActivityContext) throw WrongActivityContextException(context, IndividualActivityContext::class, this)
if (context !is IndividualActivityContext) throw WrongActivityContextException(
context,
IndividualActivityContext::class,
this
)
return create(context, currentLocation) as EntityActivity<ActivityContext>
}
fun create(context: IndividualActivityContext, currentLocation: PositionProperty): EntityActivity<IndividualActivityContext>

fun create(
context: IndividualActivityContext,
currentLocation: PositionProperty
): EntityActivity<IndividualActivityContext>
}

@Tags("generic_entity_activity")
Expand All @@ -130,7 +145,12 @@ interface GenericEntityActivityEntry : SharedEntityActivityEntry, IndividualEnti
}
}

class WrongActivityContextException(context: ActivityContext, expected: KClass<out ActivityContext>, entry: EntityActivityEntry) : IllegalStateException("""
class WrongActivityContextException(
context: ActivityContext,
expected: KClass<out ActivityContext>,
entry: EntityActivityEntry
) : IllegalStateException(
"""
|The activity context for ${entry.name} is not of the expected type.
|Expected: $expected
|Actual: $context
Expand All @@ -141,4 +161,5 @@ class WrongActivityContextException(context: ActivityContext, expected: KClass<o
|
|To fix this, you need to make sure that the activity matches the entity visibility.
|If you need more help, please join the TypeWriter Discord! https://discord.gg/gs5QYhfv9x
""".trimMargin())
""".trimMargin()
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.typewritermc.engine.paper.entry.entries

import com.typewritermc.core.entries.*
import lirand.api.extensions.server.server
import com.typewritermc.core.extension.annotations.Tags
import com.typewritermc.core.extension.annotations.Colored
import com.typewritermc.core.extension.annotations.Help
import com.typewritermc.core.extension.annotations.Placeholder
import com.typewritermc.core.extension.annotations.Tags
import com.typewritermc.engine.paper.entry.*
import com.typewritermc.engine.paper.entry.quest.QuestStatus
import com.typewritermc.engine.paper.entry.quest.isQuestActive
Expand All @@ -16,6 +15,7 @@ import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders
import com.typewritermc.engine.paper.snippets.snippet
import com.typewritermc.engine.paper.utils.asMini
import com.typewritermc.engine.paper.utils.asMiniWithResolvers
import lirand.api.extensions.server.server
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
Expand All @@ -27,12 +27,12 @@ interface QuestEntry : AudienceFilterEntry, PlaceholderEntry {
@Help("The name to display to the player.")
@Colored
@Placeholder
val displayName: String
val displayName: Var<String>

val facts: List<Ref<ReadableFactEntry>> get() = emptyList()
fun questStatus(player: Player): QuestStatus

override fun display(player: Player?): String = displayName.parsePlaceholders(player)
override fun display(player: Player?): String = displayName.get(player)?.parsePlaceholders(player) ?: ""
override fun display(): AudienceFilter = QuestAudienceFilter(
ref()
)
Expand Down Expand Up @@ -64,7 +64,7 @@ interface ObjectiveEntry : AudienceFilterEntry, PlaceholderEntry, PriorityEntry
@Help("The name to display to the player.")
@Colored
@Placeholder
val display: String
val display: Var<String>

override fun display(): AudienceFilter {
return ObjectiveAudienceFilter(
Expand All @@ -79,6 +79,8 @@ interface ObjectiveEntry : AudienceFilterEntry, PlaceholderEntry, PriorityEntry
criteria.matches(player) -> showingObjectiveDisplay
else -> inactiveObjectiveDisplay
}
val display = display.get(player) ?: ""

return text.asMiniWithResolvers(parsed("display", display)).asMini().parsePlaceholders(player)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ interface SidebarEntry : AudienceFilterEntry, PlaceholderEntry, PriorityEntry {
@Help("The title of the sidebar")
@Colored
@Placeholder
val title: String
val title: Var<String>

override fun display(player: Player?): String? = title.parsePlaceholders(player)
override fun display(player: Player?): String? {
return title.get(player)?.parsePlaceholders(player) ?: ""
}

override fun display(): AudienceFilter = SidebarFilter(ref()) { player ->
PlayerSidebarDisplay(player, SidebarFilter::class, ref())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import org.bukkit.entity.Player
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.qualifier.named
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.reflect.KClass

@Tags("variable")
Expand Down Expand Up @@ -36,6 +38,16 @@ sealed interface Var<T : Any> {
fun get(player: Player): T
}

@OptIn(ExperimentalContracts::class)
fun <T : Any> Var<T>.get(player: Player?): T? {
contract {
returns(null) implies (player == null)
}
if (this is ConstVar<*>) return this.value as T
if (player == null) return null
return get(player)
}

class ConstVar<T : Any>(val value: T) : Var<T> {
override fun get(player: Player): T = value
}
Expand All @@ -49,4 +61,15 @@ class BackedVar<T : Any>(
val entry = ref.get() ?: throw IllegalStateException("Could not find variable entry")
return entry.get(VarContext(player, data, klass))
}
}
}

class MappedVar<T : Any>(
private val variable:Var<T>,
private val mapper: (Player, T) -> T,
) : Var<T> {
override fun get(player: Player): T {
return mapper(player, variable.get(player))
}
}

fun <T : Any> Var<T>.map(mapper: (Player, T) -> T): Var<T> = MappedVar(this, mapper)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class VarSerializer : DataSerializer<Var<*>> {
obj.add("data", context.serialize(src.data))
return obj
}
is MappedVar<*> -> {
throw IllegalStateException("Could not serialize mapped var")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import java.lang.reflect.Type
class WorldSerializer : DataSerializer<World> {
override val type: Type = World::class.java

override fun serialize(src: World?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
return JsonPrimitive(src?.identifier ?: "")
override fun serialize(src: World, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
return JsonPrimitive(src.identifier)
}

override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): World {
val world = json?.asString ?: ""
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): World {
val world = json.asString

val bukkitWorld = server.getWorld(world)
?: server.worlds.firstOrNull { it.name.equals(world, true) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import com.typewritermc.engine.paper.entry.Criteria
import com.typewritermc.engine.paper.entry.Modifier
import com.typewritermc.engine.paper.entry.TriggerableEntry
import com.typewritermc.engine.paper.entry.entries.ActionEntry
import com.typewritermc.engine.paper.entry.entries.ConstVar
import com.typewritermc.engine.paper.entry.entries.Var
import com.typewritermc.engine.paper.utils.ThreadType.SYNC
import com.typewritermc.engine.paper.utils.toTicks
import org.bukkit.entity.Player
Expand All @@ -35,11 +37,11 @@ class AddPotionEffectActionEntry(
override val criteria: List<Criteria> = emptyList(),
override val modifiers: List<Modifier> = emptyList(),
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
val potionEffect: PotionEffectType = PotionEffectType.SPEED,
val potionEffect: Var<PotionEffectType> = ConstVar(PotionEffectType.SPEED),
@Default("10000")
val duration: Duration = Duration.ofSeconds(10),
val duration: Var<Duration> = ConstVar(Duration.ofSeconds(10)),
@Default("1")
val amplifier: Int = 1,
val amplifier: Var<Int> = ConstVar(1),
val ambient: Boolean = false,
@Default("true")
val particles: Boolean = true,
Expand All @@ -50,7 +52,14 @@ class AddPotionEffectActionEntry(
override fun execute(player: Player) {
super.execute(player)

val potion = PotionEffect(potionEffect, duration.toTicks().toInt(), amplifier, ambient, particles, icon)
val potion = PotionEffect(
potionEffect.get(player),
duration.get(player).toTicks().toInt(),
amplifier.get(player),
ambient,
particles,
icon
)
SYNC.launch {
player.addPotionEffect(potion)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import com.typewritermc.core.extension.annotations.Entry
import com.typewritermc.core.utils.point.Vector
import com.typewritermc.engine.paper.entry.Criteria
import com.typewritermc.engine.paper.entry.entries.ActionEntry
import com.typewritermc.engine.paper.entry.entries.ConstVar
import com.typewritermc.engine.paper.entry.entries.Var
import com.typewritermc.engine.paper.utils.toBukkitVector
import org.bukkit.entity.Player

Expand All @@ -25,11 +27,11 @@ class ApplyVelocityActionEntry(
override val criteria: List<Criteria> = emptyList(),
override val modifiers: List<Modifier> = emptyList(),
override val triggers: List<Ref<TriggerableEntry>> = emptyList(),
val force: Vector = Vector(0.0, 0.0, 0.0),
val force: Var<Vector> = ConstVar(Vector(0.0, 0.0, 0.0)),
) : ActionEntry {
override fun execute(player: Player) {
super.execute(player)

player.velocity = player.velocity.add(force.toBukkitVector())
player.velocity = player.velocity.add(force.get(player).toBukkitVector())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import com.typewritermc.engine.paper.entry.Modifier
import com.typewritermc.core.entries.Ref
import com.typewritermc.engine.paper.entry.TriggerableEntry
import com.typewritermc.engine.paper.entry.entries.ActionEntry
import com.typewritermc.engine.paper.entry.entries.ConstVar
import com.typewritermc.engine.paper.entry.entries.Var
import com.typewritermc.engine.paper.extensions.placeholderapi.parsePlaceholders
import com.typewritermc.engine.paper.utils.ThreadType.SYNC
import lirand.api.extensions.server.server
Expand All @@ -33,10 +35,11 @@ class ConsoleCommandActionEntry(
@Placeholder
@MultiLine
@Help("Every line is a different command. Commands should not be prefixed with <code>/</code>.")
private val command: String = "",
private val command: Var<String> = ConstVar(""),
) : ActionEntry {
override fun execute(player: Player) {
super.execute(player)
val command = command.get(player)
// Run in the main thread
if (command.isBlank()) return
SYNC.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import com.typewritermc.engine.paper.entry.Criteria
import com.typewritermc.engine.paper.entry.Modifier
import com.typewritermc.core.entries.Ref
import com.typewritermc.engine.paper.entry.TriggerableEntry
import com.typewritermc.engine.paper.entry.entries.ConstVar
import com.typewritermc.engine.paper.entry.entries.CustomTriggeringActionEntry
import com.typewritermc.engine.paper.entry.entries.Var
import com.typewritermc.engine.paper.utils.ThreadType.DISPATCHERS_ASYNC
import org.bukkit.entity.Player
import java.time.Duration
Expand All @@ -31,12 +33,12 @@ class DelayedActionEntry(
@SerializedName("triggers")
override val customTriggers: List<Ref<TriggerableEntry>> = emptyList(),
@Help("The duration before the next triggers are fired.")
private val duration: Duration = Duration.ZERO,
private val duration: Var<Duration> = ConstVar(Duration.ZERO),
) : CustomTriggeringActionEntry {

override fun execute(player: Player) {
DISPATCHERS_ASYNC.launch {
delay(duration.toMillis())
delay(duration.get(player).toMillis())
super.execute(player)
player.triggerCustomTriggers()
}
Expand Down
Loading

0 comments on commit bdde68d

Please sign in to comment.