WorkForOptionHandler.kt -> WorkForOptionListener.kt

Added ability to open DialogueFiles straight from the interpreter. EnchantedJewelleryPlugin.java -> EnchantedJewelleryListener.kt and moved jewellery dialogue to DialogueFile EnchantedJewelleryDialogueFile.kt
This commit is contained in:
Ceikry
2021-03-11 19:25:56 -06:00
parent 3545f4d240
commit 2d8baa565d
13 changed files with 259 additions and 303 deletions
@@ -14,7 +14,7 @@ abstract class DialogueFile {
var dialoguePlugin: DialoguePlugin? = null var dialoguePlugin: DialoguePlugin? = null
abstract fun handle(componentID: Int, buttonID: Int) abstract fun handle(componentID: Int, buttonID: Int)
fun load(player: Player, npc: NPC, interpreter: DialogueInterpreter): DialogueFile{ fun load(player: Player, npc: NPC?, interpreter: DialogueInterpreter): DialogueFile{
this.player = player this.player = player
this.npc = npc this.npc = npc
this.interpreter = interpreter this.interpreter = interpreter
@@ -137,6 +137,11 @@ public final class DialogueInterpreter {
return true; return true;
} }
public void open(DialogueFile file,Object... args){
this.dialogue = new EmptyPlugin(player,file);
this.dialogue.open(args);
}
/** /**
* Starts a dialogue script. * Starts a dialogue script.
* @param script The script. * @param script The script.
@@ -276,6 +276,7 @@ public abstract class DialoguePlugin implements Plugin<Player> {
* @param file the DialogueFile to load. * @param file the DialogueFile to load.
*/ */
public void loadFile(DialogueFile file){ public void loadFile(DialogueFile file){
if(file == null) return;
this.file = file.load(player,npc,interpreter); this.file = file.load(player,npc,interpreter);
this.file.setDialoguePlugin(this); this.file.setDialoguePlugin(this);
stage = START_DIALOGUE; stage = START_DIALOGUE;
@@ -0,0 +1,30 @@
package core.game.content.dialogue
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.tools.START_DIALOGUE
class EmptyPlugin(player: Player? = null,val file: DialogueFile?) : DialoguePlugin(player) {
override fun newInstance(player: Player?): DialoguePlugin {
return EmptyPlugin(player,null)
}
override fun open(vararg args: Any?): Boolean {
if(args.isNotEmpty() && args[0] is NPC){
npc = args[0] as NPC
}
stage = START_DIALOGUE
loadFile(file)
interpreter.handle(0,0)
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
return true
}
override fun getIds(): IntArray {
return intArrayOf(Integer.MAX_VALUE)
}
}
@@ -0,0 +1,17 @@
package core.game.content.global
import core.game.content.dialogue.DialogueFile
import core.game.node.item.Item
import core.tools.START_DIALOGUE
class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
START_DIALOGUE -> interpreter!!.sendOptions("Where would you like to go?", *jewellery.options).also { stage++ }
1 -> {
jewellery.use(player, item, buttonID - 1, player!!.equipment.containsItem(item))
end()
}
}
}
}
@@ -0,0 +1,34 @@
package core.game.content.jobs
import core.game.content.dialogue.DialogueFile
import core.game.node.item.Item
import core.tools.END_DIALOGUE
class CancelJobDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when(stage){
0 -> npc("Would you like to cancel your job?","It will cost 500 coins.").also { stage++ }
1 -> options("Yes, please.","No, thanks.").also { stage++ }
2 -> when(buttonID){
1 -> player("Yes, please.").also{ stage = 10 }
2 -> player("No, thanks.").also { stage = 20 }
}
10 -> npc("Alright then, hand over the money.").also { stage++ }
11 -> if(player!!.inventory.contains(995,500)){
player("Here you go.")
player!!.inventory.remove(Item(995,500))
player!!.removeAttribute("jobs:id")
player!!.removeAttribute("jobs:amount")
player!!.removeAttribute("jobs:original_amount")
player!!.removeAttribute("jobs:type")
stage = END_DIALOGUE
} else {
player("Oh, I don't seem to have the money...")
stage++
}
12 -> npc("Ah, that sucks! Get to work.").also { stage = END_DIALOGUE }
20 -> npc("Alright then, get to work!").also { stage = END_DIALOGUE }
}
}
}
@@ -6,6 +6,7 @@ import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager import core.game.node.item.GroundItemManager
import core.game.node.item.Item import core.game.node.item.Item
import core.game.system.SystemLogger
object JobManager { object JobManager {
@JvmStatic @JvmStatic
@@ -55,7 +56,8 @@ object JobManager {
var amount = player.inventory.getAmount(it) var amount = player.inventory.getAmount(it)
val needed = player.getAttribute("jobs:amount",0) val needed = player.getAttribute("jobs:amount",0)
if(amount == 0){ if(amount == 0){
player.dialogueInterpreter.open(9987215,npc) player.dialogueInterpreter.open(CancelJobDialogueFile(),npc)
SystemLogger.logAlert("Opening CancelJob")
return return
} }
if(amount < needed){ if(amount < needed){
@@ -1,174 +0,0 @@
package core.game.content.jobs
import GatheringJobs
import SlayingJob
import core.cache.def.impl.NPCDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.plugin.PluginManager
import core.tools.Items
import core.game.content.dialogue.DialoguePlugin
/**
* Handles the work-for actions for the NPCs
* @author Ceikry
*/
@Initializable
class WorkForOptionHandler : OptionHandler() {
val possibleWeaponLooks = arrayListOf(
Items.BRONZE_SCIMITAR_1321,
Items.STEEL_SCIMITAR_1325,
Items.RUNE_SCIMITAR_1333,
Items.BRONZE_MACE_1422,
Items.MITHRIL_WARHAMMER_1343
)
val gatheringMap = hashMapOf<Int,List<GatheringJobs>>(
0 to listOf(GatheringJobs.AIR_RUNE,GatheringJobs.COWHIDES,GatheringJobs.WATER_RUNE),
922 to listOf(GatheringJobs.ASHES,GatheringJobs.AIR_RUNE,GatheringJobs.WATER_RUNE),
3807 to listOf(GatheringJobs.COWHIDES),
4899 to listOf(GatheringJobs.CAKE,GatheringJobs.ANCHOVY_PIZZA,GatheringJobs.COOKED_SALMON,GatheringJobs.COOKED_TROUT,GatheringJobs.MEAT_PIE,GatheringJobs.MEAT_PIZZA,GatheringJobs.PLAIN_PIZZA),
4901 to listOf(GatheringJobs.RAW_SALMON,GatheringJobs.RAW_SHRIMP,GatheringJobs.RAW_TROUT),
4902 to listOf(GatheringJobs.COPPER_ORE,GatheringJobs.TIN_ORE,GatheringJobs.COAL,GatheringJobs.IRON_ORE,GatheringJobs.SILVER_ORE,GatheringJobs.GOLD_ORE),
4903 to listOf(GatheringJobs.SILVER_ORE),
4904 to listOf(GatheringJobs.BRONZE_BAR,GatheringJobs.IRON_BAR,GatheringJobs.STEEL_BAR),
4906 to listOf(GatheringJobs.LOG,GatheringJobs.OAK,GatheringJobs.WILLOW)
)
val typeMap = hashMapOf(
0 to 0,
705 to 1,
922 to 0,
1861 to 1,
3807 to 0,
4899 to 0,
4901 to 0,
4902 to 0,
4903 to 0,
4904 to 0,
4906 to 0,
4707 to 1
)
@Throws(Throwable::class)
override fun newInstance(arg: Any?): Plugin<Any>? {
NPCDefinition.forId(4906).handlers["option:work-for"] = this
NPCDefinition.forId(4707).handlers["option:work-for"] = this
NPCDefinition.forId(4904).handlers["option:work-for"] = this
NPCDefinition.forId(4903).handlers["option:work-for"] = this
NPCDefinition.forId(4902).handlers["option:work-for"] = this
NPCDefinition.forId(4901).handlers["option:work-for"] = this
NPCDefinition.forId(4899).handlers["option:work-for"] = this
NPCDefinition.forId(3807).handlers["option:work-for"] = this
NPCDefinition.forId(1861).handlers["option:work-for"] = this
NPCDefinition.forId(922).handlers["option:work-for"] = this
NPCDefinition.forId(705).handlers["option:work-for"] = this
NPCDefinition.forId(0).handlers["option:work-for"] = this
PluginManager.definePlugin(CancelJobDialogue())
return this
}
override fun handle(player: Player, node: Node, option: String): Boolean {
var amount = 0
var jobId = 0
if(player.getAttribute("jobs:id",-1) != -1){
JobManager.rewardPlayer(player,node.asNpc())
return true
}
val type = typeMap[node.id] ?: return false
jobId = if(type == 0) {
var job = gatheringMap[node.id]?.random()
while(!checkRequirement(player,job)){
job = gatheringMap[node.id]?.random()
}
amount = job?.getAmount() ?: 0
job?.ordinal ?: 0
} else {
SlayingJob.values().random().ordinal.also { amount = SlayingJob.values()[it].getAmount() }
}
when(type){
0 -> {
val job = GatheringJobs.values()[jobId]
player.dialogueInterpreter.sendItemMessage(job.itemId,"You are assigned to gather $amount ${Item(job.itemId).name.toLowerCase()}")
// Have the Fishing Tutor send you on an errand
if (node.id == 4901) player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 14);
}
1 -> {
val job = SlayingJob.values()[jobId]
player.dialogueInterpreter.sendItemMessage(possibleWeaponLooks.random(),"You are assigned to kill $amount ${NPC(job.ids[0]).name.toLowerCase()}")
}
}
player.setAttribute("/save:jobs:id",jobId)
player.setAttribute("/save:jobs:amount",amount)
player.setAttribute("/save:jobs:original_amount",amount)
player.setAttribute("/save:jobs:type",type)
return true
}
fun checkRequirement(player: Player, jobs: GatheringJobs?): Boolean{
jobs ?: return true
val requirement: Pair<Int,Int> = Pair(jobs.lvlReq,jobs.skill)
if(player.skills.getLevel(requirement.second) < requirement.first){
return false
}
return true
}
class CancelJobDialogue(player: Player? = null) : DialoguePlugin(player){
override fun newInstance(player: Player?): DialoguePlugin {
return CancelJobDialogue(player)
}
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
player ?: return false
npc("Would you like to cancel your job?","It will cost 500 coins.")
stage = 0
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when(stage){
0 -> options("Yes, please.","No, thanks.").also { stage++ }
1 -> when(buttonId){
1 -> player("Yes, please.").also{ stage = 10 }
2 -> player("No, thanks.").also { stage = 20 }
}
10 -> npc("Alright then, hand over the money.").also { stage++ }
11 -> if(player.inventory.contains(995,500)){
player("Here you go.")
player.inventory.remove(Item(995,500))
player.removeAttribute("jobs:id")
player.removeAttribute("jobs:amount")
player.removeAttribute("jobs:original_amount")
player.removeAttribute("jobs:type")
stage = 1000
} else {
player("Oh, I don't seem to have the money...")
stage++
}
12 -> npc("Ah, that sucks! Get to work.").also { stage = 1000 }
20 -> npc("Alright then, get to work!").also { stage = 1000 }
1000 -> end()
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(9987215) //Random number to avoid colliding with other dialogues
}
}
}
@@ -0,0 +1,116 @@
package core.game.content.jobs
import GatheringJobs
import SlayingJob
import core.cache.def.impl.NPCDefinition
import core.game.interaction.OptionHandler
import core.game.node.Node
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.plugin.Initializable
import core.plugin.Plugin
import core.plugin.PluginManager
import core.tools.Items
import core.game.content.dialogue.DialoguePlugin
import core.game.interaction.OptionListener
/**
* Handles the work-for actions for the NPCs
* @author Ceikry
*/
class WorkForOptionListener : OptionListener() {
val possibleWeaponLooks = arrayListOf(
Items.BRONZE_SCIMITAR_1321,
Items.STEEL_SCIMITAR_1325,
Items.RUNE_SCIMITAR_1333,
Items.BRONZE_MACE_1422,
Items.MITHRIL_WARHAMMER_1343
)
val gatheringMap = hashMapOf<Int,List<GatheringJobs>>(
0 to listOf(GatheringJobs.AIR_RUNE,GatheringJobs.COWHIDES,GatheringJobs.WATER_RUNE),
922 to listOf(GatheringJobs.ASHES,GatheringJobs.AIR_RUNE,GatheringJobs.WATER_RUNE),
3807 to listOf(GatheringJobs.COWHIDES),
4899 to listOf(GatheringJobs.CAKE,GatheringJobs.ANCHOVY_PIZZA,GatheringJobs.COOKED_SALMON,GatheringJobs.COOKED_TROUT,GatheringJobs.MEAT_PIE,GatheringJobs.MEAT_PIZZA,GatheringJobs.PLAIN_PIZZA),
4901 to listOf(GatheringJobs.RAW_SALMON,GatheringJobs.RAW_SHRIMP,GatheringJobs.RAW_TROUT),
4902 to listOf(GatheringJobs.COPPER_ORE,GatheringJobs.TIN_ORE,GatheringJobs.COAL,GatheringJobs.IRON_ORE,GatheringJobs.SILVER_ORE,GatheringJobs.GOLD_ORE),
4903 to listOf(GatheringJobs.SILVER_ORE),
4904 to listOf(GatheringJobs.BRONZE_BAR,GatheringJobs.IRON_BAR,GatheringJobs.STEEL_BAR),
4906 to listOf(GatheringJobs.LOG,GatheringJobs.OAK,GatheringJobs.WILLOW)
)
val typeMap = hashMapOf(
0 to 0,
705 to 1,
922 to 0,
1861 to 1,
3807 to 0,
4899 to 0,
4901 to 0,
4902 to 0,
4903 to 0,
4904 to 0,
4906 to 0,
4707 to 1
)
val IDs = typeMap.keys.toIntArray()
override fun defineListeners() {
on(IDs,NPC,"work-for"){ player,node ->
var amount = 0
var jobId = 0
if(player.getAttribute("jobs:id",-1) != -1){
JobManager.rewardPlayer(player,node.asNpc())
return@on true
}
val type = typeMap[node.id] ?: return@on false
jobId = if(type == 0) {
var job = gatheringMap[node.id]?.random()
while(!checkRequirement(player,job)){
job = gatheringMap[node.id]?.random()
}
amount = job?.getAmount() ?: 0
job?.ordinal ?: 0
} else {
SlayingJob.values().random().ordinal.also { amount = SlayingJob.values()[it].getAmount() }
}
when(type){
0 -> {
val job = GatheringJobs.values()[jobId]
player.dialogueInterpreter.sendItemMessage(job.itemId,"You are assigned to gather $amount ${Item(job.itemId).name.toLowerCase()}")
// Have the Fishing Tutor send you on an errand
if (node.id == 4901) player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 14);
}
1 -> {
val job = SlayingJob.values()[jobId]
player.dialogueInterpreter.sendItemMessage(possibleWeaponLooks.random(),"You are assigned to kill $amount ${NPC(job.ids[0]).name.toLowerCase()}")
}
}
player.setAttribute("/save:jobs:id",jobId)
player.setAttribute("/save:jobs:amount",amount)
player.setAttribute("/save:jobs:original_amount",amount)
player.setAttribute("/save:jobs:type",type)
return@on true
}
}
fun checkRequirement(player: Player, jobs: GatheringJobs?): Boolean{
jobs ?: return true
val requirement: Pair<Int,Int> = Pair(jobs.lvlReq,jobs.skill)
if(player.skills.getLevel(requirement.second) < requirement.first){
return false
}
return true
}
}
@@ -7,13 +7,15 @@ object Listeners {
private val listeners = HashMap<String,(Player, Node) -> Boolean>() private val listeners = HashMap<String,(Player, Node) -> Boolean>()
@JvmStatic @JvmStatic
fun add(id: Int, type: Int, option: String, method: (Player,Node) -> Boolean){ fun add(id: Int, type: Int, option: Array<out String>, method: (Player,Node) -> Boolean){
val key = "$id:$type:${option.toLowerCase()}" for(opt in option) {
listeners[key] = method val key = "$id:$type:${opt.toLowerCase()}"
listeners[key] = method
}
} }
@JvmStatic @JvmStatic
fun add(ids: IntArray, type: Int, option: String, method: (Player,Node) -> Boolean){ fun add(ids: IntArray, type: Int, option: Array<out String>, method: (Player,Node) -> Boolean){
for(id in ids){ for(id in ids){
add(id,type,option,method) add(id,type,option,method)
} }
@@ -8,7 +8,10 @@ abstract class OptionListener {
val OBJECT = 1 val OBJECT = 1
val NPC = 2 val NPC = 2
abstract fun defineListeners() abstract fun defineListeners()
fun on(id: Int, type: Int, option: String,handler: (Player, Node) -> Boolean){ fun on(id: Int, type: Int, vararg option: String,handler: (Player, Node) -> Boolean){
Listeners.add(id,type,option,handler) Listeners.add(id,type,option,handler)
} }
fun on(ids: IntArray, type: Int, vararg option: String, handler: (Player, Node) -> Boolean){
Listeners.add(ids,type,option,handler)
}
} }
@@ -11,6 +11,7 @@ import core.game.container.access.BitregisterAssembler;
import core.game.container.access.InterfaceContainer; import core.game.container.access.InterfaceContainer;
import core.game.container.impl.EquipmentContainer; import core.game.container.impl.EquipmentContainer;
import core.game.content.global.action.EquipHandler; import core.game.content.global.action.EquipHandler;
import core.game.interaction.Listeners;
import core.game.interaction.OptionHandler; import core.game.interaction.OptionHandler;
import core.game.node.entity.combat.DeathTask; import core.game.node.entity.combat.DeathTask;
import core.game.node.entity.player.Player; import core.game.node.entity.player.Player;
@@ -190,6 +191,9 @@ public final class EquipmentInterface extends ComponentPlugin {
if (item == null) { if (item == null) {
return; return;
} }
if(Listeners.run(item.getId(),0,"operate",player,item)){
return;
}
OptionHandler handler = item.getOperateHandler(); OptionHandler handler = item.getOperateHandler();
if (handler != null && handler.handle(player, item, "operate")) { if (handler != null && handler.handle(player, item, "operate")) {
return; return;
@@ -1,131 +1,47 @@
package core.game.interaction.item; package core.game.interaction.item
import core.cache.def.impl.ItemDefinition; import core.game.interaction.OptionListener
import core.game.content.dialogue.DialoguePlugin; import core.game.content.global.EnchantedJewellery
import core.game.content.global.EnchantedJewellery; import core.game.content.global.EnchantedJewelleryDialogueFile
import core.game.interaction.OptionHandler; import java.util.ArrayList
import core.game.node.Node;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.plugin.Initializable;
import core.plugin.Plugin;
/** /**
* Represents the plugin used to handle enchanted jewellery transportation. * Listener for enchanted jewellery options
* @author 'Vexia * @author Ceikry
* @version 1.0
*/ */
@Initializable class EnchantedJewelleryListener : OptionListener() {
public final class EnchantedJewelleryPlugin extends OptionHandler { val IDs: IntArray
@Override init {
public Plugin<Object> newInstance(Object arg) throws Throwable { val idsList = ArrayList<Int>()
for (j in EnchantedJewellery.values()) {
for (id in j.ids) {
idsList.add(id)
}
}
IDs = idsList.toIntArray()
}
new JewelleryDialogue().init(); override fun defineListeners() {
for (EnchantedJewellery jewellery : EnchantedJewellery.values()) {
for (int id : jewellery.getIds()) {
ItemDefinition.forId(id).getHandlers().put("option:rub", this);
ItemDefinition.forId(id).getHandlers().put("option:operate", this);
}
}
return this;
}
@Override on(IDs,ITEM,"rub","operate"){player,node ->
public boolean handle(Player player, Node node, String option) { val item = node.asItem()
final EnchantedJewellery jewellery = EnchantedJewellery.forItem((Item) node); val jewellery = EnchantedJewellery.forItem(item)
if (jewellery.isLast(jewellery.getItemIndex((Item) node))) { if (jewellery.isLast(jewellery.getItemIndex(item))) {
player.getPacketDispatch().sendMessage("The " + jewellery.getNameType((Item) node) + " has lost its charge."); player.packetDispatch.sendMessage("The " + jewellery.getNameType(item) + " has lost its charge.")
player.getPacketDispatch().sendMessage("It will need to be recharged before you can use it again."); player.packetDispatch.sendMessage("It will need to be recharged before you can use it again.")
return true; return@on true
} }
player.getPacketDispatch().sendMessage("You rub the " + jewellery.getNameType((Item) node) + "..."); player.packetDispatch.sendMessage("You rub the " + jewellery.getNameType(item) + "...")
player.getDialogueInterpreter().open(JewelleryDialogue.ID, node, jewellery, option.equals("operate"));
return true;
}
@Override if (jewellery == EnchantedJewellery.DIGSITE_PENDANT) {
public boolean isWalk() { jewellery.use(player, item, 0, player.equipment.containsItem(item))
return false; return@on true
} } else {
player.dialogueInterpreter.open(EnchantedJewelleryDialogueFile(jewellery,item))
}
return@on true
}
/** }
* Represents the jewellery dialogue plugin. }
* @author 'Vexia
* @version 1.0
*/
public final class JewelleryDialogue extends DialoguePlugin {
/**
* Represents the id to use.
*/
public static final int ID = 329128389;
/**
* Represents the enchanted jewellery.
*/
private EnchantedJewellery jewellery;
/**
* If the operate option is used.
*/
private boolean operate;
/**
* Represents the item instance.
*/
private Item item;
/**
* Constructs a new {@code EnchantedJewelleryPlugin} {@code Object}.
*/
public JewelleryDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code EnchantedJewelleryPlugin} {@code Object}.
* @param player the player.
*/
public JewelleryDialogue(final Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new JewelleryDialogue(player);
}
@Override
public boolean open(Object... args) {
item = (Item) args[0];
jewellery = (EnchantedJewellery) args[1];
operate = args.length > 2 && (Boolean) args[2];
if (jewellery == EnchantedJewellery.DIGSITE_PENDANT) {
jewellery.use(player, item, 0, operate);
return true;
}
interpreter.sendOptions("Where would you like to go?", jewellery.getOptions());
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
if (player.getInterfaceManager().isOpened()) {
end();
return true;
}
end();
jewellery.use(player, item, (buttonId - 1), operate);
return true;
}
@Override
public int[] getIds() {
return new int[] { ID };
}
}
}