Implemented Scorpion Catcher quest

This commit is contained in:
GregF 2024-05-31 09:50:54 +00:00 committed by Ryan
parent da6f05f8ce
commit dc3daebb59
16 changed files with 908 additions and 49 deletions

View file

@ -4243,77 +4243,85 @@
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "456"
"id": "456",
"weight": "0.15"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There is 1 scorpion inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "457"
"id": "457",
"weight": "0.175"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There are 2 scorpions inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "458"
"id": "458",
"weight": "0.2"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There is 1 scorpion inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "459"
"id": "459",
"weight": "0.175"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There are 2 scorpions inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "460"
"id": "460",
"weight": "0.2"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There is 1 scorpion inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "461"
"id": "461",
"weight": "0.175"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There are 2 scorpions inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "462"
"id": "462",
"weight": "0.2"
},
{
"destroy_message": "You will need to speak to Thormac to get another cage.",
"examine": "It's empty!",
"examine": "There are 3 scorpions inside.",
"durability": null,
"name": "Scorpion cage",
"tradeable": "false",
"destroy": "true",
"archery_ticket_price": "0",
"id": "463"
"id": "463",
"weight": "0.225"
},
{
"ge_buy_limit": "10000",

View file

@ -5215,6 +5215,7 @@
"melee_animation": "0",
"range_animation": "0",
"combat_audio": "3611,3612,3610",
"respawn_delay": "60",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
@ -5237,6 +5238,7 @@
"strength_level": "1",
"id": "386",
"range_level": "1",
"respawn_delay": "60",
"attack_level": "1"
},
{
@ -5249,6 +5251,7 @@
"strength_level": "1",
"id": "387",
"range_level": "1",
"respawn_delay": "60",
"attack_level": "1"
},
{

View file

@ -1121,7 +1121,7 @@
},
{
"npc_id": "385",
"loc_data": "{2549,3568,0,1,6}-"
"loc_data": "{2552,3570,0,1,6}-"
},
{
"npc_id": "386",

View file

@ -20,7 +20,6 @@ import java.util.HashMap;
public final class MysticStaffEnchantingPlugin extends ComponentPlugin {
private final Component COMPONENT = new Component(332);
private final int cost = 40000;
protected enum EnchantedStaff {
AIR(Items.MYSTIC_AIR_STAFF_1405, Items.AIR_BATTLESTAFF_1397, 21),
@ -28,7 +27,8 @@ public final class MysticStaffEnchantingPlugin extends ComponentPlugin {
EARTH(Items.MYSTIC_EARTH_STAFF_1407, Items.EARTH_BATTLESTAFF_1399, 23),
FIRE(Items.MYSTIC_FIRE_STAFF_1401, Items.FIRE_BATTLESTAFF_1393, 24),
LAVA(Items.MYSTIC_LAVA_STAFF_3054, Items.LAVA_BATTLESTAFF_3053, 25),
MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26);
MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26),
STEAM(Items.MYSTIC_STEAM_STAFF_11738, Items.STEAM_BATTLESTAFF_11736, 27);
public final int enchanted;
public final int basic;
@ -68,7 +68,6 @@ public final class MysticStaffEnchantingPlugin extends ComponentPlugin {
@Override
public boolean handle(Player player, Component component, int opcode, int buttonId, int slot, int itemId) {
player.getPacketDispatch().sendMessage("op: " + opcode + " button: " + buttonId + " slot: "+ slot + " item: " + itemId);
if (EnchantedStaff.childToBasic.containsKey(buttonId)) {
Item basicStaff = new Item(EnchantedStaff.childToBasic.get(buttonId));
@ -78,9 +77,10 @@ public final class MysticStaffEnchantingPlugin extends ComponentPlugin {
player.getPacketDispatch().sendMessage("You don't have a" + (StringUtils.isPlusN(basicStaff.getName()) ? "n " : " ") + basicStaff.getName() + " to enchant.");
return true;
}
int cost = player.getEquipment().contains(Items.SEERS_HEADBAND_14631, 1)? 27000 : 40000;
if (!player.getInventory().contains(995, cost)) {
player.getInterfaceManager().close();
player.getDialogueInterpreter().sendDialogues(389, null, "I need 40,000 coins for materials. Come", "back when you have the money!");
player.getDialogueInterpreter().sendDialogues(389, null, "I need " + String.format("%,d", cost) + " coins for materials. Come", "back when you have the money!");
return true;
}
if (player.getInventory().remove(basicStaff, new Item(995, cost))) {

View file

@ -21,7 +21,6 @@ class VelrakDialogue(player: Player? = null) : DialoguePlugin(player) {
playerl(FacialExpression.HALF_THINKING, "Are you still here?").also { stage = 100 }
} else {
npcl(FacialExpression.FRIENDLY, "Thank you for rescuing me! It isn't very comfy in this cell.")
removeItem(player, Items.JAIL_KEY_1591, Container.INVENTORY)
}
return true
}

View file

@ -0,0 +1,58 @@
package content.region.kandarin.dialogue
import content.region.kandarin.quest.scorpioncatcher.SCThormacDialogue
import core.api.*
import core.game.dialogue.DialoguePlugin
import core.game.dialogue.FacialExpression
import core.game.dialogue.Topic
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.Items
import org.rs09.consts.NPCs
@Initializable
class ThormacDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun getIds(): IntArray {
return intArrayOf(NPCs.THORMAC_389)
}
companion object {
const val COMPLETED_QUEST = 1000
const val ENCHANT_DIALOGUE = 2000
}
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
if (isQuestComplete(player, "Scorpion Catcher")){
npc(FacialExpression.HAPPY, "Thank you for rescuing my scorpions.").also {stage = COMPLETED_QUEST}
}
else{
openDialogue(player, SCThormacDialogue(getQuestStage(player, "Scorpion Catcher")), npc)
}
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
COMPLETED_QUEST -> showTopics(
Topic(FacialExpression.HAPPY, "That's okay.", END_DIALOGUE),
Topic(FacialExpression.NEUTRAL, "You said you'd enchant my battlestaff for me", ENCHANT_DIALOGUE)
)
ENCHANT_DIALOGUE -> {
val cost = if (player.equipment.contains(Items.SEERS_HEADBAND_14631, 1)) 27 else 40
npcl(FacialExpression.HAPPY, "Yes, it'll cost you $cost,000 coins for the materials needed though. " +
"Which sort of staff did you want enchanting?").also { stage++ }
}
ENCHANT_DIALOGUE + 1 -> {
end()
player.interfaceManager.openComponent(332)
}
}
return true
}
}

View file

@ -0,0 +1,40 @@
package content.region.kandarin.quest.scorpioncatcher
import core.api.setQuestStage
import core.game.dialogue.DialogueFile
import core.game.dialogue.Topic
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
class SCPeksaDialogue(val questStage: Int) : DialogueFile() {
companion object {
const val ASK_ABOUT_SCORPION = START_DIALOGUE
const val ASK_FOR_HELP = 20
const val THANK_YOU = 30
}
override fun handle(componentID: Int, buttonID: Int) {
when (stage) {
// Word wrap issues
ASK_ABOUT_SCORPION -> npc("Now how could you know about that, I wonder?", "Mind you, I don't have it anymore.").also { stage++ }
ASK_ABOUT_SCORPION + 1 -> npcl(" I gave it as a present to my brother Ivor when I visited our outpost in the west.").also { stage++ }
ASK_ABOUT_SCORPION + 2 -> npcl("Well, actually I hid it in his bed so it would nip him. It was a bit of a surprise gift.").also { stage++ }
ASK_ABOUT_SCORPION + 3 -> showTopics(
Topic("So where is this outpost?", ASK_FOR_HELP),
Topic("Thanks for the information", THANK_YOU, true)
)
ASK_FOR_HELP -> npcl("Its a fair old trek to the west, across the White Wolf Mountains. Then head west, north-west until you see the axes and horned helmets.").also { stage=
THANK_YOU }
THANK_YOU -> {
playerl("Thanks for the information").also { stage++ }
setQuestStage(player!!, "Scorpion Catcher", ScorpionCatcher.QUEST_STATE_PEKSA_HELP)
}
THANK_YOU + 1 -> npcl ("No problems! Tell Ivor I said hi!").also { stage = END_DIALOGUE }
}
}
}

View file

@ -0,0 +1,78 @@
package content.region.kandarin.quest.scorpioncatcher
import content.region.kandarin.seers.dialogue.SeerDialogue
import core.api.sendDialogue
import core.api.setQuestStage
import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
class SCSeerDialogue(val questStage: Int, private val dialogueEntry: Int) : DialogueFile() {
companion object {
const val FIRST_SCORPION_HELP = 20
const val FIRST_SCORPION_THORMAC = 30
const val FIRST_SCORPION_GUIDE = 40
const val OTHER_SCORPIONS = 50
// There are many ways that this dialogue can be entered
const val ENTRY_HELP = SeerDialogue.SC_QUEST_HELP
const val ENTRY_FRIEND = SeerDialogue.SC_QUEST_FRIEND
const val ENTRY_OTHERS = SeerDialogue.SC_QUEST_OTHER_SCORPIONS
}
override fun handle(componentID: Int, buttonID: Int) {
when (stage) {
START_DIALOGUE -> when (dialogueEntry){
ENTRY_HELP -> npcl("Well you have come to the right place. I am a master of animal detection.").also { stage = FIRST_SCORPION_HELP }
ENTRY_FRIEND -> npcl(FacialExpression.NEUTRAL, "What does the old fellow want?").also { stage = FIRST_SCORPION_THORMAC }
// word wrap doesn't work again
ENTRY_OTHERS -> npc(FacialExpression.NEUTRAL, "Well, I've checked my looking glass. There seems to be",
"a kharid scorpion in a little village to the east,",
"surrounded by lots of uncivilized-looking warriors.",
"Some kind of merchant there seems to have picked it up.").also { stage = OTHER_SCORPIONS }
else -> {
println("Invalid entry to SCSeerDialogue $dialogueEntry")
end()
}
}
FIRST_SCORPION_THORMAC -> playerl(
FacialExpression.NEUTRAL,
"He's lost his valuable lesser Kharid scorpions."
).also { stage++ }
FIRST_SCORPION_THORMAC + 1 -> npcl(
FacialExpression.HAPPY,
"Well you have come to the right place. I am a master of animal detection."
).also { stage = FIRST_SCORPION_GUIDE }
FIRST_SCORPION_HELP -> npcl("Do you need to locate any particular scorpion? Scorpions are a creature somewhat in abundance.").also { stage++ }
FIRST_SCORPION_HELP + 1 -> playerl("I'm looking for some lesser Kharid scorpions. They belong to Thormac the Sorcerer.").also {
stage = FIRST_SCORPION_GUIDE
}
FIRST_SCORPION_GUIDE -> npcl(FacialExpression.HAPPY, "Let me look into my looking glass.").also { stage++ }
FIRST_SCORPION_GUIDE + 1 -> sendDialogue(player!!, "The Seer produces a small mirror.").also { stage++ }
FIRST_SCORPION_GUIDE + 2 -> sendDialogue(player!!, "The Seer gazes into the mirror.").also { stage++ }
FIRST_SCORPION_GUIDE + 3 -> sendDialogue(player!!, "The Seer smooths his hair with his hand.").also { stage++ }
FIRST_SCORPION_GUIDE + 4 -> npcl("I can see a scorpion that you seek. It would appear to be near some nasty spiders. I can see two coffins there as well.").also { stage++ }
FIRST_SCORPION_GUIDE + 5 -> npcl("The scorpion seems to be going through some crack in the wall. Its gone into some sort of secret room.").also { stage++ }
FIRST_SCORPION_GUIDE + 6 -> npcl("Well see if you can find the scorpion then, and I'll try and get you some information on the others.").also {
setQuestStage(player!!, "Scorpion Catcher", ScorpionCatcher.QUEST_STATE_DARK_PLACE)
stage = END_DIALOGUE
}
OTHER_SCORPIONS -> npcl ("That's all I can tell about that scorpion.").also { stage++ }
OTHER_SCORPIONS + 1 -> playerl("Any more scorpions?").also { stage++ }
OTHER_SCORPIONS + 2 -> npcl ("It's good that you should ask. I have information on the last scorpion for you.").also { stage++ }
OTHER_SCORPIONS + 3 -> npcl ("It seems to be in some sort of upstairs room. There seems to be some sort of brown clothing lying on a table.").also {
setQuestStage(player!!, "Scorpion Catcher", ScorpionCatcher.QUEST_STATE_OTHER_SCORPIONS)
stage = END_DIALOGUE
}
}
}
}

View file

@ -0,0 +1,132 @@
package content.region.kandarin.quest.scorpioncatcher
import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
import core.ServerConstants
import core.api.*
import core.game.dialogue.Topic
import core.game.node.item.Item
import org.rs09.consts.Items
class SCThormacDialogue(val questStage: Int) : DialogueFile() {
companion object {
const val ASK_FOR_HELP = 10
const val HOW_TO_CATCH = 30
const val WHY_SHOULD_I_START = 50
const val WAITING_FOR_SCORPIONS = 100
const val GIVE_ANOTHER_CAGE = 110
const val GOT_THEM_ALL = 200
const val FULL_INVENTORY = 300
}
override fun handle(componentID: Int, buttonID: Int) {
when (stage){
START_DIALOGUE -> if (questStage == 0) {
npcl(FacialExpression.FRIENDLY, "Hello I am Thormac the Sorcerer, " +
"I don't suppose you could be of assistance to me?").also { stage = ASK_FOR_HELP }
}
else {
npcl(FacialExpression.NEUTRAL, "How goes your quest?").also {
stage = if (hasAnItem(player!!, Items.SCORPION_CAGE_463).exists()){
// Player has all the scorpions caught
GOT_THEM_ALL
} else {
WAITING_FOR_SCORPIONS
}
}
}
ASK_FOR_HELP -> showTopics(
Topic(FacialExpression.HAPPY,"What do you need assistance with?", ASK_FOR_HELP+1),
Topic(FacialExpression.NEUTRAL, "I'm a little busy.", END_DIALOGUE)
)
ASK_FOR_HELP+1 -> npcl(FacialExpression.WORRIED, " I've lost my pet scorpions. " +
"They're lesser Kharid scorpions, a very rare breed.").also { stage++ }
ASK_FOR_HELP+2 -> npcl(FacialExpression.WORRIED, "I left their cage door open, now I don't know where they've gone.").also { stage++ }
ASK_FOR_HELP+3 -> npcl(FacialExpression.WORRIED, "There's three of them, and they're quick little beasties. " +
"They're all over " + ServerConstants.SERVER_NAME + ".").also { stage++ }
ASK_FOR_HELP+4 -> showTopics(
Topic(FacialExpression.ASKING, "So how would I go about catching them then?", HOW_TO_CATCH),
Topic(FacialExpression.ASKING, "What's in it for me?", WHY_SHOULD_I_START),
Topic(FacialExpression.NEUTRAL, "I'm not interested then.", END_DIALOGUE)
)
WHY_SHOULD_I_START -> npcl(FacialExpression.WORRIED, "Well I suppose I can aid you with my skills as a staff sorcerer. " +
"Most battlestaffs around here are a bit puny. I can beef them up for you a bit.").also {
// Need to recheck the quest stage since it may have been changed in this dialogue
if(getQuestStage(player!!, "Scorpion Catcher") == 0) stage++
else stage = END_DIALOGUE
}
WHY_SHOULD_I_START+1 -> showTopics(
Topic(FacialExpression.ASKING, "So how would I go about catching them then?", HOW_TO_CATCH),
Topic(FacialExpression.NEUTRAL, "I'm not interested then.", END_DIALOGUE)
)
HOW_TO_CATCH -> npcl(FacialExpression.WORRIED, "Well I have a scorpion cage here which you can " +
"use to catch them in.").also {
if (hasSpaceFor(player!!,Item(Items.SCORPION_CAGE_456))) stage++
else stage = FULL_INVENTORY
}
HOW_TO_CATCH+1 -> {
sendItemDialogue(player!!, Items.SCORPION_CAGE_456, "Thormac gives you a cage.").also { stage++ }
startQuest(player!!, "Scorpion Catcher")
addItem(player!!, Items.SCORPION_CAGE_456)
}
HOW_TO_CATCH+2 -> npcl(FacialExpression.WORRIED, "If you go up to the village of Seers, to the North of " +
"here, one of them will be able to tell you where the scorpions are now.").also { stage++ }
HOW_TO_CATCH+3 -> showTopics(
Topic(FacialExpression.ASKING, "What's in it for me?", WHY_SHOULD_I_START),
Topic(FacialExpression.NEUTRAL, "Ok, I will do it then.", END_DIALOGUE )
)
WAITING_FOR_SCORPIONS -> {
if (!hasAnItem(player!!, Items.SCORPION_CAGE_456, Items.SCORPION_CAGE_457, Items.SCORPION_CAGE_458,
Items.SCORPION_CAGE_459, Items.SCORPION_CAGE_460, Items.SCORPION_CAGE_461,
Items.SCORPION_CAGE_462).exists()){
playerl(FacialExpression.SAD, "I've lost my cage.").also { stage = GIVE_ANOTHER_CAGE }
}
else{
playerl(FacialExpression.NEUTRAL, "I've not caught all the scorpions yet.").also { stage++ }
}
}
WAITING_FOR_SCORPIONS+1 -> npcl(FacialExpression.WORRIED, "Well remember to go speak to the Seers" +
" North of here, if you need any help.").also { stage = END_DIALOGUE }
GIVE_ANOTHER_CAGE -> {
player!!.inventory.add(Item(Items.SCORPION_CAGE_456))
// Clear all attributes keeping track of the scorpions
player!!.removeAttribute("scorpion_catcher:caught_taverly")
player!!.removeAttribute("scorpion_catcher:caught_barb")
player!!.removeAttribute("scorpion_catcher:caught_monk")
npcl(FacialExpression.NEUTRAL, "Ok, here's another cage. You're almost as bad" +
" at losing things as me.").also { stage = END_DIALOGUE }
}
GOT_THEM_ALL -> {
playerl ("I have retrieved all your scorpions.").also { stage++ }
}
GOT_THEM_ALL+1 ->{
npcl(FacialExpression.HAPPY, "Aha, my little scorpions home at last!").also { stage++ }
player!!.inventory.remove(Item(Items.SCORPION_CAGE_463))
// Don't need to keep track of which scorpions have been caught anymore
player!!.removeAttribute("scorpion_catcher:caught_taverly")
player!!.removeAttribute("scorpion_catcher:caught_barb")
player!!.removeAttribute("scorpion_catcher:caught_monk")
}
GOT_THEM_ALL+2 ->{
end().also { finishQuest(player!!, "Scorpion Catcher") }
}
FULL_INVENTORY -> npcl("You don't have space to hold a cage").also { stage = END_DIALOGUE }
}
}
}

View file

@ -0,0 +1,36 @@
package content.region.kandarin.quest.scorpioncatcher
import core.api.getQuestStage
import core.api.sendMessage
import core.game.global.action.DoorActionHandler
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.world.map.Location
import org.rs09.consts.Scenery
class SCWallListener : InteractionListener {
override fun defineListeners() {
on(Scenery.OLD_WALL_2117, IntType.SCENERY, "search"){ player, node ->
// You can only go through if you are doing the quest
//https://youtu.be/crc-47rwjvE?feature=shared&t=841
// Otherwise the crack reverts back to normal
// Doesn't make any sense but that's authentic...
if ((ScorpionCatcher.QUEST_STATE_DARK_PLACE .. 99).contains(getQuestStage(player, "Scorpion Catcher"))) {
// Check what side the player is on and teleport them to the other
if (player.location == Location(2875, 9799, 0)){
sendMessage(player, "You've found a secret door")
DoorActionHandler.handleAutowalkDoor(player, node.asScenery())
}
else{
// We're leaving the room
DoorActionHandler.handleAutowalkDoor(player, node.asScenery())
}
}
else{
sendMessage(player, "You search the wall but find nothing.")
}
return@on true
}
}
}

View file

@ -0,0 +1,119 @@
package content.region.kandarin.quest.scorpioncatcher
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.quest.Quest
import core.game.node.entity.skill.Skills
import core.plugin.Initializable
import org.rs09.consts.Items
@Initializable
class ScorpionCatcher : Quest("Scorpion Catcher", 108, 107, 1, 76, 0, 1, 6) {
companion object {
const val QUEST_STATE_NOT_STARTED = 0
const val QUEST_STATE_TALK_SEERS = 10
const val QUEST_STATE_DARK_PLACE = 20
const val QUEST_STATE_OTHER_SCORPIONS = 30
const val QUEST_STATE_PEKSA_HELP = 40
const val QUEST_STATE_DONE = 100
const val ATTRIBUTE_TAVERLY = "scorpion_catcher:caught_taverly"
const val ATTRIBUTE_BARB = "scorpion_catcher:caught_barb"
const val ATTRIBUTE_MONK = "scorpion_catcher:caught_monk"
}
override fun newInstance(`object`: Any?): Quest {
return this
}
override fun drawJournal(player: Player?, stage: Int) {
super.drawJournal(player, stage)
var ln = 11
/**
* Just draw this if the quest is done
*/
if (stage == QUEST_STATE_DONE) {
ln++
line(player, "I helped !!Thormac?? get his scorpions back.", ln++)
line(player, "Now he can upgrade my battlestaffs into mystic staffs.", ln)
ln++
ln++
line(player, "<col=FF0000>QUEST COMPLETE!</col>", ln)
return
}
val caughtTaverly = player!!.getAttribute(ATTRIBUTE_TAVERLY, false)
val caughtBarb = player.getAttribute(ATTRIBUTE_BARB, false)
val caughtMonk = player.getAttribute(ATTRIBUTE_MONK, false)
if (stage == QUEST_STATE_NOT_STARTED){
line(player, "I can start this quest by speaking to !!Thormac?? who is in the", ln++)
line(player, "!!Sorcerer's Tower?? south-west of !!Catherby??", ln++)
ln++ //blank line
line(player, "Requirements:", ln++)
line(player, "Level 31 Prayer", ln, player.skills.staticLevels[Skills.PRAYER] >= 31)
}
else {
line(player, "Speak to Thormac.", ln++, true)
ln++
if (stage == QUEST_STATE_TALK_SEERS) {
line(player, "I've spoken to !!Thormac?? in the !!Sorcerer's Tower?? south-west of !!Catherby.??", ln++)
line(player, "He's lost his pet !!Kharid Scorpions?? and needs my help to find them.", ln++)
// Todo check this line
line(player, "He's told me to ask a !!Seer?? for help.", ln)
}
else {
// todo check this line
line(player, "I talked to a Seer. He told me where I should look.", ln++, caughtTaverly)
ln++
line(player, "The first !!Kharid Scorpion?? is in a secret room near some", ln++, caughtTaverly)
line(player, "nasty spiders with two coffins nearby.", ln++, caughtTaverly)
ln++
if (stage == QUEST_STATE_DARK_PLACE && caughtTaverly){
// Todo check this line
line(player, "I should go back to the Seer and ask about the other scorpions.", ln++)
}
if (stage >= QUEST_STATE_OTHER_SCORPIONS){
val barb_strike = caughtBarb || (stage == QUEST_STATE_PEKSA_HELP)
line(player, "The second !!Kharid Scorpion?? has been in a !!village of??", ln++, barb_strike)
line(player, "!!uncivilised-looking warriors in the east.?? It's been picked up", ln++, barb_strike)
line(player, "by some sort of !!merchant??", ln++, barb_strike)
ln++
if (stage == QUEST_STATE_PEKSA_HELP){
// todo check this block
line(player, "I spoke with !!Peksa?? who said he sent it to his brother", ln++, caughtBarb)
line(player, "at the !!Barbarian outpost.??", ln++, caughtBarb)
ln++
}
line(player, "The third !!Kharid Scorpion?? is in some sort of !!upstairs room??", ln++, caughtMonk)
line(player, "with !!brown clothing on a table??", ln++, caughtMonk)
}
if (caughtBarb && caughtTaverly && caughtMonk && stage >= QUEST_STATE_OTHER_SCORPIONS){
ln++
line(player, "I should tell !!Thormac?? I have all of his scorpions.", ln)
}
}
}
}
override fun finish(player: Player?) {
var ln = 10
super.finish(player)
player!!.packetDispatch.sendString("You have completed the Scorpion Catcher Quest!", 277, 4)
player.packetDispatch.sendItemZoomOnInterface(Items.SCORPION_CAGE_463, 240, 277, 5)
drawReward(player, "1 Quest Point", ln++)
drawReward(player, "6625 Strength XP", ln)
player.skills.addExperience(Skills.STRENGTH, 6625.0)
}
}

View file

@ -0,0 +1,342 @@
package content.region.kandarin.quest.scorpioncatcher
import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_TAVERLY
import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_BARB
import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_MONK
import core.api.addItem
import core.game.node.item.Item
import core.api.removeItem
import core.api.runTask
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.system.config.NPCConfigParser
import core.game.world.GameWorld
import org.rs09.consts.Items
import org.rs09.consts.NPCs
class ScorpionCatcherUseListener : InteractionListener {
override fun defineListeners() {
/**
* List of cages
* Talvery Barbarian Monk
* TBM
* 456 ---
* 457 O--
* 458 00-
* 459 -0-
* 460 -00
* 461 --0
* 462 0-0
* 463 000
*
* Scorpions
* 385 - Barbarian
* 386 - Taverly
* 387 - Monastery
*/
/**
* Good captures
*/
/**
* Empty cage on Taverly scorpion
*/
// todo check this message
val haveAlready = "You already have this scorpion in this cage."
val catchMessage = "You catch a scorpion!"
onUseWith(IntType.NPC, Items.SCORPION_CAGE_456, NPCs.KHARID_SCORPION_386){ player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_457)
player.sendMessage(catchMessage)
// This is the first time taverly has been caught
if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){
player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Barbarian cage on Taverly scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_459, NPCs.KHARID_SCORPION_386){ player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_458)
player.sendMessage(catchMessage)
// This is the first time taverly has been caught
if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){
player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Monk cage on Taverly scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_461, NPCs.KHARID_SCORPION_386){ player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_462)
player.sendMessage(catchMessage)
// This is the first time taverly has been caught
if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){
player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Others on Taverly scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_460, NPCs.KHARID_SCORPION_386){ player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_463)
player.sendMessage(catchMessage)
// This is the first time taverly has been caught
if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){
player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Empty cage on barbarian agility course scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_456, NPCs.KHARID_SCORPION_385){ player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_459)
player.sendMessage(catchMessage)
// This is the first time barbarian has been caught
if (!player.getAttribute(ATTRIBUTE_BARB, false)){
player.setAttribute("/save:$ATTRIBUTE_BARB", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Cage with Taverly scorpion on barbarian scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_457, NPCs.KHARID_SCORPION_385) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_458)
player.sendMessage(catchMessage)
// This is the first time barbarian has been caught
if (!player.getAttribute(ATTRIBUTE_BARB, false)){
player.setAttribute("/save:$ATTRIBUTE_BARB", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Cage with Monk scorpion on barbarian scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_461, NPCs.KHARID_SCORPION_385) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_460)
player.sendMessage(catchMessage)
// This is the first time barbarian has been caught
if (!player.getAttribute(ATTRIBUTE_BARB, false)){
player.setAttribute("/save:$ATTRIBUTE_BARB", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Others on barbarian scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_462, NPCs.KHARID_SCORPION_385) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_463)
player.sendMessage(catchMessage)
// This is the first time barbarian has been caught
if (!player.getAttribute(ATTRIBUTE_BARB, false)){
player.setAttribute("/save:$ATTRIBUTE_BARB", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Empty on Monk scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_456, NPCs.KHARID_SCORPION_387) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_461)
player.sendMessage(catchMessage)
// This is the first time the monastery has been caught
if (!player.getAttribute(ATTRIBUTE_MONK, false)){
player.setAttribute("/save:$ATTRIBUTE_MONK", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Taverly cage on Monk scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_457, NPCs.KHARID_SCORPION_387) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_462)
player.sendMessage(catchMessage)
// This is the first time the monastery has been caught
if (!player.getAttribute(ATTRIBUTE_MONK, false)){
player.setAttribute("/save:$ATTRIBUTE_MONK", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Barbarian cage on Monk scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_459, NPCs.KHARID_SCORPION_387) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_460)
player.sendMessage(catchMessage)
// This is the first time the monastery has been caught
if (!player.getAttribute(ATTRIBUTE_MONK, false)){
player.setAttribute("/save:$ATTRIBUTE_MONK", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Others on Monk scorpion
*/
onUseWith(IntType.NPC, Items.SCORPION_CAGE_458, NPCs.KHARID_SCORPION_387) { player, used, with ->
removeItem(player, Item(used.id, 1))
addItem(player, Items.SCORPION_CAGE_463)
player.sendMessage(catchMessage)
// This is the first time the monastery has been caught
if (!player.getAttribute(ATTRIBUTE_MONK, false)){
player.setAttribute("/save:$ATTRIBUTE_MONK", true)
}
runTask(player, 2) {
with.asNpc().respawnTick =
GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34)
}
return@onUseWith true
}
/**
* Player being stupid and trying to recatch one they have already
*/
/**
* Taverly
*/
// Just Taverly
onUseWith(IntType.NPC, Items.SCORPION_CAGE_457, NPCs.KHARID_SCORPION_386){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// Taverly and Barb
onUseWith(IntType.NPC, Items.SCORPION_CAGE_458, NPCs.KHARID_SCORPION_386){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// Taverly and Monk
onUseWith(IntType.NPC, Items.SCORPION_CAGE_462, NPCs.KHARID_SCORPION_386){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// All
onUseWith(IntType.NPC, Items.SCORPION_CAGE_463, NPCs.KHARID_SCORPION_386){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
/**
* Barbarian
*/
// Just Barb
onUseWith(IntType.NPC, Items.SCORPION_CAGE_459, NPCs.KHARID_SCORPION_385){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// Barb and Taverly
onUseWith(IntType.NPC, Items.SCORPION_CAGE_458, NPCs.KHARID_SCORPION_385){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// Barb and Monk
onUseWith(IntType.NPC, Items.SCORPION_CAGE_460, NPCs.KHARID_SCORPION_385){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// All
onUseWith(IntType.NPC, Items.SCORPION_CAGE_463, NPCs.KHARID_SCORPION_385){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
/**
* Monastery
*/
// Just Monk
onUseWith(IntType.NPC, Items.SCORPION_CAGE_461, NPCs.KHARID_SCORPION_387){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// Monk and Taverly
onUseWith(IntType.NPC, Items.SCORPION_CAGE_462, NPCs.KHARID_SCORPION_387){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// Monk and Barb
onUseWith(IntType.NPC, Items.SCORPION_CAGE_460, NPCs.KHARID_SCORPION_387){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
// All
onUseWith(IntType.NPC, Items.SCORPION_CAGE_463, NPCs.KHARID_SCORPION_387){ player, _, _ ->
player.sendMessage(haveAlready)
return@onUseWith true
}
}
}

View file

@ -1,10 +1,15 @@
package content.region.kandarin.seers.dialogue
import content.region.kandarin.seers.diary.SeerDiaryDialogue
import content.region.kandarin.quest.scorpioncatcher.SCSeerDialogue
import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher
import core.api.getAttribute
import core.api.getQuestStage
import core.api.isQuestInProgress
import core.api.openDialogue
import core.game.dialogue.DialoguePlugin
import core.game.dialogue.FacialExpression
import core.game.dialogue.IfTopic
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
@ -27,8 +32,12 @@ class SeerDialogue(player: Player? = null) : DialoguePlugin(player) {
const val DIARY = 20
const val SC_QUEST = 30
const val MANY_GREETINGS = 60
const val POWER = 70
const val SC_QUEST_HELP = 40
const val SC_QUEST_FRIEND = 50
const val SC_QUEST_OTHER_SCORPIONS = 60
const val MANY_GREETINGS = 70
const val POWER = 80
}
override fun open(vararg args: Any?): Boolean {
@ -38,27 +47,56 @@ class SeerDialogue(player: Player? = null) : DialoguePlugin(player) {
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
val scorpionCatcherQuestStage = getQuestStage(player, "Scorpion Catcher")
when (stage) {
START_DIALOGUE ->
npcl(FacialExpression.NEUTRAL, "Anyway, sorry about that.").also { stage++ }
START_DIALOGUE+1 ->
showTopics(
Topic("Talk about something else.", OTHER_TOPIC, true),
Topic("Talk about achievement diary.", DIARY, true)
)
START_DIALOGUE+1 -> {
if (isQuestInProgress(player, "Scorpion Catcher", 1, 99)) {
showTopics(
Topic("Talk about Scorpion Catcher.", SC_QUEST, true),
Topic("Talk about Achievement Diary.", DIARY, true)
)
}
else {
showTopics(
Topic("Talk about something else.", OTHER_TOPIC, true),
Topic("Talk about achievement diary.", DIARY, true)
)
}
}
SC_QUEST -> {
if (scorpionCatcherQuestStage == ScorpionCatcher.QUEST_STATE_TALK_SEERS) {
showTopics(
Topic("I need to locate some scorpions.", SC_QUEST_HELP,),
Topic("Your friend Thormac sent me to speak to you.", SC_QUEST_FRIEND,),
Topic("I seek knowledge and power!", POWER)
)
}
else if ((scorpionCatcherQuestStage == ScorpionCatcher.QUEST_STATE_DARK_PLACE) and
getAttribute(player!!, ScorpionCatcher.ATTRIBUTE_TAVERLY, false)
) {
playerl(
FacialExpression.NEUTRAL,
"Hi, I have retrieved the scorpion from near the spiders."
).also { stage = SC_QUEST_OTHER_SCORPIONS }
}
else {
npcl(FacialExpression.NEUTRAL, "Good luck finding those scorpions.").also { stage = END_DIALOGUE }
}
}
SC_QUEST_HELP, SC_QUEST_FRIEND, SC_QUEST_OTHER_SCORPIONS -> {
// Use the current stage value as the entry point to Seers
openDialogue(player, SCSeerDialogue(scorpionCatcherQuestStage, stage), npc)
}
OTHER_TOPIC -> showTopics(
Topic("Many greetings.", MANY_GREETINGS),
Topic("I seek knowledge and power!", POWER)
)
DIARY -> openDialogue(player, SeerDiaryDialogue(), npc)
OTHER_TOPIC -> if (isQuestInProgress(player, "Scorpion Catcher", 1, 99)) {
npcl(FacialExpression.FURIOUS, "Not implemented").also { stage = END_DIALOGUE }
}
else{
showTopics(
Topic("Many greetings.", MANY_GREETINGS),
Topic("I seek knowledge and power!", POWER)
)
}
MANY_GREETINGS -> npcl(FacialExpression.NEUTRAL,
"Remember, whenever you set out to do something, something else must be done first.").also { stage = END_DIALOGUE }

View file

@ -60,7 +60,7 @@ class SeerDiaryDialogue : DialogueFile() {
// This has to be npc otherwise wordwrap goes wrong and extends to 5 lines
ASK_FOR_HELP -> npc(FacialExpression.HAPPY, "I certainly do - we have a set of tasks spanning Seers'", "Village, Catherby, Hemenster and the Sinclair Mansion.",
"Just complete the tasks listed in the Achievement Diary", "and they will be ticked off automatically.").also { stage++ }
ASK_FOR_HELP + 1 -> playerl(FacialExpression.ASKING, "Hi! Can you help me out with the Achievement Diary tasks?").also { stage++ }
ASK_FOR_HELP + 1 -> playerl(FacialExpression.ASKING, "Can you help me out with the Achievement Diary tasks?").also { stage++ }
ASK_FOR_HELP + 2 -> npcl(FacialExpression.SAD,
"I'm afraid not. It is important that adventurers complete the tasks unaided. That way, only the truly worthy collect the spoils.").also {
stage = END_DIALOGUE

View file

@ -1,5 +1,7 @@
package content.region.misthalin.barbvillage.dialogue
import content.region.kandarin.quest.scorpioncatcher.SCPeksaDialogue
import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher
import core.api.getQuestStage
import core.api.openDialogue
import core.game.dialogue.DialoguePlugin
@ -34,8 +36,7 @@ class PeksaDialogue(player: Player? = null) : DialoguePlugin(player){
showTopics(
Topic("I could be, yes.", GO_SHOPPING),
Topic("No, I'll pass on that.", LEAVE),
// todo get the quest state from Scorpion catcher to make this work
// IfTopic("Scorpion Stuff", SCORPION_CATCHER, getQuestStage(player, "Scorpion Catcher") == 50)
IfTopic("I've heard you have a small scorpion in your possession.", DIALOGUE_SCORPION_CATCHER, getQuestStage(player, "Scorpion Catcher") == ScorpionCatcher.QUEST_STATE_OTHER_SCORPIONS)
)
}
@ -48,9 +49,9 @@ class PeksaDialogue(player: Player? = null) : DialoguePlugin(player){
npcl(FacialExpression.HALF_GUILTY, "Well, come back if you change your mind.").also { stage = END_DIALOGUE }
}
// DIALOGUE_SCORPION_CATCHER -> {
// openDialogue(player, PeksaDialogueSC(), npc)
// }
DIALOGUE_SCORPION_CATCHER -> {
openDialogue(player, SCPeksaDialogue(getQuestStage(player, "Scorpion Catcher")), npc)
}
}
return true

View file

@ -48,12 +48,17 @@ class QuestCommandSet : CommandSet(Privilege.ADMIN){
val quest = args[1].toIntOrNull() ?: reject(player,"INVALID QUEST")
val stage = args[2].toIntOrNull() ?: reject(player,"INVALID STAGE")
val questObject = player.questRepository.forIndex(quest as Int)
player.questRepository.setStageNonmonotonic(questObject, stage as Int)
if (stage == 0){
questObject.reset(player)
if (questObject == null){
reject(player, "$quest did not match anything in the quest repository")
}
else{
player.questRepository.setStageNonmonotonic(questObject, stage as Int)
if (stage == 0) {
questObject.reset(player)
}
questObject.updateVarps(player)
notify(player, "<col=209dff>Setting " + questObject.name + " to stage $stage</col>")
}
questObject.updateVarps(player)
notify(player, "<col=209dff>Setting " + questObject.name + " to stage $stage</col>")
}
/**