Some conversions + destination override support for option listeners

This commit is contained in:
Ceikry
2021-03-13 19:43:27 -06:00
parent 154d570569
commit 3a3602a7e5
7 changed files with 145 additions and 81 deletions
@@ -0,0 +1,42 @@
package rs09.game.content.activity.gnomecooking
import core.game.content.dialogue.FacialExpression
import core.game.node.item.Item
import rs09.game.content.activity.gnomecooking.GnomeTipper.getTip
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
import rs09.tools.stringtools.colorize
class GCCompletionDialogue(val job: GnomeCookingJob) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
0 -> {
val neededItem = player!!.getAttribute<Item>("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM", null)
if (neededItem != null && player!!.inventory.containsItem(neededItem)) {
player!!.dialogueInterpreter.sendDialogues(job.npc_id, FacialExpression.OLD_HAPPY, "Thank you!")
player!!.inventory.remove(neededItem)
player!!.inventory.add(getTip(job.level))
player!!.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL")
player!!.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM")
var curPoints = player!!.getAttribute("$GC_BASE_ATTRIBUTE:$GC_POINTS", 0)
curPoints += 3
if (curPoints == 12) {
player!!.inventory.add(Item(9474))
player!!.sendMessage(colorize("%RYou have been granted a food delivery token. Use it to have food delivered."))
} else if (curPoints % 12 == 0) {
var curRedeems = player!!.getAttribute("$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD", 0)
player!!.setAttribute(
"/save:$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD",
if (curRedeems != 10) ++curRedeems else curRedeems
)
player!!.sendMessage(colorize("%RYou have been granted a single food delivery charge."))
}
player!!.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_POINTS", curPoints)
} else {
player!!.dialogueInterpreter.sendDialogues(job.npc_id, FacialExpression.ANGRY, "Where's my food?!")
}
stage = END_DIALOGUE
}
}
}
}
@@ -2,6 +2,7 @@ package rs09.game.interaction
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.world.map.Location
abstract class InteractionListener : Listener{
val ITEM = 0
@@ -25,4 +26,13 @@ abstract class InteractionListener : Listener{
fun onUseWith(type: Int, used: IntArray, vararg with: Int, handler: (Player, Node, Node) -> Boolean){
Listeners.add(type,used,with,handler)
}
open fun defineDestinationOverrides(){}
fun setDest(type: Int, id: Int,handler: (Node) -> Location){
Listeners.addDestOverride(type,id,handler)
}
fun setDest(type:Int, vararg options: String, handler: (Node) -> Location){
Listeners.addDestOverrides(type,options,handler)
}
}
@@ -4,10 +4,12 @@ import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.world.map.Location
object Listeners {
private val listeners = HashMap<String,(Player, Node) -> Boolean>(1000)
private val useWithListeners = HashMap<String,(Player,Node,Node) -> Boolean>(1000)
private val destinationOverrides = HashMap<String,(Node) -> Location>(100)
@JvmStatic
fun add(id: Int, type: Int, option: Array<out String>, method: (Player,Node) -> Boolean){
@@ -64,6 +66,28 @@ object Listeners {
return listeners["$type:${option.toLowerCase()}"]
}
@JvmStatic
fun addDestOverride(type: Int, id: Int, method: (Node) -> Location){
destinationOverrides["$type:$id"] = method
}
@JvmStatic
fun addDestOverrides(type: Int,options: Array<out String>, method: (Node) -> Location){
for(opt in options){
destinationOverrides["$type:${opt.toLowerCase()}"] = method
}
}
@JvmStatic
fun getOverride(type: Int,id: Int): ((Node) -> Location)?{
return destinationOverrides["$type:$id"]
}
@JvmStatic
fun getOverride(type: Int,option: String): ((Node) -> Location)?{
return destinationOverrides["$type:$option"]
}
@JvmStatic
fun run(used: Node, with: Node, type: Int,player: Player): Boolean{
val flag = when(type){
@@ -72,11 +96,14 @@ object Listeners {
else -> DestinationFlag.OBJECT
}
if(player.locks.isInteractionLocked) return false
var flipped = false
val method = get(used.id,with.id,type) ?: get(with.id,used.id,type).also { flipped = true } ?: return false
if(type != 0) {
if(player.locks.isMovementLocked) return false
player.pulseManager.run(object : MovementPulse(player, with, flag) {
override fun pulse(): Boolean {
player.faceLocation(with.location)
@@ -100,10 +127,14 @@ object Listeners {
else -> DestinationFlag.OBJECT
}
if(player.locks.isInteractionLocked) return false
val method = get(id,type,option) ?: get(option,type) ?: return false
val destOverride = getOverride(type,node.id) ?: getOverride(type,option.toLowerCase())
if(type != 0) {
player.pulseManager.run(object : MovementPulse(player, node, flag) {
if(player.locks.isMovementLocked) return false
player.pulseManager.run(object : MovementPulse(player, node, flag, destOverride) {
override fun pulse(): Boolean {
player.faceLocation(node.location)
method.invoke(player,node)
@@ -0,0 +1,44 @@
package rs09.game.interaction.npc
import core.game.node.entity.npc.NPC
import rs09.game.content.activity.gnomecooking.*
import rs09.game.interaction.InteractionListener
/**
* Handles the NPC talk-to option.
* @author Ceikry
*/
class NPCTalkListener : InteractionListener() {
override fun defineListeners() {
on(NPC,"talk-to","talk"){player,node ->
val npc = node.asNpc()
if (!npc.getAttribute("facing_booth", false)) {
npc.faceLocation(player.location)
}
//I'm sorry for this but it was honestly the best way to do this
if (player.getAttribute(GC_BASE_ATTRIBUTE + ":" + GC_JOB_ORDINAL, -1) != -1) {
val job = GnomeCookingJob.values()[player.getAttribute(GC_BASE_ATTRIBUTE + ":" + GC_JOB_ORDINAL, -1)]
if (node.getId() == job.npc_id && !player.getAttribute(GC_BASE_ATTRIBUTE + ":" + GC_JOB_COMPLETE, false)) {
player.dialogueInterpreter.open(GCCompletionDialogue(job))
return@on true
}
}
return@on player.dialogueInterpreter.open(npc.id, npc)
}
}
override fun defineDestinationOverrides() {
setDest(NPC,"talk","talk-to"){node ->
val npc = node as NPC
if (npc.getAttribute("facing_booth", false)) {
val offsetX = npc.direction.stepX shl 1
val offsetY = npc.direction.stepY shl 1
return@setDest npc.location.transform(offsetX, offsetY, 0)
}
return@setDest node.location
}
}
}
@@ -73,7 +73,9 @@ object PluginManager {
} catch (e: Exception) {e.printStackTrace()}
}
result.getSubclasses("rs09.game.interaction.InteractionListener").forEach {
(it.loadClass().newInstance() as InteractionListener).defineListeners()
val clazz = it.loadClass().newInstance() as InteractionListener
clazz.defineListeners()
clazz.defineDestinationOverrides()
}
}