Implemented Murder Mystery

This commit is contained in:
Syndromeramo
2025-08-18 11:26:45 +00:00
committed by Ryan
parent 1ff19880ef
commit 2471584c42
25 changed files with 1858 additions and 17 deletions
+8
View File
@@ -415,6 +415,14 @@
"item_id": "1785",
"loc_data": "{1,2822,3355,0,150}-"
},
{
"item_id": "1812",
"loc_data": "{1,2747,3579,0,100}"
},
{
"item_id": "1813",
"loc_data": "{1,2746,3578,0,100}"
},
{
"item_id": "1856",
"loc_data": "{1,2638,3292,0,150}-"
+11 -11
View File
@@ -18946,7 +18946,7 @@
"equipment_slot": "2"
},
{
"examine": "Anna's shiny silver coated necklace.",
"examine": "Anna's shiny silver coated necklace coated with a thin layer of flour.",
"durability": null,
"name": "Silver necklace",
"weight": "1",
@@ -18964,7 +18964,7 @@
"id": "1798"
},
{
"examine": "Bob's shiny silver coated tea cup.",
"examine": "Bob's shiny silver coated tea cup coated with a thin layer of flour.",
"durability": null,
"name": "Silver cup",
"tradeable": "false",
@@ -18982,7 +18982,7 @@
"id": "1800"
},
{
"examine": "Carol's shiny silver coated bottle.",
"examine": "Carol's shiny silver coated bottle coated with a thin layer of flour.",
"durability": null,
"name": "Silver bottle",
"tradeable": "false",
@@ -19000,7 +19000,7 @@
"id": "1802"
},
{
"examine": "David's shiny silver coated book.",
"examine": "David's shiny silver coated book coated with a thin layer of flour.",
"durability": null,
"name": "Silver book",
"tradeable": "false",
@@ -19018,7 +19018,7 @@
"id": "1804"
},
{
"examine": "Elizabeth's shiny silver coated needle.",
"examine": "Elizabeth's shiny silver coated needle coated with a thin layer of flour.",
"durability": null,
"name": "Silver needle",
"tradeable": "false",
@@ -19036,7 +19036,7 @@
"id": "1806"
},
{
"examine": "Frank's shiny silver coated pot.",
"examine": "Frank's shiny silver coated pot coated with a thin layer of flour.",
"durability": null,
"name": "Silver pot",
"tradeable": "false",
@@ -19045,7 +19045,7 @@
"id": "1807"
},
{
"examine": "Some (colour) thread found at the murder scene.",
"examine": "Some red thread found at the murder scene.",
"durability": null,
"name": "Criminal's thread",
"tradeable": "false",
@@ -19054,7 +19054,7 @@
"id": "1808"
},
{
"examine": "Some (colour) thread found at the murder scene.",
"examine": "Some green thread found at the murder scene.",
"durability": null,
"name": "Criminal's thread",
"tradeable": "false",
@@ -19063,7 +19063,7 @@
"id": "1809"
},
{
"examine": "Some (colour) thread found at the murder scene.",
"examine": "Some blue thread found at the murder scene.",
"durability": null,
"name": "Criminal's thread",
"tradeable": "false",
@@ -19090,7 +19090,7 @@
"id": "1812"
},
{
"examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.",
"examine": "A flimsy-looking dagger found at the crime scene.",
"attack_audios": "2517,2517,2500,2517",
"durability": null,
"name": "Criminal's dagger",
@@ -19098,7 +19098,7 @@
"id": "1813"
},
{
"examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.",
"examine": "A flimsy looking dagger found at the crime scene coated with a thin layer of flour.",
"attack_audios": "2517,2517,2500,2517",
"durability": null,
"name": "Criminal's dagger",
+12 -1
View File
@@ -8816,7 +8816,7 @@
"attack_level": "1"
},
{
"examine": "Big",
"examine": "Big, noisy, and scary looking!",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
@@ -73944,46 +73944,57 @@
"id": "797"
},
{
"examine": "His job doesn't look very fun...",
"name": "Pierre",
"id": "807"
},
{
"examine": "He looks kind of stuck up...",
"name": "Hobbes",
"id": "808"
},
{
"examine": "She looks like she enjoys her job.",
"name": "Louisa",
"id": "809"
},
{
"examine": "She looks very nervous...",
"name": "Mary",
"id": "810"
},
{
"examine": "He looks like he spends a lot of time outdoor.",
"name": "Stanford",
"id": "811"
},
{
"examine": "She's dressed in a red top and green trousers.",
"name": "Anna",
"id": "814"
},
{
"examine": "He's dressed all in red.",
"name": "Bob",
"id": "815"
},
{
"examine": "She's wearing a blue top and red trousers.",
"name": "Carol",
"id": "816"
},
{
"examine": "He's dressed all in green.",
"name": "David",
"id": "817"
},
{
"examine": "She's wearing a green top and blue trousers.",
"name": "Elizabeth",
"id": "818"
},
{
"examine": "He's dressed all in blue.",
"name": "Frank",
"id": "819"
},
+65 -1
View File
@@ -2351,14 +2351,46 @@
"npc_id": "805",
"loc_data": "{2936,3288,0,1,4}-"
},
{
"npc_id": "806",
"loc_data": "{2745,3576,1,0,4}-"
},
{
"npc_id": "807",
"loc_data": "{2750,3576,0,0,4}-"
},
{
"npc_id": "808",
"loc_data": "{2736,3575,0,1,1}-"
},
{
"npc_id": "809",
"loc_data": "{2734,3581,0,1,1}-"
},
{
"npc_id": "810",
"loc_data": "{2736,3576,1,1,1}-"
},
{
"npc_id": "811",
"loc_data": "{2731,3579,0,1,4}-"
},
{
"npc_id": "812",
"loc_data": "{2738,3473,0,0,1}-{2733,3473,0,0,1}-"
"loc_data": "{2741,3562,0,1,0}-"
},
{
"npc_id": "813",
"loc_data": "{2741,3552,0,1,1}-"
},
{
"npc_id": "820",
"loc_data": "{2697,3496,0,0,0}-"
},
{
"npc_id": "821",
"loc_data": "{2750,3580,0,1,0}-"
},
{
"npc_id": "822",
"loc_data": "{3302,9466,0,1,6}-"
@@ -10463,6 +10495,38 @@
"npc_id": "6190",
"loc_data": "{1906,4270,0,1,0}-"
},
{
"npc_id": "6191",
"loc_data": "{2739,3577,0,1,0}-{2739,3579,1,1,0}-"
},
{
"npc_id": "6192",
"loc_data": "{2734,3575,0,1,0}-"
},
{
"npc_id": "6193",
"loc_data": "{2748,3559,0,1,0}-"
},
{
"npc_id": "6194",
"loc_data": "{2734,3581,1,1,0}-"
},
{
"npc_id": "6195",
"loc_data": "{2739,3581,0,1,0}-"
},
{
"npc_id": "6196",
"loc_data": "{2746,3581,1,1,0}-"
},
{
"npc_id": "6197",
"loc_data": "{2742,3577,0,1,0}-"
},
{
"npc_id": "6199",
"loc_data": "{2737,3466,0,1,0}-"
},
{
"npc_id": "6200",
"loc_data": "{2947,3366,0,0,1}-{2949,3366,0,0,1}-{2946,3366,0,0,1}-{2948,3366,0,0,1}-{2945,3366,0,0,1}-{3010,3353,0,0,1}-{3011,3353,0,0,1}-{3012,3353,0,0,1}-{3013,3353,0,0,1}-{3014,3353,0,0,1}-{3015,3353,0,0,1}-"
@@ -1,11 +1,18 @@
package content.region.fremennik.rellekka.quest.thefremenniktrials
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.inInventory
import core.api.setAttribute
import core.game.dialogue.DialoguePlugin
import core.game.dialogue.FacialExpression
import core.game.dialogue.IfTopic
import core.game.dialogue.Topic
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
import org.rs09.consts.Items
import content.data.Quests
@Initializable
@@ -18,12 +25,18 @@ class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) {
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
//val murderMysteryStage = player.questRepository.isComplete(Quests.MURDER_MYSTERY)
val murderMysteryStage = player.questRepository.getStage(Quests.MURDER_MYSTERY)
val fremennikTrialsStage = player.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS)
when (stage) {
START_DIALOGUE -> when (buttonId) {
1 -> { player("Err... nevermind"); stage = END_DIALOGUE }
1 -> {
when (murderMysteryStage) {
0 -> npcl(FacialExpression.NEUTRAL, "I'm afraid I'm all sold out of poison at the moment. People know a bargain when they see it!").also { stage = END_DIALOGUE }
1 -> playerl(FacialExpression.NEUTRAL, "I'm investigating the murder at the Sinclair house.").also { stage = 50 }
100 -> npcl(FacialExpression.NEUTRAL, "I hear you're pretty smart to have solved the Sinclair Murder!").also { stage = END_DIALOGUE }
}
}
2 -> { player("Hello."); stage = 10 }
}
@@ -88,6 +101,42 @@ class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) {
stage++
}
45 -> { npc("Well come back when you do!"); stage = END_DIALOGUE }
//Murder Mystery
50 -> npcl(FacialExpression.NEUTRAL, "There was a murder at the Sinclair house??? That's terrible! And I was only there the other day too! They bought the last of my Patented Multi Purpose Poison!").also { stage++ }
51 -> showTopics(
Topic("Patented Multi Purpose Poison?", 52),
Topic("Who did you sell Poison to at the house?", 61),
Topic("Can I buy some Poison?", 65),
IfTopic("I have this pot I found at the murder scene...", 69, inInventory(player, Items.PUNGENT_POT_1812))
)
52 -> npcl(FacialExpression.NEUTRAL, "Aaaaah... a miracle of modern apothecaries!").also { stage++ }
53 -> npcl(FacialExpression.NEUTRAL, "This exclusive concoction has been tested on all known forms of life and been proven to kill them all in varying dilutions from cockroaches to king dragons!").also { stage++ }
54 -> npcl(FacialExpression.NEUTRAL, "So incredibly versatile, it can be used as pest control, a cleansing agent, drain cleaner, metal polish and washes whiter than white,").also { stage++ }
55 -> npcl(FacialExpression.NEUTRAL, "all with our uniquely fragrant concoction that is immediately recognisable across the land as Peter Potter's Patented Poison potion!!!").also { stage++ }
56 -> sendDialogue("The salesman stops for breath.").also { stage ++ }
57 -> npcl(FacialExpression.NEUTRAL, "I'd love to sell you some but I've sold out recently. That's just how good it is! Three hundred and twenty eight people in this area alone cannot be wrong!").also { stage++ }
58 -> npcl(FacialExpression.NEUTRAL, "Nine out of Ten poisoners prefer it in controlled tests!").also { stage++ }
59 -> npcl(FacialExpression.NEUTRAL, "Can I help you with anything else? Perhaps I can take your name and add it to our mailing list of poison users? We will only send you information related to the use of poison and other Peter Potter Products!").also { stage++ }
60 -> playerl(FacialExpression.NEUTRAL, "Uh... no, it's ok. Really.").also { stage = END_DIALOGUE }
61 -> npcl(FacialExpression.HAPPY, "Well, Peter Potter's Patented Multi Purpose Poison is a product of such obvious quality that I am glad to say I managed to sell a bottle to each of the Sinclairs!").also { stage++ }
62 -> npcl(FacialExpression.HAPPY, "Anna, Bob, Carol, David, Elizabeth and Frank all bought a bottle! In fact they bought the last of my supplies!").also { stage++ }
63 -> npcl(FacialExpression.HAPPY, "Maybe I can take your name and address and I will personally come and visit you when stocks return?").also { stage++ }
64 -> playerl(FacialExpression.THINKING, "Uh...no, it's ok.")
.also { setAttribute(player, attributePoisonClue, 1)}
.also { stage = END_DIALOGUE }
65 -> npcl(FacialExpression.NEUTRAL, "I'm afraid I am totally out of stock at the moment after my successful trip to the Sinclairs' House the other day.").also { stage++ }
66 -> npcl(FacialExpression.NEUTRAL, "But don't worry! Our factories are working overtime to produce Peter Potter's Patented Multi Purpose Poison!").also { stage++ }
67 -> npcl(FacialExpression.NEUTRAL, "Possibly the finest multi purpose poison and cleaner yet available to the general market.").also { stage++ }
68 -> npcl(FacialExpression.NEUTRAL, "And its unique fragrance makes it the number one choice for cleaners and exterminators the whole country over!").also { stage = END_DIALOGUE }
69 -> sendDialogue("You show the poison salesman the pot you found at the murder", "scene with the unusual smell.").also { stage ++ }
70 -> npcl(FacialExpression.THINKING, "Hmmm... yes, that smells exactly like my Patented Multi Purpose Poison, but I don't see how it could be. It quite clearly says on the label of all bottles").also { stage++ }
71 -> npcl(FacialExpression.THINKING, "'Not to be taken internally - EXTREMELY POISONOUS'.").also { stage++ }
72 -> playerl(FacialExpression.THINKING, "Perhaps someone else put it in his wine?").also { stage++ }
73 -> npcl(FacialExpression.THINKING, "Yes... I suppose that could have happened...").also { stage = END_DIALOGUE }
END_DIALOGUE -> end()
}
return true
@@ -0,0 +1,60 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonAnna
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
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 AnnaDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, AnnaDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return AnnaDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.ANNA_814, NPCs.ANNA_6192)
}
}
class AnnaDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl(FacialExpression.ASKING, "Oh really? What do you want to know then?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you when the murder happened?", 6),
IfTopic("Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
IfTopic("Why'd you buy poison the other day?", 10, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("It was clearly an intruder.").also { stage++ }
4 -> playerl("Well, I don't think it was.").also { stage++ }
5 -> npcl("It was one of our lazy servants then.").also { stage = END_DIALOGUE }
6 -> npcl("In the library. No one else was there so you'll just have to take my word for it.").also { stage = END_DIALOGUE }
7 -> sendDialogue(player!!, "You show Anna the thread from the study.")
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1809)) stage++ else stage = 9 }
8 -> npcl("It's some Green thread. It's not exactly uncommon is it? My trousers are made of the same material.").also { stage = END_DIALOGUE }
9 -> npcl("Not really, no. Thread is fairly common.").also { stage = END_DIALOGUE }
10 -> npcl(FacialExpression.ANNOYED, "That useless Gardener Stanford let his compost heap fester. It's an eyesore to the garden! So I bought some poison from a travelling salesman so that I could kill off some of the wildlife living in it.")
.also { setAttribute(player!!, attributeAskPoisonAnna, true)}
.also { stage = END_DIALOGUE }
}
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,61 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonBob
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
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 BobDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, BobDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return BobDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.BOB_815, NPCs.BOB_6193)
}
}
class BobDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl("I suppose I had better talk to you then.").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you when the murder happened?", 4),
IfTopic(FacialExpression.THINKING, "Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
IfTopic("Why'd you buy poison the other day?", 10, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("I don't really care as long as no one thinks it's me. Maybe it was that strange poison seller who headed towards the seers village.").also { stage = END_DIALOGUE }
4 -> npcl("I was walking by myself in the garden.").also { stage++ }
5 -> playerl("And can anyone vouch for that?").also { stage++ }
6 -> npcl("No. But I was.").also { stage = END_DIALOGUE }
7 -> sendDialogue(player!!, "You show him the thread you discovered.")
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1808)) stage++ else stage = 9 }
8 -> npcl("It's some red thread. I suppose you think that's some kind of clue? It looks like the material my trousers are made of.").also { stage = END_DIALOGUE }
9 -> npcl(FacialExpression.THINKING, "It's some thread. Great clue. No, really.").also { stage = END_DIALOGUE }
10 -> npcl(FacialExpression.THINKING, "What's it to you anyway?").also { stage++ }
11 -> npcl(FacialExpression.ANGRY, "If you absolutely must know, we had a problem with the beehive in the garden, and as all of our servants are so pathetically useless, I decided I would deal with it myself. So I did.")
.also { setAttribute(player!!, attributeAskPoisonBob, true)}
.also { stage = END_DIALOGUE }
}
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,59 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonCarol
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
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 CarolDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, CarolDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return CarolDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.CAROL_816, NPCs.CAROL_6194)
}
}
class CarolDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl("Well, ask what you want to know then.").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you when the murder happened?", 4),
IfTopic("Do you recognise this thread?", 5, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
IfTopic("Why'd you buy poison the other day?", 8, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("I don't know. I think it's very convenient that you have arrived here so soon after it happened. Maybe it was you.").also { stage = END_DIALOGUE }
4 -> npcl("Why? Are you accusing me of something? You seem to have a very high opinion of yourself. I was in my room if you must know, alone.").also { stage = END_DIALOGUE }
5 -> sendDialogue(player!!, "You show Carol the thread found at the crime scene.")
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1808)) stage++ else stage = 7 }
6 -> npcl("It's some red thread... it kind of looks like the Same material as my trousers. But obviously it's not.").also { stage = END_DIALOGUE }
7 -> npcl("It's some thread. Sorry, do you have a point here? Or do you just enjoy wasting peoples time?").also { stage = END_DIALOGUE }
8 -> npcl(FacialExpression.THINKING, "I don't see what on earth it has to do with you, but the drain outside was").also { stage++ }
9 -> npcl(FacialExpression.ANNOYED, "blocked, and as nobody else here has the intelligence to even unblock a simple drain I felt I had to do it myself.")
.also { setAttribute(player!!, attributeAskPoisonCarol, true)}
.also { stage = END_DIALOGUE }
}
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,60 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonDavid
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
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 DavidDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, DavidDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return DavidDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.DAVID_817, NPCs.DAVID_6195)
}
}
class DavidDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl("And? Make this quick. I have better things to do than be interrogated by halfwits all day.").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you when the murder happened?", 5),
IfTopic("Do you recognise this thread?", 6, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
IfTopic("Why'd you buy poison the other day?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("I don't really know or care. Frankly, the old man deserved to die.").also { stage++ }
4 -> npcl("There was a suspicious red headed man who came to the house the other day selling poison now I think about it. Last I saw he was headed towards the tavern in the Seers village.").also { stage = END_DIALOGUE }
5 -> npcl("That is none of your business. Are we finished now, or are you just going to stand there irritating me with your idiotic questions all day?").also { stage = END_DIALOGUE }
6 -> sendDialogue(player!!, "You show him the thread you found on the study window.")
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1809)) stage++ else stage = 8 }
7 -> npcl("It's some Green thread, like my trousers are made of. Are you finished? I'm not sure which I dislike more bout you, your face or your general bad odour.").also { stage = END_DIALOGUE }
8 -> npcl("No. Can I go yet? Your face irritates me.").also { stage = END_DIALOGUE }
9 -> npcl(FacialExpression.ANGRY, "There was a nest of spiders upstairs between the two servants' quarters. Obviously I had to kill them before our pathetic servants whined at my father some more.").also { stage++ }
10 -> npcl(FacialExpression.THINKING, "Honestly, it's like they expect to be treated like royalty! If I had my way I would fire the whole workshy lot of them!")
.also { setAttribute(player!!, attributeAskPoisonDavid, true)}
.also { stage = END_DIALOGUE }
}
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,57 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs
@Initializable
class DonovanDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, DonovanDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return DonovanDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.DONOVAN_THE_FAMILY_HANDYMAN_806)
}
}
class DonovanDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> npcl("I have no interest in talking to gawkers.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl("I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl("How can I help?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you at the time of the murder?", 5),
IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)),
IfTopic("Do you know why so much poison was bought recently?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("Oh... I really couldn't say. I wouldn't really want to point any fingers at anybody. If I had to make a guess I'd have to say it was probably Bob though.").also { stage++ }
4 -> npcl("I saw him arguing with Lord Sinclair about some missing silverware from the Kitchen. It was a very heated argument.").also { stage = END_DIALOGUE }
5 -> npcl("Me? I was sound asleep here in the servants Quarters. It's very hard work as a handyman around here. There's always something to do!").also { stage = END_DIALOGUE }
6 -> npcl("Hmmm... No, I didn't, but I sleep very soundly at night.").also { stage++ }
7 -> playerl("So you didn't hear any sounds of a struggle or any barking from the guard dog next to his study window?").also { stage++ }
8 -> npcl("Now you mention it, no. It is odd I didn't hear anything like that. But I do sleep very soundly as I said and wouldn't necessarily have heard it if there was any such noise.").also { stage = END_DIALOGUE }
9 -> npcl("Well, I do know Frank bought some poison recently to clean the family crest that's outside.").also { stage++ }
10 -> npcl("It's very old and rusty, and I couldn't clean it myself, so he said he would buy some cleaner and clean it himself. He probably just got some from that Poison Salesman who came to the door the other day...").also { stage++ }
11 -> npcl("You'd really have to ask him though.").also { stage = END_DIALOGUE }
}
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,64 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonElizabeth
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
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 ElizabethDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, ElizabethDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return ElizabethDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.ELIZABETH_818, NPCs.ELIZABETH_6196)
}
}
class ElizabethDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl("What's so important you need to bother me with then?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you when the murder happened?", 4),
IfTopic("Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
IfTopic("Why'd you buy poison the other day?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("Could have been anyone. The old man was an idiot. He's been asking for it for years.").also { stage = END_DIALOGUE }
4 -> npcl("I was out.").also { stage++ }
5 -> playerl("Care to be any more specific?").also { stage++ }
6 -> npcl("Not really. I don't have to justify myself to the likes of you, you know. I know the King personally you know. Now are we finished here?").also { stage = END_DIALOGUE }
7 -> sendDialogue(player!!, "You show her the thread from the study window.")
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1810)) stage++ else stage = 11 }
8 -> npcl(" Looks like Blue thread to me. If you can't work that out for yourself I don't hold much hope of you solving this crime.").also { stage++ }
9 -> playerl("It looks a lot like the material your trousers are made of doesn't it?").also { stage++ }
10 -> npcl("I suppose it does. So what?").also { stage = END_DIALOGUE }
11 -> npcl(" It's some thread. You're not very good at this whole investigation thing are you?").also { stage = END_DIALOGUE }
12 -> npcl("There was a nest of mosquitos under the fountain in the garden, which I killed with poison the other day. You can see for yourself if you're capable of managing that, which I somehow doubt.").also { stage++ }
13 -> playerl(FacialExpression.ANNOYED, "I hate mosquitos!").also { stage++ }
14 -> npcl("Doesn't everyone?")
.also { setAttribute(player!!, attributeAskPoisonElizabeth, true)}
.also { stage = END_DIALOGUE }
}
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,26 @@
package content.region.kandarin.quest.murdermystery
import core.api.*
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
import org.rs09.consts.Items
class FlypaperDialogue : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (stage) {
0 -> sendDialogue(player!!, "There's some flypaper in there. Should I take it?").also { stage++ }
1 -> options("Yes, it might be useful.", "No, I don't see any need for it.").also { stage++ }
2 -> when(buttonID) {
1 -> if (addItem(player!!, Items.FLYPAPER_1811)){
sendDialogue(player!!, "You take a piece of fly paper. There is still plenty of fly paper left.")
.also { stage = END_DIALOGUE }
}
else {
sendDialogue(player!!, "You don't have enough space in your inventory.")
.also { stage = END_DIALOGUE }
}
2 -> sendDialogue(player!!, "You leave the paper in the sack.").also { stage = END_DIALOGUE }
}
}
}
}
@@ -0,0 +1,15 @@
package content.region.kandarin.quest.murdermystery
import core.api.*
import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE
class FountainDialogue : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (stage) {
0 -> sendDialogue(player!!, "The fountain is swarming with mosquitos. There's a nest of them underneath the fountain.").also { stage++ }
1 -> playerl("I hate mosquitos, they're so annoying!").also { stage++ }
2 -> sendDialogue(player!!, "It's certainly clear nobody's used poison here.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,60 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonFrank
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
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 FrankDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, FrankDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return FrankDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.FRANK_819, NPCs.FRANK_6197)
}
}
class FrankDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl("Good for you. Now what do you want?").also { stage++ }
2 -> npcl(FacialExpression.SAD, "...And can you spare me any money? I'm a little short...").also { stage++ }
3 -> showTopics(
Topic("Who do you think is responsible?", 4),
Topic( "Where were you when the murder happened?", 5),
IfTopic("Do you recognise this thread?", 6, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
IfTopic("Why'd you buy poison the other day?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
4 -> npcl("I don't know. You don't know how long it takes an inheritance to come through do you? I could really use that money pretty soon...").also { stage = END_DIALOGUE }
5 -> npcl("I don't know, somewhere around here probably. Could you spare me a few coins? I'll be able to pay you back double tomorrow it's just there's this poker night tonight in town...").also { stage = END_DIALOGUE }
6 -> sendDialogue(player!!, "Frank examines the thread from the crime scene.")
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1810)) stage++ else stage = 8 }
7 -> npcl("It kind of looks like the same material as my trousers are made of... same colour anyway. Think it's worth anything? Can I have it? Or just some money?").also { stage = END_DIALOGUE }
8 -> npcl("It looks like thread to me, but I'm not exactly an expert. Is it worth something? Can I have it? Actually, can you spare me a few gold?").also { stage = END_DIALOGUE }
9 -> npcl("Would you like to buy some? I'm kind of strapped for cash right now. I'll sell it to you cheap. It's hardly been used at all.").also { stage++ }
10 -> npcl("I just used a bit to clean that family crest outside up a bit. Do you think I could get much money for the family crest, actually? It's cleaned up a bit now.")
.also { setAttribute(player!!, attributeAskPoisonFrank, true)}
.also { stage = END_DIALOGUE }
}
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,133 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import core.tools.RandomFunction
import org.rs09.consts.NPCs
@Initializable
class GossipDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, GossipDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return GossipDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.GOSSIP_813)
}
}
class GossipDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> npcl("There's some kind of commotion up at the Sinclair place I hear. Not surprising all things considered.").also { stage = END_DIALOGUE}
1 -> when (stage) {
0 -> playerl("I'm investigating the murder up at the Sinclair place.").also { stage++ }
1 -> npcl("Murder is it? Well, I'm not really surprised...").also { stage++ }
2 -> options("What can you tell me about the Sinclairs?", "Who do you think was responsible?", "I think the butler did it.", "I am so confused about who did it.").also { stage++ }
3 -> when(buttonID) {
1 -> playerl("What can you tell me about the Sinclairs?").also { stage = 4 }
2 -> playerl("Who do you think was responsible?").also { stage = 40 }
3 -> playerl("I think the butler did it.").also { stage = 42 }
4 -> playerl("I am so confused about who did it.").also { stage = 43 }
}
4 -> npcl("Well, what do you want to know?").also { stage++ }
5 -> options("Tell me about Lord Sinclair.", "Why do the Sinclairs live so far from town?", "What can you tell me about his sons?", "What can you tell me about his daughters?").also { stage++ }
6 -> when(buttonID) {
1 -> playerl("Tell me about Lord Sinclair.").also { stage = 7 }
2 -> playerl("Why do the Sinclairs live so far from town?").also { stage = 10 }
3 -> playerl("What can you tell me about his sons?").also { stage = 12 }
4 -> playerl("What can you tell me about his daughters?").also { stage = 15 }
}
7 -> npcl("Old Lord Sinclair was a great man with a lot of respect around these parts. More than his worthless children have anyway.").also { stage++ }
8 -> playerl("His children? They have something to gain by his death?").also { stage++ }
9 -> npcl("Yes. You could say that. Not that I am one to gossip.").also { stage = END_DIALOGUE }
10 -> npcl("Well, they used to live in the big castle, but old Lord Sinclair gave it up so that those strange knights could live there instead. So the king built him a new house to the North.").also { stage++ }
11 -> npcl("It's more cramped than his old place, but he seemed to like it. His children were furious at him for doing it though!").also { stage = END_DIALOGUE }
12 -> npcl("His sons eh? They all have their own skeletons in their cupboards. You'll have to be more specific. Who are you interested in exactly?").also { stage++ }
13 -> options("Tell me about Bob.", "Tell me about David.", "Tell me about Frank.").also { stage++ }
14 -> when(buttonID) {
1 -> playerl("Tell me about Bob.").also { stage = 18 }
2 -> playerl("Tell me about David.").also { stage = 23 }
3 -> playerl("Tell me about Frank.").also { stage = 27 }
}
15 -> npcl("His daughters eh? They're all nasty pieces of work, which of them specifically did you want to know about?").also { stage++ }
16 -> options("Tell me about Anna.", "Tell me about Carol.", "Tell me about Elizabeth.").also { stage++ }
17 -> when(buttonID) {
1 -> playerl("Tell me about Anna.").also { stage = 30 }
2 -> playerl("Tell me about Carol.").also { stage = 33 }
3 -> playerl("Tell me about Elizabeth.").also { stage = 36 }
}
18 -> npcl("Bob is an odd character indeed... I'm not one to gossip, but I heard Bob is addicted to Tea. He can't make").also { stage++ }
19 -> npcl("it through the day without having at least 20 cups!").also { stage++ }
20 -> npcl("You might not think that's such a big thing, but he has spent thousands of gold to feed his habit!").also { stage++ }
21 -> npcl("At one point he stole a lot of silverware from the kitchen and pawned it just so he could afford to buy his daily tea allowance.").also { stage++ }
22 -> npcl("If his father ever found out, he would be in so much trouble... he might even get disowned!").also { stage = END_DIALOGUE }
23 -> npcl("David... oh David... not many people know this, but David really has an anger problem. He's always screaming and shouting").also { stage++ }
24 -> npcl("at the household servants when he's angry, and they live in a state of fear, always walking on eggshells around him, but none of them have the courage").also { stage++ }
25 -> npcl("to talk to his father about his behaviour. If they did, Lord Sinclair would almost certainly").also { stage++ }
26 -> npcl("kick him out of the house, as some of the servants have been there longer than he has, and he definitely has no right to treat them like he does... but I'm not one to gossip about people.").also { stage = END_DIALOGUE }
27 -> npcl("I'm not one to talk ill of people behind their back, but Frank is a real piece of work. He is an absolutely terrible gambler...he can't pass 2 dogs in the street without putting a bet on which one will bark first!").also { stage++ }
28 -> npcl("He has already squandered all of his allowance, and I heard he had stolen a number of paintings of his fathers to sell to try and cover his debts, but he still owes a lot of people a lot of").also { stage++ }
29 -> npcl("money. If his father ever found out, he would stop his income, and then he would be in serious trouble!").also { stage = END_DIALOGUE }
30 -> npcl("Anna... ah yes... Anna has 2 great loves:").also { stage++ }
31 -> npcl("Sewing and gardening. But one thing she has kept secret is that she once had an affair with Stanford the gardener, and tried to get him fired when they broke up,").also { stage++ }
32 -> npcl("by killing all of the flowers in the garden. If her father ever found out she had done that he would be so furious he would probably disown her.").also { stage = END_DIALOGUE }
33 -> npcl("Oh Carol... she is such a fool. You didn't hear this from me, but I heard a while ago she was conned out of a lot of money by a travelling salesman who sold her a box full").also { stage++ }
34 -> npcl("of beans by telling her they were magic. But they weren't. She sold some rare books from the library to cover her debts, but").also { stage++ }
35 -> npcl("her father would be incredibly annoyed if he ever found out - he might even throw her out of the house!").also { stage = END_DIALOGUE }
36 -> npcl("Elizabeth? Elizabeth has a strange problem... She cannot help herself, but is always stealing small objects - it's pretty sad that she is rich enough to afford to buy things, but would rather steal them instead.").also { stage++ }
37 -> npcl("Now, I don't want to spread stories, but I heard she even stole a silver needle from her father that had great sentimental value for him.").also { stage++ }
38 -> npcl("He was devastated when it was lost, and cried for a week thinking he had lost it!").also { stage++ }
39 -> npcl("If he ever found out that it was her who had stolen it he would go absolutely mental, maybe even disowning her!").also { stage = END_DIALOGUE }
40 -> npcl("Well, I guess it could have been an intruder, but with that big guard dog of theirs I seriously doubt it. I suspect it was someone closer to home...").also { stage ++ }
41 -> npcl("Especially as I heard that the poison salesman in the Seers' village made a big sale to one of the family the other day.")
.also { setAttribute(player!!, attributeNoiseClue, true)}
.also { stage = END_DIALOGUE }
42 -> npcl("And I think you've been reading too many cheap detective novels. Hobbes is kind of uptight, but his loyalty to old Lord Sinclair is beyond question.").also { stage = END_DIALOGUE }
43 -> playerl("Think you could give me any hints?")
.also { when (RandomFunction.random(4)) { //RS3 wiki seems to indicate this is fully random, not based off of progression
0 -> stage = 44
1 -> stage = 46
2 -> stage = 47
3 -> stage = 48
4 -> stage = 51
}
}
44 -> npcl("Well, I don't know if it's related, but I heard from that Poison Salesman in town that he sold some poison to one of the Sinclair family").also { stage++ }
45 -> npcl("the other day. I don't think he has any stock left now though...").also { stage = END_DIALOGUE }
46 -> npcl("Well, I don't know how much help this is, but I heard their guard dog will bark loudly at anyone it doesn't recognise. Maybe you should find out if anyone heard anything suspicious?")
.also { stage = END_DIALOGUE }
47 -> npcl("Well, this might be of some help to you. My father was in the guards when he was younger and he always said that there isn't a crime that can't be solved through careful examination of the crime scene and all surrounding areas.").also { stage = END_DIALOGUE }
48 -> npcl("I don't know how much help this is to you, but my dad was in the guard once and he told me the marks on your hands are totally unique. He calls them 'finger prints'.").also { stage++ }
49 -> npcl("He said you can find them easily on any shiny metallic surface, by using a fine powder to mark out where the marks are and then using some sticky paper to lift the print from the object.").also { stage++ }
50 -> npcl("I bet if you could find a way to get everyone's 'finger prints' you could solve the crime pretty easily!").also { stage = END_DIALOGUE }
51 -> npcl("My father used to be in the guard, he always wrote himself notes on a piece of paper so he could keep track of information easily.").also { stage++ }
52 -> npcl("Maybe you should try that? Don't forget to thank me if I help you solve the case!").also { stage = END_DIALOGUE }
}
}
}
}
@@ -0,0 +1,220 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeRandomMurderer
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.clueCount
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.solvedMystery
import core.ServerConstants.Companion.SERVER_NAME
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import core.tools.RandomFunction
import org.rs09.consts.Items
import org.rs09.consts.NPCs
@Initializable
class GuardDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, GuardDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return GuardDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.GUARD_812, NPCs.GUARD_6191)
}
}
class GuardDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
val KILLER = when (getAttribute(player!!, attributeRandomMurderer, 0)) {
0 -> "Anna"
1 -> "Bob"
2 -> "Carol"
3 -> "David"
4 -> "Elizabeth"
5 -> "Frank"
else -> "Anna"
}
val POISONSPOT = when (getAttribute(player!!, attributeRandomMurderer, 0)) {
0 -> "compost heap"
1 -> "beehive"
2 -> "drain"
3 -> "spiders nest"
4 -> "fountain"
5 -> "Sinclair Crest"
else -> "compost heap"
}
val KILLERMALE = when (getAttribute(player!!, attributeRandomMurderer, 0)) {
1, 3, 5 -> true
else -> false
}
val EVIDENCE = (1796..1822).toList().toIntArray() //All Murder Mystery related items are between these item ids
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "What's going on here?").also { stage++ }
1 -> npcl(FacialExpression.SAD, "Oh, it's terrible! Lord Sinclair has been murdered and we don't have any clues as to who or why. We're totally baffled!").also { stage++ }
2 -> npcl(FacialExpression.SAD, "If you can help us we will be very grateful.").also { stage++ }
3 -> options("Sure, I'll help.", "You should do your own dirty work.").also { stage++ }
4 -> when (buttonID) {
1 -> playerl(FacialExpression.HAPPY, "Sure, I'll help.").also { stage++ }
2 -> playerl("You should do your own dirty work.").also { stage = 8 }
}
5 -> npcl(FacialExpression.HAPPY, "Thanks a lot!").also { stage++ }
6 -> playerl(FacialExpression.NEUTRAL, "What should I be doing to help?").also { stage++ }
7 -> npcl(FacialExpression.NEUTRAL, "Look around and investigate who might be responsible. The Sarge said every murder leaves clues to who done it, but frankly we're out of our depth here.")
.also { setAttribute(player!!, attributeRandomMurderer, RandomFunction.random(5))}
.also { setQuestStage(player!!, Quests.MURDER_MYSTERY, 1) }
.also { stage = END_DIALOGUE }
8 -> npcl("Get lost then, this is private property! ...Unless you'd like to be taken in for questioning yourself?").also { stage = END_DIALOGUE }
}
1 -> when (stage) {
0 -> options("What should I be doing to help again?", "How did Lord Sinclair die?", "I know who did it!").also { stage++ }
1 -> when(buttonID) {
1 -> playerl("What should I be doing to help?").also { stage = 2 }
2 -> playerl("How did Lord Sinclair die?").also { stage = 3 }
3 -> playerl(FacialExpression.HAPPY, "I know who did it!")
.also {
stage = if (solvedMystery(player!!)) 46
else if (clueCount(player!!) == 1) {
if (inInventory(player!!, Items.KILLERS_PRINT_1815)) {
41
}
else if (getAttribute(player!!, attributePoisonClue,0) == 2) {
37
}
else 33
}
else if (clueCount(player!!) > 1) 32
else 6
}
}
2 -> npcl("Look around and investigate who might be responsible. The Sarge said every murder leaves clues to who done it, but frankly we're out of our depth here.").also { stage = END_DIALOGUE }
3 -> npcl("Well, it's all very mysterious. Mary, the maid, found the body in the study next to his bedroom on the east wing of the ground floor.").also { stage++ }
4 -> npcl("The door was found locked from the inside, and he seemed to have been stabbed, but there was an odd smell in the room. Frankly, I'm stumped.").also { stage = END_DIALOGUE }
5 -> npcl("Really? That was quick work! Who?").also { stage++ }
6 -> options("It was an intruder!", "The butler did it!", "It was one of the servants!", "It was one of his family!").also { stage++ }
7 -> when (buttonID) {
1 -> playerl("It was an intruder!").also { stage = 10 }
2 -> playerl("The butler did it!").also { stage = 8 }
3 -> playerl("It was one of the servants!").also { stage = 13 }
4 -> playerl("It was one of his family!").also { stage = 20 }
}
8 -> npcl("I hope you have proof to that effect. We have to arrest someone for this and it seems to me that only the actual murderer would gain by falsely accusing someone.").also { stage++ }
9 -> npcl("Although having said that the butler is kind of shifty looking...").also { stage = END_DIALOGUE }
10 -> npcl("That's what we were thinking too. That someone broke in to steal something, was discovered by Lord Sinclair, stabbed him and ran.").also { stage++ }
11 -> npcl("It's odd that apparently nothing was stolen though... Find out something has been stolen,").also { stage++ }
12 -> npcl("and the case is closed, but the murdered man was a friend of the King and it's more than my job's worth not to investigate fully.").also { stage = END_DIALOGUE }
13 -> npcl("Oh really? Which one?").also { stage++ }
14 -> options("It was one of the women.", "It was one of the men.").also { stage++ }
15 -> when (buttonID) {
1 -> playerl("It was one of the women.").also { stage = 16 }
2 -> playerl("It was one of the men.").also { stage = 18 }
}
16 -> options("It was so obviously Louisa The Cook.", "It must have been Mary The Maid.").also { stage++ }
17 -> when (buttonID) {
1 -> playerl("It was so obviously Louisa The Cook.").also { stage = 27 }
2 -> playerl("It must have been Mary The Maid.").also { stage = 27 }
}
18 -> options("It can only be Donovan the Handyman.", "Pierre the Dog Handler. No question", "Hobbes the Butler. The butler *always* did it.", "You must know it was Stanford The Gardener.").also { stage++ }
19-> when (buttonID) {
1 -> playerl("It can only be Donovan the Handyman.").also { stage = 27 }
2 -> playerl("Pierre the Dog Handler. No question.").also { stage = 27 }
3 -> playerl("Hobbes the Butler. The butler *always* did it.").also { stage = 8 }
4 -> playerl("You must know it was Stanford The Gardener.").also { stage = 27 }
}
20 -> npcl("Oh really? Which one?").also { stage++ }
21 -> options("It was one of the women.", "It was one of the men.").also { stage++ }
22 -> when (buttonID) {
1 -> playerl("It was one of the women.").also { stage = 23 }
2 -> playerl("It was one of the men.").also { stage = 25 }
}
23 -> options("I know it was Anna.", "I am so sure it was Carol.", "I'll bet you anything it was Elizabeth.").also { stage++ }
24 -> when (buttonID) {
1 -> playerl("I know it was Anna.").also { stage = 27 }
2 -> playerl("I am so sure it was Carol.").also { stage = 27 }
3 -> playerl("I'll bet you anything it was Elizabeth.").also { stage = 27 }
}
25 -> options("I'm certain it was Bob.", "It was David. No doubt about it.", "If it wasn't Frank I'll eat my shoes.").also { stage++ }
26 -> when (buttonID) {
1 -> playerl("I'm certain it was Bob.").also { stage = 27 }
2 -> playerl("It was David. No doubt about it.").also { stage = 27 }
3 -> playerl("If it wasn't Frank I'll eat my shoes.").also { stage = 27 }
}
27 -> sendDialogue(player!!, "You tell the guard who you suspect of the crime.").also { stage++ }
28 -> npcl("Great work, show me the evidence and we'll take them to the dungeons.").also { stage++ }
29 -> npcl("You *DO* have evidence of their crime, right?").also { stage++ }
30 -> playerl("Uh...").also { stage++ }
31 -> npcl("Tch. You wouldn't last a day in the guards with sloppy thinking like that. Come see me when you have some proof of your accusations.").also { stage = END_DIALOGUE }
32 -> showTopics(
IfTopic("I have proof that it wasn't any of the servants.", 33, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810), true),
IfTopic("I have proof one of the family lied about the poison.", 37, getAttribute(player!!, attributePoisonClue, 0) == 2, true),
IfTopic("I have the finger prints of the culprit.", 41, inInventory(player!!, Items.KILLERS_PRINT_1815), true)
)
33 -> playerl("I have proof that it wasn't any of the servants!").also { stage++ }
34 -> sendDialogue(player!!, "You show the guard the thread you found on the window.").also { stage ++ }
35 -> playerl("All the servants dress in black so it couldn't have been one of them.").also { stage++ }
36 -> npcl("That's some good work there. I guess it wasn't a servant. You still haven't proved who did do it though.").also { stage = END_DIALOGUE }
37 -> playerl("I have proof that $KILLER is lying about the poison.").also { stage++ }
38 -> npcl("Oh really? How did you get that?").also { stage++ }
39 -> sendDialogue(player!!, "You tell the guard about the " +
when (getAttribute(player!!, attributeRandomMurderer, 0)) {
4 -> "mosquitos at the fountain."
5 -> "tarnished family crest."
else -> "$POISONSPOT."
}).also { stage++ }
40 -> npcl("Hmm. That's some good detective work there, we need more evidence before we can close the case though. Keep up the good work.").also { stage = END_DIALOGUE }
41 -> playerl("I have the fingerprints of the culprit!").also { stage++ }
42 -> playerl("I have $KILLER's fingerprints here, you can see for yourself they match the fingerprints on the murder weapon exactly.").also { stage++ }
43 -> sendDialogue(player!!,"You show the guard the finger prints evidence.").also { stage++ }
44 -> npcl("... I'm impressed. How on earth did you think of something like that? I've never heard of such a technique for finding criminals before!").also { stage++ }
45 -> npcl("This will come in very handy in the future but we can't arrest someone on just this. I'm afraid you'll still need to find more evidence before we can close this case completely.").also { stage = END_DIALOGUE }
46 -> playerl(FacialExpression.HAPPY, "I have conclusive proof who the killer was.").also { stage++ }
47 -> npcl(FacialExpression.HAPPY, "You do? That's excellent work. Let's hear it then.").also { stage++ }
48 -> playerl("I don't think it was an intruder, and I don't think Lord Sinclair was killed by being stabbed.").also { stage++ }
49 -> npcl("Hmmm? Really? Why not?").also { stage++ }
50 -> playerl(FacialExpression.HAPPY, "Nobody heard the guard dog barking, which it would have if it had been an intruder who was responsible.").also { stage++ }
51 -> playerl("Nobody heard any signs of a struggle either. I think the knife was there to throw suspicion away from the real culprit.").also { stage++ }
52 -> npcl("Yes, that makes sense. But who did do it then?").also { stage++ }
53 -> sendDialogue(player!!, "You prove to the guard the thread matches $KILLER's clothes.").also { stage++ }
54 -> npcl("Yes, I'd have to agree with that... but we need more evidence!").also { stage++ }
55 -> sendDialogue(player!!, "You prove to the guard $KILLER did not use the poison on the $POISONSPOT.").also { stage++ }
56 -> npcl("Excellent work - have you considered a career as a detective? But I'm afraid it's still not quite enough...").also { stage++ }
57 -> sendDialogue(player!!, "You match $KILLER's finger prints with those on the dagger found in the body of Lord Sinclair.").also { stage++ }
58 -> npcl(FacialExpression.HAPPY, "Yes. There's no doubt about it. It must have been $KILLER who killed " + if (KILLERMALE) {"his"} else {"her"} + " father. All of the guards must congratulate you on your excellent work in helping us to solve this case.").also { stage++ }
59 -> npcl("We don't have many murders here in $SERVER_NAME and I'm afraid we wouldn't have been able to solve it by ourselves. We will hold " + if (KILLERMALE) {"him"} else {"her"} + " here under house arrest until such time as we bring " + if (KILLERMALE) {"him"} else {"her"} + " to trial.").also { stage++ }
60 -> npcl("You have our gratitude, and I'm sure the rest of the family's as well, in helping to apprehend the murderer. I'll just take the evidence from you now.").also { stage++ }
61 -> sendDialogue(player!!, "You hand over all the evidence.").also { stage++ }
62 -> npcl(FacialExpression.HAPPY, "Please accept this reward from the family!").also { stage++ }
63 -> finishQuest(player!!, Quests.MURDER_MYSTERY)
.also {
player!!.inventory.removeAll(EVIDENCE)
player!!.bank.removeAll(EVIDENCE)
player!!.equipment.removeAll(EVIDENCE)
}
.also { stage = END_DIALOGUE }
}
100 -> when (stage) {
0 -> npcl("Excellent work on solving the murder! All of the guards I know are very impressed, and don't worry, we have the murderer under guard until they can be taken to trial.").also { stage++ }
1 -> playerl("Is there anything else I can do? Seems awfully quiet up at the house, considering their sibling has just been arrested.").also { stage++ }
2 -> npcl("Nothing right now, we have it all under control.").also { stage = END_DIALOGUE }
}
}
}
}
@@ -0,0 +1,62 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs
@Initializable
class HobbesDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, HobbesDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return HobbesDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.HOBBES_808)
}
}
class HobbesDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> npcl("This is private property! Please leave!").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you at the time of the murder?", 6),
IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)),
IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("Well, in my considered opinion it must be David. The man is nothing more than a bully And I happen to know that poor Lord Sinclair and David had a massive argument in the living").also { stage++ }
4 -> npcl("room about the way he treats the staff, the other day. I did not intend to overhear their conversation, but they were shouting so loudly I could not help but Overhear it. David definitely used the words").also { stage++ }
5 -> npcl("'I am going to kill you!' as well. I think he should be the prime suspect. He has a nasty temper that one.").also { stage = END_DIALOGUE }
6 -> npcl("I was assisting the cook with the evening meal. I gave Mary His Lordships' dinner, and sent her to take it to him, then heard the scream as she found the body.").also { stage = END_DIALOGUE }
7 -> npcl("How do you mean 'suspicious'?").also { stage++ }
8 -> playerl("Any sounds of a struggle with Lord Sinclair?").also { stage++ }
9 -> npcl("No, I definitely didn't hear anything like that.").also { stage++ }
10 -> playerl("How about the guard dog barking at all?").also { stage++ }
11 -> npcl("You know, now you come to mention it I don't believe I did. I suppose that is Proof enough that it could not have been an intruder who is responsible.").also { stage = END_DIALOGUE }
12 -> npcl("Well, I do know that Elizabeth was extremely annoyed by the mosquito nest under the fountain in the garden, and was going to do something about it. I suspect any poison she bought would have been").also { stage++ }
13 -> npcl ("enough to get rid of it. A Good job, too. I hate mosquitos.").also { stage++ }
14 -> playerl("Yeah, so do I.").also { stage++ }
15 -> npcl("You'd really have to ask her though.").also { stage = END_DIALOGUE }
}
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,59 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs
@Initializable
class LouisaDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, LouisaDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return LouisaDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.LOUISA_809)
}
}
class LouisaDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> npcl("I'm far too upset to talk to random people right now.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you at the time of the murder?", 6),
IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)),
IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("Elizabeth.").also { stage ++ }
4 -> npcl("Her father confronted her about her constant petty thieving, and was devastated to find she had stolen a silver needle which had meant a lot to him.").also { stage++ }
5 -> npcl("You could hear their argument from Lumbridge!").also { stage = END_DIALOGUE }
6 -> npcl("I was right here with Hobbes and Mary. You can't suspect me surely!").also { stage = END_DIALOGUE }
7 -> npcl("Suspicious? What do you mean suspicious?").also { stage++ }
8 -> playerl("Any sounds of a struggle with an intruder for example?").also { stage++ }
9 -> npcl("No, I'm sure I don't recall any such thing.").also { stage++ }
10 -> playerl("How about the guard dog barking at an intruder?").also { stage++ }
11 -> npcl("No, I didn't. If you don't have anything else to ask can You go and leave me alone now? I have a lot of cooking to do for this evening.").also { stage = END_DIALOGUE }
12 -> npcl("I told Carol to buy some from that strange poison salesman and clean the drains before they began to smell any worse. She was the one who blocked them in the first place with a load").also { stage++ }
13 -> npcl("of beans that she bought for some reason. There were far too many to eat, and they were almost rotten when she bought them anyway! You'd really have to ask her though.").also { stage = END_DIALOGUE }
}
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,59 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs
@Initializable
class MaryDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, MaryDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return MaryDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.MARY_810)
}
}
class MaryDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you at the time of the murder?", 5),
IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)),
IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("Oh I don't know... Frank was acting kind of funny... After that big argument him and the Lord had the other day by the beehive... so").also { stage ++ }
4 -> npcl("I guess maybe him... but it's really scary to think someone here might have been responsible. I actually hope it was a burglar...").also { stage = END_DIALOGUE }
5 -> npcl("I was with Hobbes and Louisa in the Kitchen helping to prepare Lord Sinclair's meal, and then when I took it to his study... I saw... oh, it was horrible... he was...").also { stage++ }
6 -> sendDialogue(player!!, "She seems to be on the verge of crying. You decide not to push her anymore for details.").also { stage = END_DIALOGUE}
7 -> npcl("I don't really remember hearing anything out of the ordinary.").also { stage++ }
8 -> playerl("No sounds of a struggle then?").also { stage++ }
9 -> npcl("No, I don't remember hearing anything like that.").also { stage++ }
10 -> playerl("How about the guard dog barking?").also { stage++ }
11 -> npcl("Oh that horrible dog is always barking at noting but I don't think I did...").also { stage = END_DIALOGUE }
12 -> npcl("I overheard Anna saying to Stanford that if he didn't do something about the state of his compost heap, she was going to.").also { stage++ }
13 -> npcl("She really doesn't get on well with Stanford, I really have no idea why. You'd really have to ask her though.").also { stage = END_DIALOGUE }
}
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,156 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import core.api.*
import core.game.node.entity.player.link.quest.Quest
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.plugin.Initializable
import org.rs09.consts.Items
// https://www.youtube.com/watch?v=f1Eou5i5hBo at 2:29
// https://www.youtube.com/watch?v=BwO4JhZdQKo at 25:20
// https://www.youtube.com/watch?v=u5Osw_jas4A at 26:35
// https://www.youtube.com/watch?v=f1Eou5i5hBo
// https://www.youtube.com/watch?v=9Q2aLUg44SQ at 10:02
// https://www.youtube.com/watch?v=_lTUessdfOM 6:18
/**
* Murder Mystery Quest
*/
@Initializable
class MurderMystery : Quest(Quests.MURDER_MYSTERY, 93, 92, 3, 192, 0, 1, 2) {
companion object {
const val questName = "Murder Mystery"
const val attributeRandomMurderer = "/save:quest:murdermystery-randommurderer" //Alphabetical, 0 for Anna, 1 for Bob, 2 for Carol, 3 for David, 4 for Elizabeth, 5 for Frank
const val attributeTakenThread = "/save:quest:murdermystery-takenthread" //true after taking thread for the first time from window
const val attributeNoiseClue = "/save:quest:murdermystery-noiseclue" //true on learning of the barking dog for the first time
const val attributePoisonClue = "/save:quest:murdermystery-poisonclue" //1 after learning poison was bought, 2 after finding liar
const val attributeAskPoisonAnna = "/save:quest:murdermystery-askpoisonanna" //true after asking Anna about poison
const val attributeAskPoisonBob = "/save:quest:murdermystery-askpoisonbob" //true after asking Bob about poison
const val attributeAskPoisonCarol = "/save:quest:murdermystery-askpoisoncarol" //true after asking Carol about poison
const val attributeAskPoisonDavid = "/save:quest:murdermystery-askpoisondavid" //true after asking David about poison
const val attributeAskPoisonElizabeth = "/save:quest:murdermystery-askpoisonelizabeth" //true after asking Elizabeth about poison
const val attributeAskPoisonFrank = "/save:quest:murdermystery-askpoisonfrank" //true after asking Anna about poison
fun clueCount(player: Player) : Int {
var count = 0
if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) {
count++
}
if (inInventory(player, Items.KILLERS_PRINT_1815)) {
count ++
}
if (getAttribute(player, attributePoisonClue,0) == 2) {
count ++
}
return count
}
fun solvedMystery(player: Player) : Boolean {
return (
( inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810) )
&& inInventory(player, Items.KILLERS_PRINT_1815)
&& getAttribute(player, attributePoisonClue,0) == 2
&& getAttribute(player, attributeNoiseClue, false)
)
}
}
override fun drawJournal(player: Player, stage: Int) {
super.drawJournal(player, stage)
var line = 12
var stage = getStage(player)
var started = getQuestStage(player, Quests.MURDER_MYSTERY) > 0
if (!started) {
line(player, "I can start this quest by speaking to one of the !!Guards?? at", line++, false)
line(player, "the !!Sinclair Mansion??, North of the !!Seer's Village??.", line++, false)
} else if (stage < 100) {
line(player, "Lord Sinclair, a prominent nobleman, had been horribly", line++, true)
line(player, "murdered at his mansion. The guards had been sent to", line++, true)
line(player, "investigate his murder, but have been completely stuck.", line++, true)
if (solvedMystery(player)) {
line(player, "One of the guards asked me for my help in solving the", line++, true)
line(player, "murder. After careful examination of the crime scene and", line++, true)
line(player, "interrogating all suspects, I worked out who was guilty.", line++, true)
} else {
line(player, "One of the !!guards?? has asked me for my help in solving the", line++, false)
line(player, "murder. I should !!examine the crime scene?? very closely for", line++, false)
line(player, "evidence, and !!interrogate everybody?? in the area carefully.", line++, false)
}
// This may not be a stage but an attribute when all the evidence is collected.
if (solvedMystery(player)) {
line(player, "I have !!indisputable evidence?? of who the murderer must be.", line++, false)
line(player, "I should take it to one of the !!Guards?? immediately.", line++, false)
} else {
line++
if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) {
line(player, "I have found some !!coloured thread??. It might be useful.", line++, false)
}
if (inInventory(player, Items.CRIMINALS_DAGGER_1813) || inInventory(player, Items.CRIMINALS_DAGGER_1814)) {
line(player, "I have taken the !!murder weapon??. I think it might help me.", line++, false)
}
if (inInventory(player, Items.PUNGENT_POT_1812)) {
line(player, "I have a !!strange smelling pot??. It seems like a clue.", line++, false)
}
}
} else {
line(player, "One of the guards asked me for my help in solving the", line++, true)
line(player, "murder. After careful examination of the crime scene and", line++, true)
line(player, "interrogating all suspects, I worked out who was guilty.", line++, true)
line(player, "I took the evidence I had collected to the Guards and", line++, true)
line(player, "explained how it could identify the killer. Impressed", line++, true)
line(player, "with my deductions, the killer was arrested and I was", line++, true)
line(player, "given a fair reward for my help in solving the crime.", line++, true)
line++
line(player,"<col=FF0000>QUEST COMPLETE!</col>", line)
}
}
override fun reset(player: Player) {
removeAttribute(player, attributeRandomMurderer)
removeAttribute(player, attributeNoiseClue)
removeAttribute(player, attributePoisonClue)
removeAttribute(player, attributeTakenThread)
removeAttribute(player, attributeAskPoisonAnna)
removeAttribute(player, attributeAskPoisonBob)
removeAttribute(player, attributeAskPoisonCarol)
removeAttribute(player, attributeAskPoisonDavid)
removeAttribute(player, attributeAskPoisonElizabeth)
removeAttribute(player, attributeAskPoisonFrank)
}
override fun finish(player: Player) {
var ln = 10
super.finish(player)
player.packetDispatch.sendString("You have completed the Murder Mystery quest!", 277, 4)
player.packetDispatch.sendItemZoomOnInterface(Items.COINS_617, 230, 277, 5)
drawReward(player, "3 Quest Points", ln++)
drawReward(player, "2000 coins", ln++)
drawReward(player, "1406 Crafting XP", ln++)
addItem(player, Items.COINS_995, 2000)
rewardXP(player, Skills.CRAFTING, 1406.0)
removeAttribute(player, attributeNoiseClue)
removeAttribute(player, attributePoisonClue)
removeAttribute(player, attributeTakenThread)
removeAttribute(player, attributeAskPoisonAnna)
removeAttribute(player, attributeAskPoisonBob)
removeAttribute(player, attributeAskPoisonCarol)
removeAttribute(player, attributeAskPoisonDavid)
removeAttribute(player, attributeAskPoisonElizabeth)
removeAttribute(player, attributeAskPoisonFrank)
}
override fun newInstance(`object`: Any?): Quest {
return this
}
}
@@ -0,0 +1,442 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonAnna
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonBob
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonCarol
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonDavid
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonElizabeth
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonFrank
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeRandomMurderer
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeTakenThread
import core.api.*
import core.game.interaction.InteractionListener
import core.game.node.item.GroundItem
import core.game.node.item.Item
import org.rs09.consts.Items
import org.rs09.consts.Scenery
class MurderMysteryListeners : InteractionListener {
companion object {
val UNDUSTEDEVIDENCE = intArrayOf(
Items.CRIMINALS_DAGGER_1813,
Items.PUNGENT_POT_1812,
Items.SILVER_NECKLACE_1796,
Items.SILVER_CUP_1798,
Items.SILVER_BOTTLE_1800,
Items.SILVER_BOOK_1802,
Items.SILVER_NEEDLE_1804,
Items.SILVER_POT_1806
)
val DUSTEDEVIDENCE = intArrayOf(
Items.CRIMINALS_DAGGER_1814,
Items.SILVER_NECKLACE_1797,
Items.SILVER_CUP_1799,
Items.SILVER_BOTTLE_1801,
Items.SILVER_BOOK_1803,
Items.SILVER_NEEDLE_1805,
Items.SILVER_POT_1807
)
val SILVERBARRELS = intArrayOf(
Scenery.ANNA_S_BARREL_2656,
Scenery.BOB_S_BARREL_2657,
Scenery.CAROL_S_BARREL_2658,
Scenery.DAVID_S_BARREL_2659,
Scenery.ELIZABETH_S_BARREL_2660,
Scenery.FRANK_S_BARREL_2661
)
val POISONSPOTS = intArrayOf(
Scenery.SINCLAIR_FAMILY_COMPOST_HEAP_26120,
Scenery.SINCLAIR_FAMILY_BEEHIVE_26121,
Scenery.SINCLAIR_MANSION_DRAIN_2843,
Scenery.SPIDERS__NEST_26109,
Scenery.SINCLAIR_FAMILY_FOUNTAIN_2654,
Scenery.SINCLAIR_FAMILY_CREST_2655
)
val SUSPECTPRINTS = intArrayOf(
Items.ANNAS_PRINT_1816,
Items.BOBS_PRINT_1817,
Items.CAROLS_PRINT_1818,
Items.DAVIDS_PRINT_1819,
Items.ELIZABETHS_PRINT_1820,
Items.FRANKS_PRINT_1821
)
}
override fun defineListeners() {
on(Items.CRIMINALS_DAGGER_1813, GROUNDITEM, "take") { player, groundItem ->
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
1 -> {
if (inInventory(player, Items.CRIMINALS_DAGGER_1813) || inInventory(player, Items.CRIMINALS_DAGGER_1814)) {
sendDialogue(player, "I already have the murder weapon.")
}
else if (addItem(player, Items.CRIMINALS_DAGGER_1813)) {
removeGroundItem(groundItem as GroundItem)
sendDialogue(player, "This knife doesn't seem sturdy enough to have killed Lord Sinclair.")
}
return@on true
}
else -> {
sendDialogue(player, "You need the guards' permission to do that.")
return@on true
}
}
}
on(Items.PUNGENT_POT_1812, GROUNDITEM, "take") { player, groundItem ->
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
1 -> {
if (inInventory(player, Items.PUNGENT_POT_1812)) {
sendDialogue(player, "I already have the poisoned pot.")
} else if (addItem(player, Items.PUNGENT_POT_1812)) {
removeGroundItem(groundItem as GroundItem)
sendDialogue(player, "It seems like Lord Sinclair was drinking from this before he died.")
}
return@on true
}
else -> {
sendDialogue(player, "You need the guards' permission to do that.")
return@on true
}
}
}
on(intArrayOf(Scenery.STURDY_WOODEN_GATE_2664, Scenery.STURDY_WOODEN_GATE_2665), SCENERY, "investigate") { player, _ ->
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
1 -> {
sendDialogue(player, "As you approach the gate the guard dog starts barking loudly at you. There is no way an intruder could have committed the murder. It must have been someone the dog knew to get past it quietly.")
setAttribute(player, attributeNoiseClue, true)
return@on true
}
else -> {
sendDialogue(player, "You need the guards' permission to do that.")
return@on true
}
}
}
on(Scenery.SMASHED_WINDOW_26110, SCENERY, "investigate") { player, _ ->
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
1 -> {
sendDialogue(player, "Some thread seems to have been caught on a loose nail on the window.")
if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) {
sendMessage(player, "You have already taken the thread.")
}
else if (getAttribute(player, attributeTakenThread, false)) {
if (hasSpaceFor(player, Item(Items.CRIMINALS_THREAD_1808))) {
when (getAttribute(player, attributeRandomMurderer, 0)) {
1, 2 -> addItem(player, Items.CRIMINALS_THREAD_1808)
0, 3 -> addItem(player, Items.CRIMINALS_THREAD_1809)
else -> addItem(player, Items.CRIMINALS_THREAD_1810)
}
sendMessage(player, "Lucky for you there's some thread left. You should be less careless in the future.")
}
}
else {
if (hasSpaceFor(player, Item(Items.CRIMINALS_THREAD_1808))) {
when (getAttribute(player, attributeRandomMurderer, 0)) {
1, 2 -> addItem(player, Items.CRIMINALS_THREAD_1808)
0, 3 -> addItem(player, Items.CRIMINALS_THREAD_1809)
else -> addItem(player, Items.CRIMINALS_THREAD_1810)
}
sendMessage(player, "You take the thread.")
setAttribute(player, attributeTakenThread, true)
}
}
return@on true
}
else -> {
sendDialogue(player, "You need the guards' permission to do that.")
return@on true
}
}
}
on(Scenery.SMASHED_WINDOW_26110, SCENERY, "break") { player, _ ->
sendDialogue(player, "You don't want to damage evidence!")
return@on true
}
on(Scenery.SACKS_2663, SCENERY, "investigate") { player, _ ->
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
1 -> {
openDialogue(player, FlypaperDialogue())
return@on true
}
else -> {
sendDialogue(player, "You need the guards' permission to do that.")
return@on true
}
}
}
on(SILVERBARRELS, SCENERY, "search") { player, node ->
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
1 -> {
when (node.id) {
Scenery.ANNA_S_BARREL_2656 -> {
if (inInventory(player, Items.SILVER_NECKLACE_1796) || inInventory(player, Items.SILVER_NECKLACE_1797)) {
sendDialogue(player, "I already have Anna's Necklace.")
}
else if (addItem(player, Items.SILVER_NECKLACE_1796)){
sendDialogue(player, "There's something shiny hidden at the bottom. You take Anna's Silver Necklace.")
}
}
Scenery.BOB_S_BARREL_2657 -> {
if (inInventory(player, Items.SILVER_CUP_1798) || inInventory(player, Items.SILVER_CUP_1799)) {
sendDialogue(player, "I already have Bob's cup.")
}
else if (addItem(player, Items.SILVER_CUP_1798)){
sendDialogue(player, "There's something shiny hidden at the bottom. You take Bob's silver cup.")
}
}
Scenery.CAROL_S_BARREL_2658 -> {
if (inInventory(player, Items.SILVER_BOTTLE_1800) || inInventory(player, Items.SILVER_BOTTLE_1801)) {
sendDialogue(player, "I already have Carol's bottle.")
}
else if (addItem(player, Items.SILVER_BOTTLE_1800)){
sendDialogue(player, "There's something shiny hidden at the bottom. You take Carol's silver bottle.")
}
}
Scenery.DAVID_S_BARREL_2659 -> {
if (inInventory(player, Items.SILVER_BOOK_1802) || inInventory(player, Items.SILVER_BOOK_1803)) {
sendDialogue(player, "I already have David's book.")
}
else if (addItem(player, Items.SILVER_BOOK_1802)){
sendDialogue(player, "There's something shiny hidden at the bottom. You take David's silver book.")
}
}
Scenery.ELIZABETH_S_BARREL_2660 -> {
if (inInventory(player, Items.SILVER_NEEDLE_1804) || inInventory(player, Items.SILVER_NEEDLE_1805)) {
sendDialogue(player, "I already have Elizabeth's Needle.")
}
else if (addItem(player, Items.SILVER_NEEDLE_1804)){
sendDialogue(player, "There's something shiny hidden at the bottom. You take Elizabeth's silver needle.")
}
}
Scenery.FRANK_S_BARREL_2661 -> {
if (inInventory(player, Items.SILVER_POT_1806) || inInventory(player, Items.SILVER_POT_1807)) {
sendDialogue(player, "I already have Frank's pot.")
}
else if (addItem(player, Items.SILVER_POT_1806)){
sendDialogue(player, "There's something shiny hidden at the bottom. You take Frank's silver pot.")
}
}
}
return@on true
}
else -> {
sendDialogue(player, "You need the guards' permission to do that.")
return@on true
}
}
}
on(POISONSPOTS, SCENERY, "investigate") { player, node ->
when (node.id) {
Scenery.SINCLAIR_FAMILY_COMPOST_HEAP_26120 -> {
if (!getAttribute(player, attributeAskPoisonAnna, false)) {
sendDialogue(player, "It's a heap of compost.")
}
else if (getAttribute(player, attributeRandomMurderer, 0) == 0) {
sendDialogue(player, "The compost is teeming with maggots. Somebody should really do something about it. It's certainly clear nobody's used poison here.")
setAttribute(player, attributePoisonClue, 2)
}
else {
sendDialogue(player, "There is a faint smell of poison behind the smell of the compost.")
}
}
Scenery.SINCLAIR_FAMILY_BEEHIVE_26121 -> {
if (!getAttribute(player, attributeAskPoisonBob, false)) {
sendDialogue(player, "It's a very old beehive.")
}
else if (getAttribute(player, attributeRandomMurderer, 0) == 1) {
sendDialogue(player, "The beehive buzzes with activity. These bees definitely don't seem poisoned at all.")
setAttribute(player, attributePoisonClue, 2)
}
else {
sendDialogue(player, "The hive is empty. There are a few dead bees and a faint smell of poison.")
}
}
Scenery.SINCLAIR_MANSION_DRAIN_2843 -> {
if (!getAttribute(player, attributeAskPoisonCarol, false)) {
sendDialogue(player, "It's the drains from the kitchen.")
}
else if (getAttribute(player, attributeRandomMurderer, 0) == 2) {
sendDialogue(player, "The drain is totally blocked. It really stinks. No, it REALLY smells bad. It's certainly clear nobody's cleaned it recently.")
setAttribute(player, attributePoisonClue, 2)
}
else {
sendDialogue(player, "The drain seems to have been recently cleaned. You can still smell the faint aroma of poison.")
}
}
Scenery.SPIDERS__NEST_26109 -> {
if (!getAttribute(player, attributeAskPoisonDavid, false)) {
sendDialogue(player, "It looks like a spiders' nest of some kind...")
}
else if (getAttribute(player, attributeRandomMurderer, 0) == 3) {
sendDialogue(player, "There is a spiders' nest here. You estimate there must be at least a few hundred spiders ready to hatch. It's certainly clear nobody's used poison here.")
setAttribute(player, attributePoisonClue, 2)
}
else {
sendDialogue(player, "A faint smell of poison and a few dead spiders is all that remains of the spiders nest.")
}
}
Scenery.SINCLAIR_FAMILY_FOUNTAIN_2654 -> {
if (!getAttribute(player, attributeAskPoisonElizabeth, false)) {
sendDialogue(player, "A fountain with large numbers of insects around the base.")
}
else if (getAttribute(player, attributeRandomMurderer, 0) == 4) {
openDialogue(player, FountainDialogue())
setAttribute(player, attributePoisonClue, 2)
}
else {
sendDialogue(player, "There are a lot of dead mosquitos around the base of the fountain. A faint smell of poison is in the air, but the water seems clean.")
}
}
Scenery.SINCLAIR_FAMILY_CREST_2655 -> {
if (!getAttribute(player, attributeAskPoisonFrank, false)) {
sendDialogue(player, "The Sinclair Family Crest is hung up here.")
}
else if (getAttribute(player, attributeRandomMurderer, 0) == 5) {
sendDialogue(player, "It looks like the Sinclair family crest but it is very dirty. You can barely make it out under all of the grime. It's certainly clear nobody's cleaned it recently.")
setAttribute(player, attributePoisonClue, 2)
}
else {
sendDialogue(player, "The Sinclair family crest. It's shiny and freshly polished and has a slight smell of poison.")
}
}
}
return@on true
}
onUseWith(ITEM, UNDUSTEDEVIDENCE, Items.POT_OF_FLOUR_1933) { player, used, _ ->
when (used.id) {
Items.CRIMINALS_DAGGER_1813 -> {
removeItem(player, used)
addItem(player, Items.CRIMINALS_DAGGER_1814)
sendMessage(player, "You sprinkle a small amount of flour on the murder weapon.")
sendMessage(player, "The murder weapon is now coated with a thin layer of flour.")
}
Items.PUNGENT_POT_1812 -> {
sendMessage(player, "You sprinkle a small amount of flour on the strange smelling pot.")
sendMessage(player, "The surface isn't shiny enough to take a fingerprint from.")
}
Items.SILVER_NECKLACE_1796 -> {
removeItem(player, used)
addItem(player, Items.SILVER_NECKLACE_1797)
sendMessage(player, "You sprinkle the flour on Anna's necklace.")
sendMessage(player, "The necklace is now coated with a thin layer of flour.")
}
Items.SILVER_CUP_1798 -> {
removeItem(player, used)
addItem(player, Items.SILVER_CUP_1799)
sendMessage(player, "You sprinkle the flour on Bob's cup.")
sendMessage(player, "The cup is now coated with a thin layer of flour.")
}
Items.SILVER_BOTTLE_1800 -> {
removeItem(player, used)
addItem(player, Items.SILVER_BOTTLE_1801)
sendMessage(player, "You sprinkle the flour on Carol's bottle.")
sendMessage(player, "The bottle is now coated with a thin layer of flour.")
}
Items.SILVER_BOOK_1802 -> {
removeItem(player, used)
addItem(player, Items.SILVER_BOOK_1803)
sendMessage(player, "You sprinkle the flour on David's book.")
sendMessage(player, "The Book is now coated with a thin layer of flour.")
}
Items.SILVER_NEEDLE_1804 -> {
removeItem(player, used)
addItem(player, Items.SILVER_NEEDLE_1805)
sendMessage(player, "You sprinkle the flour on Elizabeth's needle.")
sendMessage(player, "The Needle is now coated with a thin layer of flour.")
}
Items.SILVER_POT_1806 -> {
removeItem(player, used)
addItem(player, Items.SILVER_POT_1807)
sendMessage(player, "You sprinkle the flour on Frank's pot")
sendMessage(player, "The Pot is now coated with a thin layer of flour.")
}
}
removeItem(player, Items.POT_OF_FLOUR_1933)
addItem(player, Items.EMPTY_POT_1931)
return@onUseWith true
}
onUseWith(ITEM, DUSTEDEVIDENCE, Items.FLYPAPER_1811) { player, used, _ ->
removeItem(player, Items.FLYPAPER_1811)
when (used.id) {
Items.CRIMINALS_DAGGER_1814 -> {
removeItem(player, used)
addItem(player, Items.CRIMINALS_DAGGER_1813)
addItem(player, Items.UNKNOWN_PRINT_1822)
sendMessage(player, "You use the flypaper on the floury dagger.")
sendMessage(player, "You have a clean impression of the murderer's finger prints.")
}
Items.SILVER_NECKLACE_1797 -> {
removeItem(player, used)
addItem(player, Items.SILVER_NECKLACE_1796)
addItem(player, Items.ANNAS_PRINT_1816)
sendMessage(player, "You use the flypaper on the flour covered necklace.")
sendMessage(player, "You have a clean impression of Anna's finger prints.")
}
Items.SILVER_CUP_1799 -> {
removeItem(player, used)
addItem(player, Items.SILVER_CUP_1798)
addItem(player, Items.BOBS_PRINT_1817)
sendMessage(player, "You use the flypaper on the flour covered cup.")
sendMessage(player, "You have a clean impression of Bob's finger prints.")
}
Items.SILVER_BOTTLE_1801 -> {
removeItem(player, used)
addItem(player, Items.SILVER_BOTTLE_1800)
addItem(player, Items.CAROLS_PRINT_1818)
sendMessage(player, "You use the flypaper on the flour covered bottle.")
sendMessage(player, "You have a clean impression of Carol's finger prints.")
}
Items.SILVER_BOOK_1803 -> {
removeItem(player, used)
addItem(player, Items.SILVER_BOOK_1802)
addItem(player, Items.DAVIDS_PRINT_1819)
sendMessage(player, "You use the flypaper on the flour covered book.")
sendMessage(player, "You have a clean impression of David's finger prints.")
}
Items.SILVER_NEEDLE_1805 -> {
removeItem(player, used)
addItem(player, Items.SILVER_NEEDLE_1804)
addItem(player, Items.ELIZABETHS_PRINT_1820)
sendMessage(player, "You use the flypaper on the flour covered needle.")
sendMessage(player, "You have a clean impression of Elizabeth's finger prints.")
}
Items.SILVER_POT_1807 -> {
removeItem(player, used)
addItem(player, Items.SILVER_POT_1806)
addItem(player, Items.FRANKS_PRINT_1821)
sendMessage(player, "You use the flypaper on the flour covered pot.")
sendMessage(player, "You have a clean impression of Frank's finger prints.")
}
}
return@onUseWith true
}
onUseWith(ITEM, SUSPECTPRINTS, Items.UNKNOWN_PRINT_1822) { player, used, with ->
val SUSPECT = when (used.id) {
Items.ANNAS_PRINT_1816 -> "Anna"
Items.BOBS_PRINT_1817 -> "Bob"
Items.CAROLS_PRINT_1818 -> "Carol"
Items.DAVIDS_PRINT_1819 -> "David"
Items.ELIZABETHS_PRINT_1820 -> "Elizabeth"
Items.FRANKS_PRINT_1821 -> "Frank"
else -> "Anna"
}
if (used.id == getAttribute(player, attributeRandomMurderer, 0) + Items.ANNAS_PRINT_1816) {
sendDialogue(player, "The fingerprints are an exact match to $SUSPECT's.")
removeItem(player, with.id)
addItem(player, Items.KILLERS_PRINT_1815)
}
else {
sendDialogue(player, "They don't seem to be the same. I guess that clears $SUSPECT of the crime. You destroy the useless fingerprint.")
removeItem(player, used.id)
}
return@onUseWith true
}
onUseWith(SCENERY, intArrayOf(Items.SILVER_POT_1806, Items.PUNGENT_POT_1812), Scenery.BARREL_OF_FLOUR_26122) { player, _, _ ->
sendDialogue(player, "You probably shouldn't use evidence from a crime scene to keep flour in.")
return@onUseWith true
}
}
}
@@ -0,0 +1,58 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs
@Initializable
class PierreDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, PierreDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return PierreDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.PIERRE_807)
}
}
class PierreDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> npcl("The Guards told me not to talk to anyone.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you at the time of the murder?", 5),
IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)),
IfTopic("Do you know why so much poison was bought recently?", 11, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("Honestly? I think it was Carol.").also { stage++ }
4 -> npcl("I saw her in a huge argument with Lord Sinclair in the library the other day. It was something to do with stolen books. She definitely seemed upset enough to have done it afterwards.").also { stage = END_DIALOGUE }
5 -> npcl("I was in town at the inn. When I got back the house was swarming with guards who told me what had happened. Sorry.").also { stage = END_DIALOGUE }
6 -> npcl("Well, like what?").also { stage++ }
7 -> playerl("Any sounds of a struggle with Lord Sinclair?").also { stage++ }
8 -> npcl("No, I don't remember hearing anything like that.").also { stage++ }
9 -> playerl("How about the guard dog barking at all?").also { stage++ }
10 -> npcl("I hear him bark all the time. It's one of his favourite things to do. I can't say I did the night of the murder though as I wasn't close enough to hear either way.").also { stage = END_DIALOGUE }
11 -> npcl("Well, I know David said that he was going to do something about the spiders' nest that's between the two servants' quarters upstairs.").also { stage++ }
12 -> npcl("He made a big deal about it to Mary the Maid, calling her useless and incompetent. I felt quite sorry for her actually. You'd really have to ask him though.").also { stage = END_DIALOGUE }
}
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
}
}
}
@@ -0,0 +1,58 @@
package content.region.kandarin.quest.murdermystery
import content.data.Quests
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
import core.api.*
import core.game.dialogue.*
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs
@Initializable
class StanfordDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, StanfordDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return StanfordDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.STANFORD_811)
}
}
class StanfordDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
0 -> npcl("Have you no shame? We are all grieving at the moment.").also { stage = END_DIALOGUE }
1 -> when (stage) {
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
2 -> showTopics(
Topic("Who do you think is responsible?", 3),
Topic( "Where were you at the time of the murder?", 5),
IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)),
IfTopic("Do you know why so much poison was bought recently?", 11, getAttribute(player!!, attributePoisonClue, 0) > 0)
)
3 -> npcl("It was Anna. She is seriously unbalanced. She trashed the garden once then tried to blame it on me! I bet it was her. It's just the kind of thing she'd do!").also { stage++ }
4 -> npcl("She really hates me and was arguing with Lord Sinclair about trashing the garden a few days ago.").also { stage = END_DIALOGUE }
5 -> npcl("Right here, by my little shed. It's very cosy to sit and think in.").also { stage = END_DIALOGUE }
6 -> npcl("Not that I remember.").also { stage++ }
7 -> playerl("So no sounds of a struggle between Lord Sinclair and an intruder?").also { stage++ }
8 -> npcl("Not to the best of my recollection.").also { stage++ }
9 -> playerl("How about the guard dog barking?").also { stage++ }
10 -> npcl("Not that I can recall.").also { stage = END_DIALOGUE }
11 -> npcl("Well, Bob mentioned to me the other day he wanted to get rid of the bees in that hive over there. I think I saw him buying poison").also { stage++ }
12 -> npcl("from that poison salesman the other day. I assume it was to sort out those bees. You'd really have to ask him though.").also { stage = END_DIALOGUE }
}
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
}
}
}
@@ -52,6 +52,6 @@ public final class CamelotGuardDialogue extends DialoguePlugin {
@Override
public int[] getIds() {
return new int[] { 812 };
return new int[] { 6183, 6184 };
}
}
@@ -161,7 +161,7 @@ abstract class DialogueFile {
return true
}
else if (validTopics.size == 1) {
val topic = topics[0]
val topic = topics.filter { it.text == validTopics[0] }[0]
if(topic.toStage is DialogueFile) {
val topicFile = topic.toStage as DialogueFile
interpreter!!.dialogue.loadFile(topicFile)