mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-05 08:40:08 +00:00
WIP
This commit is contained in:
@@ -20,16 +20,9 @@ abstract class KotlinPluginScript(var world: World, val context: PluginContext)
|
||||
|
||||
private var stopListener: (World) -> Unit = { _ -> }
|
||||
|
||||
fun <T : Any, C : ListenableContext, I : PredicateContext> on(
|
||||
listenable: Listenable<T, C, I>,
|
||||
callback: C.() -> Unit
|
||||
) {
|
||||
registerListener(listenable, null, callback)
|
||||
}
|
||||
|
||||
internal fun <T : Any, C : ListenableContext, I : PredicateContext> registerListener(
|
||||
listenable: Listenable<T, C, I>,
|
||||
predicateContext: I?,
|
||||
predicateContext: I,
|
||||
callback: C.() -> Unit
|
||||
) {
|
||||
// Smart-casting/type-inference is completely broken in this function in intelliJ, so assign to otherwise
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.apollo.game.plugin.kotlin
|
||||
|
||||
import org.apollo.game.message.handler.MessageHandler
|
||||
import org.apollo.game.model.World
|
||||
import org.apollo.game.model.entity.Player
|
||||
import org.apollo.game.model.event.Event
|
||||
import org.apollo.game.model.event.EventListener
|
||||
import org.apollo.net.message.Message
|
||||
@@ -16,12 +17,20 @@ sealed class Listenable<T : Any, C : ListenableContext, P : PredicateContext> {
|
||||
|
||||
abstract class EventListenable<T : Event, C : ListenableContext, P : PredicateContext> : Listenable<T, C, P>() {
|
||||
|
||||
abstract fun createHandler(world: World, predicateContext: P?, callback: C.() -> Unit): EventListener<T>
|
||||
abstract fun createHandler(world: World, predicateContext: P, callback: C.() -> Unit): EventListener<T>
|
||||
|
||||
}
|
||||
|
||||
abstract class MessageListenable<T : Message, C : ListenableContext, P : PredicateContext> : Listenable<T, C, P>() {
|
||||
|
||||
abstract fun createHandler(world: World, predicateContext: P?, callback: C.() -> Unit): MessageHandler<T>
|
||||
protected fun handler(world: World, callback: (Player, T) -> Unit): MessageHandler<T> {
|
||||
return object : MessageHandler<T>(world) {
|
||||
override fun handle(player: Player, message: T) {
|
||||
callback(player, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun createHandler(world: World, predicateContext: P, callback: C.() -> Unit): MessageHandler<T>
|
||||
|
||||
}
|
||||
|
||||
@@ -31,16 +31,16 @@ class ButtonClick(override val player: Player, val button: Int) : PlayerContext
|
||||
companion object : MessageListenable<ButtonMessage, ButtonClick, ButtonPredicateContext>() {
|
||||
|
||||
override val type = ButtonMessage::class
|
||||
|
||||
|
||||
override fun createHandler(
|
||||
world: World,
|
||||
predicateContext: ButtonPredicateContext?,
|
||||
predicateContext: ButtonPredicateContext,
|
||||
callback: ButtonClick.() -> Unit
|
||||
): MessageHandler<ButtonMessage> {
|
||||
return object : MessageHandler<ButtonMessage>(world) {
|
||||
|
||||
override fun handle(player: Player, message: ButtonMessage) {
|
||||
if (predicateContext == null || predicateContext.button == message.widgetId) {
|
||||
if (predicateContext.button == message.widgetId) {
|
||||
val context = ButtonClick(player, message.widgetId)
|
||||
context.callback()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import org.apollo.cache.def.NpcDefinition
|
||||
import org.apollo.game.message.impl.NpcActionMessage
|
||||
import org.apollo.game.message.impl.ObjectActionMessage
|
||||
import org.apollo.game.plugin.kotlin.KotlinPluginScript
|
||||
import org.apollo.game.plugin.kotlin.message.action.npc.NpcAction
|
||||
import org.apollo.game.plugin.kotlin.message.action.npc.NpcActionPredicateContext
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.InteractiveObject
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.ObjectAction
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.ObjectActionPredicateContext
|
||||
|
||||
/**
|
||||
* Registers a listener for [ObjectActionMessage]s that occur on any of the given [InteractiveObject]s using the
|
||||
* given [option] (case-insensitive).
|
||||
*
|
||||
* ```
|
||||
* on(ObjectAction, option = "Open", objects = DOORS.toList()) {
|
||||
* player.sendMessage("You open the door.")
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
fun KotlinPluginScript.on(
|
||||
listenable: ObjectAction.Companion,
|
||||
option: String,
|
||||
callback: ObjectAction<*>.() -> Unit
|
||||
) {
|
||||
registerListener(listenable, ObjectActionPredicateContext(option, emptyList()), callback)
|
||||
}
|
||||
|
||||
fun <T : InteractiveObject> KotlinPluginScript.on(
|
||||
listenable: ObjectAction.Companion,
|
||||
option: String,
|
||||
interactives: List<T>,
|
||||
callback: ObjectAction<T>.() -> Unit
|
||||
) {
|
||||
val cb = callback as ObjectAction<*>.() -> Unit
|
||||
registerListener(listenable, ObjectActionPredicateContext<T>(option, interactives.toList()), cb)
|
||||
}
|
||||
|
||||
|
||||
fun <T : InteractiveObject> KotlinPluginScript.on(
|
||||
listenable: ObjectAction.Companion,
|
||||
option: String,
|
||||
objects: Array<T>,
|
||||
callback: ObjectAction<T>.() -> Unit
|
||||
) {
|
||||
on(listenable, option, objects.toList(), callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a listener for [NpcActionMessage]s that occur on any of the given [NpcDefinition]s using the
|
||||
* given [option] (case-insensitive).
|
||||
*
|
||||
* ```
|
||||
* on(NpcAction, option = "Talk-to", npcs = npcs("(Gnome )?Banker") {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
fun KotlinPluginScript.on(
|
||||
listenable: NpcAction.Companion,
|
||||
option: String,
|
||||
npcs: Sequence<NpcDefinition>,
|
||||
callback: NpcAction.() -> Unit
|
||||
) {
|
||||
registerListener(listenable, NpcActionPredicateContext(option, npcs.toList()), callback)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.apollo.game.plugin.kotlin.message.action.npc
|
||||
|
||||
import org.apollo.cache.def.NpcDefinition
|
||||
import org.apollo.game.message.handler.MessageHandler
|
||||
import org.apollo.game.message.impl.NpcActionMessage
|
||||
import org.apollo.game.message.impl.ObjectActionMessage
|
||||
import org.apollo.game.model.World
|
||||
import org.apollo.game.model.entity.Npc
|
||||
import org.apollo.game.model.entity.Player
|
||||
import org.apollo.game.plugin.kotlin.KotlinPluginScript
|
||||
import org.apollo.game.plugin.kotlin.MessageListenable
|
||||
import org.apollo.game.plugin.kotlin.message.action.ActionContext
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.InteractiveObject
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.ObjectAction
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.ObjectActionPredicateContext
|
||||
|
||||
class NpcAction(override val option: String, override val player: Player, val target: Npc) : ActionContext {
|
||||
|
||||
companion object : MessageListenable<NpcActionMessage, NpcAction, NpcActionPredicateContext>() {
|
||||
override val type = NpcActionMessage::class
|
||||
|
||||
override fun createHandler(world: World, predicateContext: NpcActionPredicateContext, callback: NpcAction.() -> Unit): MessageHandler<NpcActionMessage> {
|
||||
val ids = predicateContext.npcDefinitions.map(NpcDefinition::getId).toSet()
|
||||
|
||||
return handler(world) { player, message ->
|
||||
val npc = world.npcRepository[message.index]
|
||||
val option = npc.definition.interactions[message.option]
|
||||
val npcMatched = ids.isEmpty() || npc.id in ids
|
||||
|
||||
if (npcMatched && predicateContext.option.equals(option, ignoreCase = true)) {
|
||||
val context = NpcAction(option, player, npc)
|
||||
context.callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.apollo.game.plugin.kotlin.message.action.npc
|
||||
|
||||
import org.apollo.cache.def.NpcDefinition
|
||||
import org.apollo.game.plugin.kotlin.message.action.ActionPredicateContext
|
||||
import org.apollo.game.plugin.kotlin.message.action.obj.InteractiveObject
|
||||
|
||||
data class NpcActionPredicateContext(
|
||||
override val option: String,
|
||||
val npcDefinitions: List<NpcDefinition>
|
||||
) : ActionPredicateContext(option)
|
||||
-2
@@ -9,6 +9,4 @@ interface InteractiveObject {
|
||||
|
||||
val id: Int
|
||||
|
||||
fun instanceOf(other: GameObject): Boolean // TODO alternative name?
|
||||
|
||||
}
|
||||
+17
-45
@@ -31,30 +31,6 @@ fun <T : InteractiveObject> KotlinPluginScript.on(
|
||||
registerListener(listenable, ObjectActionPredicateContext(option, objects), callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a listener for [ObjectActionMessage]s that occur on any of the given [InteractiveObject]s using the
|
||||
* given [option] (case-insensitive).
|
||||
*
|
||||
* ```
|
||||
* on(ObjectAction, option = "Open", objects = DOORS.toList()) {
|
||||
* player.sendMessage("You open the door.")
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
fun KotlinPluginScript.on(
|
||||
listenable: ObjectAction.Companion,
|
||||
option: String,
|
||||
callback: ObjectAction<*>.() -> Unit
|
||||
) {
|
||||
registerListener(listenable, ObjectActionPredicateContext(option, emptyList()), callback)
|
||||
}
|
||||
|
||||
fun KotlinPluginScript.x() {
|
||||
on(ObjectAction, "walk") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An interaction between a [Player] and an [interactive] [GameObject].
|
||||
*/
|
||||
@@ -71,35 +47,31 @@ class ObjectAction<T : InteractiveObject?>( // TODO split into two classes, one
|
||||
|
||||
override fun createHandler(
|
||||
world: World,
|
||||
predicateContext: ObjectActionPredicateContext<*>?,
|
||||
predicateContext: ObjectActionPredicateContext<*>,
|
||||
callback: ObjectAction<*>.() -> Unit
|
||||
): MessageHandler<ObjectActionMessage> {
|
||||
return object : MessageHandler<ObjectActionMessage>(world) {
|
||||
val objectMap = predicateContext.objects.associateBy(InteractiveObject::id)
|
||||
|
||||
override fun handle(player: Player, message: ObjectActionMessage) {
|
||||
val def = ObjectDefinition.lookup(message.id)
|
||||
val option = def.menuActions[message.option]
|
||||
return handler(world) { player, message ->
|
||||
val def = ObjectDefinition.lookup(message.id)
|
||||
val option = def.menuActions[message.option]
|
||||
|
||||
val target = world.regionRepository
|
||||
.fromPosition(message.position)
|
||||
.getEntities<GameObject>(message.position, EntityType.DYNAMIC_OBJECT, EntityType.STATIC_OBJECT)
|
||||
.find { it.definition == def }
|
||||
?: return // Could happen if object was despawned this tick, before calling this handle function
|
||||
val target = world.regionRepository
|
||||
.fromPosition(message.position)
|
||||
.getEntities<GameObject>(message.position, EntityType.DYNAMIC_OBJECT, EntityType.STATIC_OBJECT)
|
||||
.find { it.definition == def }
|
||||
?: return@handler // Could happen if object was despawned this tick, before calling this handle function
|
||||
|
||||
val context = when { // Evaluation-order matters here.
|
||||
predicateContext == null -> ObjectAction<InteractiveObject?>(player, option, target, null)
|
||||
!predicateContext.option.equals(option, ignoreCase = true) -> return
|
||||
predicateContext.objects.isEmpty() -> ObjectAction(player, option, target, null)
|
||||
predicateContext.objects.any { it.instanceOf(target) } -> {
|
||||
val interactive = predicateContext.objects.find { it.instanceOf(target) } ?: return
|
||||
ObjectAction(player, option, target, interactive)
|
||||
}
|
||||
else -> return
|
||||
val context = when { // Evaluation-order matters here.
|
||||
!predicateContext.option.equals(option, ignoreCase = true) -> return@handler
|
||||
objectMap.isEmpty() -> ObjectAction(player, option, target, null)
|
||||
objectMap.containsKey(message.id) -> {
|
||||
ObjectAction(player, option, target, objectMap[message.id])
|
||||
}
|
||||
|
||||
context.callback()
|
||||
else -> return@handler
|
||||
}
|
||||
|
||||
context.callback()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user