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
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.npc = npc
this.interpreter = interpreter
@@ -137,6 +137,11 @@ public final class DialogueInterpreter {
return true;
}
public void open(DialogueFile file,Object... args){
this.dialogue = new EmptyPlugin(player,file);
this.dialogue.open(args);
}
/**
* Starts a dialogue script.
* @param script The script.
@@ -276,6 +276,7 @@ public abstract class DialoguePlugin implements Plugin<Player> {
* @param file the DialogueFile to load.
*/
public void loadFile(DialogueFile file){
if(file == null) return;
this.file = file.load(player,npc,interpreter);
this.file.setDialoguePlugin(this);
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.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.SystemLogger
object JobManager {
@JvmStatic
@@ -55,7 +56,8 @@ object JobManager {
var amount = player.inventory.getAmount(it)
val needed = player.getAttribute("jobs:amount",0)
if(amount == 0){
player.dialogueInterpreter.open(9987215,npc)
player.dialogueInterpreter.open(CancelJobDialogueFile(),npc)
SystemLogger.logAlert("Opening CancelJob")
return
}
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>()
@JvmStatic
fun add(id: Int, type: Int, option: String, method: (Player,Node) -> Boolean){
val key = "$id:$type:${option.toLowerCase()}"
listeners[key] = method
fun add(id: Int, type: Int, option: Array<out String>, method: (Player,Node) -> Boolean){
for(opt in option) {
val key = "$id:$type:${opt.toLowerCase()}"
listeners[key] = method
}
}
@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){
add(id,type,option,method)
}
@@ -8,7 +8,10 @@ abstract class OptionListener {
val OBJECT = 1
val NPC = 2
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)
}
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.impl.EquipmentContainer;
import core.game.content.global.action.EquipHandler;
import core.game.interaction.Listeners;
import core.game.interaction.OptionHandler;
import core.game.node.entity.combat.DeathTask;
import core.game.node.entity.player.Player;
@@ -190,6 +191,9 @@ public final class EquipmentInterface extends ComponentPlugin {
if (item == null) {
return;
}
if(Listeners.run(item.getId(),0,"operate",player,item)){
return;
}
OptionHandler handler = item.getOperateHandler();
if (handler != null && handler.handle(player, item, "operate")) {
return;
@@ -1,131 +1,47 @@
package core.game.interaction.item;
package core.game.interaction.item
import core.cache.def.impl.ItemDefinition;
import core.game.content.dialogue.DialoguePlugin;
import core.game.content.global.EnchantedJewellery;
import core.game.interaction.OptionHandler;
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;
import core.game.interaction.OptionListener
import core.game.content.global.EnchantedJewellery
import core.game.content.global.EnchantedJewelleryDialogueFile
import java.util.ArrayList
/**
* Represents the plugin used to handle enchanted jewellery transportation.
* @author 'Vexia
* @version 1.0
* Listener for enchanted jewellery options
* @author Ceikry
*/
@Initializable
public final class EnchantedJewelleryPlugin extends OptionHandler {
class EnchantedJewelleryListener : OptionListener() {
val IDs: IntArray
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
init {
val idsList = ArrayList<Int>()
for (j in EnchantedJewellery.values()) {
for (id in j.ids) {
idsList.add(id)
}
}
IDs = idsList.toIntArray()
}
new JewelleryDialogue().init();
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 fun defineListeners() {
@Override
public boolean handle(Player player, Node node, String option) {
final EnchantedJewellery jewellery = EnchantedJewellery.forItem((Item) node);
if (jewellery.isLast(jewellery.getItemIndex((Item) node))) {
player.getPacketDispatch().sendMessage("The " + jewellery.getNameType((Item) node) + " has lost its charge.");
player.getPacketDispatch().sendMessage("It will need to be recharged before you can use it again.");
return true;
}
player.getPacketDispatch().sendMessage("You rub the " + jewellery.getNameType((Item) node) + "...");
player.getDialogueInterpreter().open(JewelleryDialogue.ID, node, jewellery, option.equals("operate"));
return true;
}
on(IDs,ITEM,"rub","operate"){player,node ->
val item = node.asItem()
val jewellery = EnchantedJewellery.forItem(item)
if (jewellery.isLast(jewellery.getItemIndex(item))) {
player.packetDispatch.sendMessage("The " + jewellery.getNameType(item) + " has lost its charge.")
player.packetDispatch.sendMessage("It will need to be recharged before you can use it again.")
return@on true
}
player.packetDispatch.sendMessage("You rub the " + jewellery.getNameType(item) + "...")
@Override
public boolean isWalk() {
return false;
}
if (jewellery == EnchantedJewellery.DIGSITE_PENDANT) {
jewellery.use(player, item, 0, player.equipment.containsItem(item))
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 };
}
}
}
}
}