diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json
index 95a7b32de..195f51a94 100644
--- a/Server/data/configs/npc_spawns.json
+++ b/Server/data/configs/npc_spawns.json
@@ -499,6 +499,10 @@
"npc_id": "162",
"loc_data": "{2480,3426,0,1,6}-{2489,3429,0,1,1}-{2480,3431,0,1,0}-{2475,3418,0,1,4}-{2470,3423,0,1,1}"
},
+ {
+ "npc_id": "163",
+ "loc_data": "{2465,9899,0,1,6}-{2477,9896,0,1,6}-{2469,9887,0,1,6}-{2463,9893,0,1,6}"
+ },
{
"npc_id": "166",
"loc_data": "{2450,3480,1,0,1}-{2449,3480,1,0,1}-{2448,3480,1,0,1}-{2440,3488,1,0,4}-{2440,3487,1,0,4}-{2448,3427,1,0,6}-{2448,3424,1,0,6}-{2443,3424,1,0,3}-{2443,3425,1,0,3}"
@@ -1818,14 +1822,30 @@
{
"npc_id": "668",
"loc_data": "{3284,3503,1,1,1}"
- },
+ },
+ {
+ "npc_id": "669",
+ "loc_data": "{2678,3086,1,1,1}"
+ },
{
"npc_id": "670",
- "loc_data": "{2465,3496,0,1,6}"
+ "loc_data": "{2465,3496,0,1,6}-{2466,9896,0,0,6}"
+ },
+ {
+ "npc_id": "671",
+ "loc_data": "{2479,3463,1,1,6}"
+ },
+ {
+ "npc_id": "672",
+ "loc_data": "{2390,3515,1,1,6}"
+ },
+ {
+ "npc_id": "673",
+ "loc_data": "{2464,3495,3,0,6}"
},
{
"npc_id": "674",
- "loc_data": "{3001,3041,0,0,0}"
+ "loc_data": "{3001,3041,0,0,0}-{2954,3025,0,0,0}"
},
{
"npc_id": "675",
diff --git a/Server/src/main/content/global/handlers/item/BookreadOption.java b/Server/src/main/content/global/handlers/item/BookreadOption.java
index 02ad8f1a8..5f087786b 100644
--- a/Server/src/main/content/global/handlers/item/BookreadOption.java
+++ b/Server/src/main/content/global/handlers/item/BookreadOption.java
@@ -60,6 +60,10 @@ public class BookreadOption extends OptionHandler {
return 49610760;
case Items.SLASHED_BOOK_9715:
return 49610761;
+ case Items.GLOUGHS_JOURNAL_785:
+ return 49610762;
+ case Items.TRANSLATION_BOOK_784:
+ return 49610763;
/*case 9004:
return 423943;*/
case 11710:
diff --git a/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java b/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java
index 099ae43b7..de6d7ccba 100644
--- a/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java
+++ b/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java
@@ -1,5 +1,6 @@
package content.global.travel.glider;
+import content.region.kandarin.quest.grandtree.TheGrandTree;
import core.game.component.Component;
import core.game.dialogue.DialoguePlugin;
import core.game.dialogue.FacialExpression;
@@ -7,6 +8,10 @@ import core.game.node.entity.npc.NPC;
import core.plugin.Initializable;
import core.game.node.entity.player.Player;
+import static core.api.ContentAPIKt.isQuestComplete;
+import static core.api.ContentAPIKt.questStage;
+import static core.tools.DialogueConstKt.END_DIALOGUE;
+
/**
* Represents the dialogue plugin used for the captain dalbur npc.
* @author 'Vexia
@@ -54,12 +59,14 @@ public final class CaptainDalburDialogue extends DialoguePlugin {
stage = 1;
break;
case 1:
- npc("If you wish.");
- stage++;
- /*
- * interpreter.sendDialogues(npc, FacialExpression.NORMAL,
- * "I only fly friends of the gnomes!"); stage = 2;
- */
+ if(!isQuestComplete(player, TheGrandTree.questName)){
+ interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "I only fly friends of the gnomes!");
+ stage = END_DIALOGUE;
+ }
+ else {
+ npc("If you wish.");
+ stage++;
+ }
break;
case 2:
end();
diff --git a/Server/src/main/content/global/travel/glider/GliderPlugin.java b/Server/src/main/content/global/travel/glider/GliderPlugin.java
index 70ed2de87..c62e404d9 100644
--- a/Server/src/main/content/global/travel/glider/GliderPlugin.java
+++ b/Server/src/main/content/global/travel/glider/GliderPlugin.java
@@ -1,13 +1,15 @@
package content.global.travel.glider;
+import content.region.kandarin.quest.grandtree.TheGrandTree;
+import core.api.ContentAPIKt;
import core.cache.def.impl.NPCDefinition;
import core.game.component.Component;
-import content.global.travel.glider.Gliders;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.plugin.Plugin;
+import static core.api.ContentAPIKt.isQuestComplete;
/**
* Represents the plugin used for gliders.
@@ -29,8 +31,12 @@ public final class GliderPlugin extends OptionHandler {
@Override
public boolean handle(Player player, Node node, String option) {
- player.getInterfaceManager().open(new Component(138));
- Gliders.sendConfig(node.asNpc(), player);
+ if(isQuestComplete(player, TheGrandTree.questName)){
+ player.getInterfaceManager().open(new Component(138));
+ Gliders.sendConfig(node.asNpc(), player);
+ } else {
+ ContentAPIKt.sendMessage(player,"You must complete The Grand Tree Quest to access the gnome glider.");
+ }
return true;
}
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt
new file mode 100644
index 000000000..ea85f4131
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt
@@ -0,0 +1,48 @@
+package content.region.kandarin.quest.grandtree
+
+import core.api.addItemOrDrop
+import core.api.questStage
+import core.api.sendDialogue
+import core.game.dialogue.DialogueFile
+import core.game.node.item.Item
+import core.tools.END_DIALOGUE
+import org.rs09.consts.Items
+
+class AnitaDialogue : DialogueFile(){
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(questStage(player!!, TheGrandTree.questName)){
+ 60 -> {
+ if(player!!.hasItem(Item(Items.GLOUGHS_KEY_788)) && stage < 12){
+ when(stage){
+ 0 -> npcl("Have you taken that key to Glough yet?").also { stage++ }
+ 1 -> playerl("No, I'm still carrying it around.").also { stage++ }
+ 2 -> npcl("Oh. Please take it to Glough!").also { stage = END_DIALOGUE }
+ }
+ } else {
+ when(stage){
+ 0 -> playerl("Hello there.").also { stage++ }
+ 1 -> npcl("Oh hello, I've seen you with the King.").also { stage++ }
+ 2 -> playerl("Yes, I'm helping him with a problem.").also { stage++ }
+ 3 -> npcl("You must know my boyfriend Glough then?").also { stage++ }
+ 4 -> playerl("Indeed!").also { stage++ }
+ 5 -> npcl("Could you do me a favour?").also { stage++ }
+ 6 -> options("I suppose so.","No, I'm busy.").also { stage++ }
+ 7 -> when(buttonID){
+ 1 -> playerl("I suppose so.").also { stage = 10 }
+ 2 -> playerl("No, I'm busy.").also { stage = END_DIALOGUE }
+ }
+ 10 -> playerl("I suppose so.").also { stage++ }
+ 11 -> npcl("Please give this key to Glough, he left it here last night.").also { stage++ }
+ 12 -> sendDialogue(player!!, "Anita gives you a key.").also {
+ addItemOrDrop(player!!, Items.GLOUGHS_KEY_788)
+ stage++
+ }
+ 13 -> npcl("Thanks a lot.").also { stage++ }
+ 14 -> playerl("No... thank you!").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt
new file mode 100644
index 000000000..05d62d989
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt
@@ -0,0 +1,87 @@
+package content.region.kandarin.quest.grandtree
+
+import content.region.misthalin.dorgeshuun.quest.thelosttribe.LostTribeCutscene
+import core.api.openDialogue
+import core.api.sendChat
+import core.api.sendDialogue
+import core.api.sendMessage
+import core.game.activity.Cutscene
+import core.game.dialogue.FacialExpression
+import core.game.node.entity.player.Player
+import core.game.world.map.Direction
+import core.game.world.map.Location
+import core.game.global.action.DoorActionHandler
+import core.game.node.entity.npc.NPC
+import org.rs09.consts.NPCs
+
+class BlackDemonCutscene(player: Player) : Cutscene(player) {
+ override fun setup() {
+ setExit(Location.create(2491, 9864, 0))
+ if(player.settings.isRunToggled){
+ player.settings.toggleRun()
+ }
+ loadRegion(9882)
+ addNPC(NPCs.GLOUGH_671, 48, 8, Direction.WEST)
+ addNPC(NPCs.BLACK_DEMON_677, 43, 9, Direction.EAST)
+ }
+
+ override fun runStage(stage: Int) {
+ when(stage)
+ {
+ 0 -> {
+ fadeToBlack()
+ timedUpdate(6)
+ }
+ 1 -> {
+ fadeFromBlack()
+ teleport(player, 59, 8)
+ moveCamera(55, 8)
+ rotateCamera(0, 0)
+ sendChat(player, "Hello?")
+ player.face(getNPC(NPCs.GLOUGH_671)!!)
+ timedUpdate(3)
+ }
+ 2 -> {
+ moveCamera(48, 8)
+ sendChat(player, "Anybody?")
+ timedUpdate(3)
+ }
+ 3 -> {
+ sendChat(player, "Glough?")
+ move(getNPC(NPCs.GLOUGH_671)!!, 52, 8)
+ timedUpdate(10)
+ }
+ 4 -> {
+ moveCamera(55, 4,2000)
+ rotateCamera(55, 6)
+ timedUpdate(4)
+ }
+ 5 -> {
+ move(player, 53, 8)
+ playerDialogueUpdate(FacialExpression.SCARED, "Glough?")
+ }
+ 6 -> {
+ dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "You really are becoming a headache! Well, at least now you can die knowing you were right, it will save me having to hunt you down like all the other human filth of RuneScape!")
+ }
+ 7 -> {
+ playerDialogueUpdate(FacialExpression.SCARED, "You're crazy, Glough!")
+ }
+ 8 -> {
+ dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "Bah! Well, soon you'll see, the gnomes are ready to fight. In three weeks this tree will be dead wood, in ten weeks it will be 30 battleships! Finally we will rid the world of the disease called humanity!")
+ }
+ 9 -> {
+ playerDialogueUpdate(FacialExpression.SCARED, "What makes you think I'll let you get away with it?")
+ }
+ 10 -> {
+ moveCamera(47,9)
+ rotateCamera(40, 9)
+ dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "Fool...meet my little friend!")
+ }
+ 11 -> {
+ end{
+ BlackDemonNPC(NPCs.BLACK_DEMON_677, Location.create(2485, 9864, 0)).init();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt
new file mode 100644
index 000000000..d57351a7f
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt
@@ -0,0 +1,34 @@
+package content.region.kandarin.quest.grandtree
+
+import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName
+import core.api.*
+import core.game.node.entity.Entity
+import core.game.node.entity.npc.AbstractNPC
+import core.game.node.entity.player.Player
+import core.game.world.map.Location
+import core.plugin.Initializable
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+import core.game.interaction.InteractionListener
+
+@Initializable
+class BlackDemonNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location), InteractionListener {
+
+ override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC {
+ return BlackDemonNPC(id, location)
+ }
+
+ override fun getIds(): IntArray {
+ return intArrayOf(NPCs.BLACK_DEMON_677)
+ }
+
+ override fun defineListeners() {
+ }
+
+ override fun finalizeDeath(killer: Entity?) {
+ // In the event that this npcID is used somewhere else...
+ if(killer!!.asPlayer().location.regionId == 9882)
+ setQuestStage(killer!!.asPlayer(), questName, 98)
+ super.finalizeDeath(killer)
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt
new file mode 100644
index 000000000..29853c9d0
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt
@@ -0,0 +1,78 @@
+package content.region.kandarin.quest.grandtree
+
+import content.global.travel.glider.Gliders
+import core.api.questStage
+import core.api.setQuestStage
+import core.api.teleport
+import core.game.component.Component
+import core.game.dialogue.DialogueFile
+import core.game.world.map.Location
+import core.tools.END_DIALOGUE
+
+class CaptainErrdoDialogue: DialogueFile(){
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(questStage(player!!, TheGrandTree.questName)){
+ 55 -> {
+ if(player!!.location.regionId == 11567){
+ when(stage){
+ 0 -> npcl("Sorry about that.").also { stage++ }
+ 1 -> npcl("That turbulence over the Karamja Volcano was a bit unexpected, and the area round here isn't well suited for emergency landing.").also { stage++ }
+ 2 -> npcl("Still! we're still alive that's the main thing. Are you okay?").also { stage++ }
+ 3 -> playerl("I'm fine, I can't say the same for your glider!").also { stage++ }
+ 4 -> npcl("I don't think I can fix this. Looks like we'll be heading back by foot. I might see if I can find Penwie while I'm here, I believe he's charting the area.").also { stage++ }
+ 5 -> playerl("Where's the shipyard from here?").also { stage++ }
+ 6 -> npcl("I think I saw some buildings on the coast east of here while we were crashing. I'd have a look there.").also { stage++ }
+ 7 -> npcl("Take care adventurer!").also { stage++ }
+ 8 -> playerl("Take care little man.").also { stage = END_DIALOGUE }
+ }
+ } else if (player!!.location.regionId == 9782){
+ when(stage){
+ 0 -> npcl("Hi. The king said that you need to leave?").also { stage++ }
+ 1 -> playerl("Apparently, humans are invading!").also { stage++ }
+ 2 -> npcl("I find that hard to believe. I have lots of human friends.").also { stage++ }
+ 3 -> playerl("I don't understand it either!").also { stage++ }
+ 4 -> npcl("So, where to?").also { stage++ }
+ 5 -> options("Take me to Karamja please!", "Not anywhere for now!").also { stage++ }
+ 6 -> when(buttonID){
+ 1 -> playerl("Take me to Karamja, please.").also { stage++ }
+ 2 -> playerl("Not anywhere for now.").also { stage = 10 }
+ }
+ 7 -> npcl("Okay, you're the boss! Hold on tight, it'll be a rough ride.").also {
+ teleport(player!!, Location.create(2917, 3054, 0))
+ stage = END_DIALOGUE
+ }
+ 10 -> npcl("Okay. I'll be here for when you're ready.").also { stage = END_DIALOGUE }
+ }
+ } else {
+ // We are talking to another gnome outside the stronghold during the quest.
+ when(stage) {
+ 0 -> playerl("May you fly me somewhere on your glider?").also { stage++ }
+ 1 -> npcl("I only fly friends of the gnomes!").also {
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ }
+ 100 -> {
+ when(stage){
+ 0 -> playerl("May you fly me somewhere on your glider?").also { stage++ }
+ 1 -> npcl("If you wish.").also {
+ stage = END_DIALOGUE
+ player!!.interfaceManager.open(Component(138))
+ Gliders.sendConfig(npc, player);
+
+ }
+ }
+ }
+ else -> {
+ when(stage){
+ 0 -> playerl("May you fly me somewhere on your glider?").also { stage++ }
+ 1 -> npcl("I only fly friends of the gnomes!").also {
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt
new file mode 100644
index 000000000..ebc7e024e
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt
@@ -0,0 +1,128 @@
+package content.region.kandarin.quest.grandtree
+
+import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName
+import content.region.misthalin.varrock.quest.familycrest.doDoor
+import core.api.*
+import core.game.dialogue.DialogueFile
+import core.game.dialogue.FacialExpression
+import core.game.global.action.DoorActionHandler
+import core.game.node.entity.npc.NPC
+import core.game.node.item.Item
+import core.game.node.scenery.SceneryBuilder
+import core.game.system.task.Pulse
+import core.game.world.GameWorld
+import core.game.world.map.Direction
+import core.game.world.map.Location
+import core.game.world.update.flag.context.Animation
+import core.tools.END_DIALOGUE
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+import org.rs09.consts.Scenery
+
+class CharlieDialogue : DialogueFile() {
+
+ override fun handle(componentID: Int, buttonID: Int) {
+ when (questStage(player!!, questName)) {
+ 46 -> {
+ when (stage) {
+ 0 -> playerl("Tell me. Why would you want to kill the Grand Tree?").also { stage++ }
+ 1 -> npcl("What do you mean?").also { stage++ }
+ 2 -> playerl("Don't tell me, you just happened to be caught carrying Daconia rocks!").also { stage++ }
+ 3 -> npcl("All I know is that I did what I was asked.").also { stage++ }
+ 4 -> playerl("I don't understand.").also { stage++ }
+ 5 -> npcl("Glough paid me to go to this gnome on a hill. I gave the gnome a seal and he gave me some Daconia rocks to give to Glough.").also { stage++ }
+ 6 -> npcl("I've been doing it for weeks, this time though Glough locked me up here! I just don't understand it.").also { stage++ }
+ 7 -> playerl("Sounds like Glough is hiding something.").also { stage++ }
+ 8 -> npcl("I don't know what he's up to. If you want to find out, you'd better search his home.").also { stage++ }
+ 9 -> playerl("OK. Thanks Charlie.").also { stage++ }
+ 10 -> npcl("Good luck!").also {
+ setQuestStage(player!!, questName, 47)
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ 47 -> {
+ when (stage) {
+ 0 -> npcl("Hello adventurer. Have you figured out what's going on?").also { stage++ }
+ 1 -> playerl("No idea.").also { stage++ }
+ 2 -> npcl("To get to the bottom of this you'll need to search Glough's home.").also { stage = END_DIALOGUE }
+ }
+ }
+ 50 -> {
+ when(stage) {
+ 0 -> npcl("So they got you as well?").also { stage++ }
+ 1 -> playerl("It's Glough! He's trying to cover something up.").also { stage++ }
+ 2 -> npcl("I shouldn't tell you this adventurer. But if you want to get to the bottom of this you should go and talk to the Karamja Shipyard foreman.").also { stage++ }
+ 3 -> playerl("Why?").also { stage++ }
+ 4 -> npcl("Glough sent me to Karamja to meet him. I delivered a large amount of gold. For what? I don't know. He may be able to tell you what Glough's up to. That's if you can get out of here. You'll find him").also { stage++ }
+ 5 -> npcl("in the Karamja Shipyard, east of Shilo Village. Be careful! If he discovers you're not working for Glough, there'll be trouble! The sea men use the password Ka-Lu-Min.").also { stage++ }
+ 6 -> playerl("Thanks Charlie!").also {
+ stage = END_DIALOGUE
+ GameWorld.Pulser.submit(object : Pulse(0) {
+ var count = 0
+ val npc = NPC.create(NPCs.KING_NARNODE_SHAREEN_670, Location.create(2467, 3496, 3), null)
+ override fun pulse(): Boolean {
+ when (count) {
+ 0 -> {
+ // Spawn in narnode
+ npc.init();
+ lock(player!!,10)
+ forceWalk(npc, player!!.location.transform(Direction.EAST, 2), "SMART")
+ }
+
+ 2 -> {
+ sendNPCDialogue(player!!, npc.id,"Traveller please accept my apologies! Glough had no right to arrest you! I just think he's scared of humans. Let me get you out of there.")
+ }
+
+ 4 -> {
+ DoorActionHandler.handleAutowalkDoor(player!!,
+ getScenery(2465,3496,3)
+ )
+ openDialogue(player!!,KingNarnodeUpstairsDialogue(), npc)
+ }
+ 8 -> {
+ unlock(player!!)
+ npc.clear();
+ setQuestStage(player!!, questName, 55)
+ return true;
+ }
+ }
+ count++
+ return false
+ }
+ })
+ }
+ }
+ }
+ 55 -> {
+ if(player!!.hasItem(Item(Items.LUMBER_ORDER_787))){
+ when(stage) {
+ 0 -> playerl("How are you doing Charlie?").also { stage++ }
+ 1 -> npcl("I've been better.").also { stage++ }
+ 2 -> playerl("Glough has some plan to rule RuneScape!").also { stage++ }
+ 3 -> npcl("I wouldn't put it past him, the Gnome's crazy!").also { stage++ }
+ 4 -> playerl("I need some proof to convince the King.").also { stage++ }
+ 5 -> npcl("Hmm...you could be in luck! Before Glough had me locked up I heard him mention that he'd left his chest keys at his girlfriend's.").also { stage++ }
+ 6 -> playerl("Where does she live?").also { stage++ }
+ 7 -> npcl("Just west of the toad swamp.").also { stage++ }
+ 8 -> playerl("OK, I'll see what I can find.").also {
+ setQuestStage(player!!, questName, 60)
+ stage = END_DIALOGUE
+ }
+ }
+ } else {
+ when(stage) {
+ 0 -> playerl("I can't figure this out Charlie!").also { stage++ }
+ 1 -> npcl("Go and see the foreman in the Karamja jungle, there's a shipyard there, you might find some clues. Don't forget the password is Ka-Lu-Min;").also { stage++ }
+ 2 -> npcl("Tf they realise that you're not working for Glough there'll be trouble!").also { stage = END_DIALOGUE }
+
+ }
+ }
+ } else -> {
+ when(stage){
+ 0 -> sendDialogue(player!!, "The prisoner is in no mood to talk.").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt b/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt
new file mode 100644
index 000000000..841cc8599
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt
@@ -0,0 +1,143 @@
+package content.region.kandarin.quest.grandtree
+
+import core.api.*
+import core.game.component.Component
+import core.game.dialogue.DialogueFile
+import core.game.interaction.IntType
+import core.game.node.entity.Entity
+import core.game.node.entity.npc.AbstractNPC
+import core.game.node.entity.player.Player
+import core.game.world.map.Location
+import core.plugin.Initializable
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+import core.game.interaction.InteractionListener
+import core.game.interaction.MovementPulse
+import core.game.node.entity.impl.PulseType
+import core.game.node.entity.npc.NPC
+import core.game.system.task.Pulse
+import core.game.world.GameWorld
+import core.game.world.map.Direction
+import core.game.world.map.RegionManager
+import core.game.world.map.path.Pathfinder
+import core.tools.END_DIALOGUE
+import org.rs09.consts.Components
+
+@Initializable
+class ForemanNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location), InteractionListener {
+
+ override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC {
+ return ForemanNPC(id, location)
+ }
+
+ override fun getIds(): IntArray {
+ return intArrayOf(NPCs.FOREMAN_674)
+ }
+
+ override fun defineListeners() {
+ on(this.ids, IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, ForemanDialogue(), npc)
+ return@on true;
+ }
+ }
+
+ override fun finalizeDeath(killer: Entity?) {
+ if(questStage(killer as Player, TheGrandTree.questName) == 55) {
+ sendMessage(killer,"The foreman drops a piece of paper as he dies.")
+ produceGroundItem(killer, Items.LUMBER_ORDER_787, 1, this.location)
+ }
+ super.finalizeDeath(killer)
+ }
+}
+
+class ForemanDialogue: DialogueFile(){
+ private fun attackPlayer(){
+ val foreman = RegionManager.getNpc(player!!.location, NPCs.FOREMAN_674, 6)
+ foreman!!.attack(player!!)
+ }
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(stage){
+ 0 -> playerl("Hello, are you in charge?").also { stage++ }
+ 1 -> npcl("That's right, and you are...?").also { stage++ }
+ 2 -> playerl("Glough sent me to check on how you are doing.").also { stage++ }
+ 3 -> npcl("Right. Glough sent a human?").also { stage++ }
+ 4 -> playerl("His gnomes are busy.").also { stage++ }
+ 5 -> npcl("Hmm...in that case we'd better go to my office. Follow me.").also {
+ val foremanOffice = Location.create(2954, 3024, 0);
+ GameWorld.Pulser.submit(object : Pulse(0) {
+ var count = 0
+ override fun pulse(): Boolean {
+ when (count) {
+ 0 -> {
+ player!!.interfaceManager.closeOverlay()
+ player!!.interfaceManager.openOverlay(Component(Components.FADE_TO_BLACK_120))
+ }
+ 2 -> {
+ teleport(player!!,foremanOffice)
+ player!!.interfaceManager.closeOverlay()
+ player!!.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170))
+ return true
+ }
+ }
+ count++
+ return false
+ }
+ })
+ stage++;
+ }
+ 6 -> npcl("Tell me again why you're here.").also { stage++ }
+ 7 -> playerl("Er...Glough sent me?").also { stage++ }
+ 8 -> npcl("By the way how is Glough? Still with his wife?").also { stage++ }
+ 9 -> options("Yes, they're getting on great.","Always arguing as usual!","Sadly his wife is no longer with us!").also { stage++ }
+ 10 -> when(buttonID){
+ 1 -> playerl("Yes, they're getting on great.").also { stage++ }
+ 2 -> playerl("Always arguing as usual!").also { stage++ }
+ 3 -> playerl("Sadly his wife is no longer with us!").also { stage = 20 }
+ }
+ 11 -> npcl("Really? That's odd, considering she died last year. Die imposter!").also {
+ attackPlayer()
+ stage = END_DIALOGUE
+ }
+ 20 -> npcl("Right answer. I have to watch for imposters. What's Glough's favourite dish?").also { stage++ }
+ 21 -> options("He loves tangled toads legs.","He loves worm holes.","He loves choc bombs.").also { stage++ }
+ 22 -> when(buttonID){
+ 1 -> playerl("He loves tangled toads legs.").also { stage++ }
+ 2 -> playerl("He loves worm holes.").also { stage = 30 }
+ 3 -> playerl("He loves choc bombs.").also { stage++ }
+ }
+ 23 -> npcl("Our survey said.... Bzzzzzz! Wrong answer!").also {
+ attackPlayer()
+ stage = END_DIALOGUE
+ }
+ 30 -> npcl("OK. Just one more. What's the name of his new girlfriend?").also { stage++ }
+ 31 -> options("Anita.","Alia.","Elena.").also { stage++ }
+ 32 -> when(buttonID){
+ 1 -> playerl("Anita.").also { stage = 35 }
+ 2 -> playerl("Alia.").also { stage++ }
+ 3 -> playerl("Elena.").also { stage++ }
+ }
+ 33 -> npcl("You almost had me fooled! Die imposter!").also {
+ attackPlayer()
+ stage = END_DIALOGUE
+ }
+ 35 -> npcl("Well, well, you do know Glough. Sorry for the interrogation but I'm sure you understand.").also { stage++ }
+ 36 -> playerl("Of course, security is paramount.").also { stage++ }
+ 37 -> npcl("As you can see things are going well.").also { stage++ }
+ 38 -> playerl("Indeed.").also { stage++ }
+ 39 -> npcl("When I was asked to build a fleet large enough to invade Port Sarim and carry 300 gnome troops I said: 'If anyone can, I can.'").also { stage++ }
+ 40 -> playerl("That's a lot of troops!").also { stage++ }
+ 41 -> npcl("True but if the gnomes are really going to take over RuneScape they'll need at least that.").also { stage++ }
+ 42 -> playerl("Take over?").also { stage++ }
+ 43 -> npcl("Of course, why else would Glough want 30 battleships? Between you and me I don't think he stands a chance.").also { stage++ }
+ 44 -> playerl("No?").also { stage++ }
+ 45 -> npcl("I mean, for the kind of battleships Glough's ordered I'll need tons and tons of limber! Still, if he says he can supply the wood I'm sure he can! Anyway, here's the order for the lumber.").also { stage++ }
+ 46 -> sendDialogue(player!!, "The Foreman gives you the Lumber order.").also {
+ addItemOrDrop(player!!,Items.LUMBER_ORDER_787)
+ stage++
+ }
+ 47 -> playerl("OK. I'll head off and give this order to Glough.").also {
+ stage = END_DIALOGUE
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt
new file mode 100644
index 000000000..91d8399d2
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt
@@ -0,0 +1,126 @@
+package content.region.kandarin.quest.grandtree
+
+import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName
+import core.api.*
+import core.game.dialogue.DialogueFile
+import core.game.dialogue.FacialExpression
+import core.game.interaction.MovementPulse
+import core.game.node.entity.impl.PulseType
+import core.game.node.entity.npc.NPC
+import core.game.node.item.Item
+import core.game.node.scenery.Scenery
+import core.game.node.scenery.SceneryBuilder
+import core.game.system.task.Pulse
+import core.game.world.GameWorld
+import core.game.world.map.Direction
+import core.game.world.map.Location
+import core.game.world.map.RegionManager
+import core.game.world.map.path.Pathfinder
+import core.game.world.update.flag.context.Animation
+import core.tools.END_DIALOGUE
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+
+class GloughDialogue : DialogueFile() {
+
+ override fun handle(componentID: Int, buttonID: Int) {
+ when (questStage(player!!, questName)) {
+ 40 -> {
+ when (stage) {
+ 0 -> playerl("Hello.").also { stage++ }
+ 1 -> sendDialogue(player!!,"The gnome is munching on a worm hole.").also { stage++ }
+ 2 -> npcl("Can I help human? Can't you see I'm eating?!").also { stage++ }
+ 3 -> sendDialogue(player!!,"The gnome continues to eat.").also { stage++ }
+ 4 -> playerl("The King asked me to inform you that the Daconia rocks have been taken!").also { stage++ }
+ 5 -> npcl("Surely not!").also { stage++ }
+ 6 -> playerl("Apparently a human took them from Hazelmere. Hazelmere believed him; he had the King's seal!").also { stage++ }
+ 7 -> npcl("I should've known! The humans are going to invade!").also { stage++ }
+ 8 -> playerl("Never!").also { stage++ }
+ 9 -> npcl("Your type can't be trusted! I'll take care of this! Go back to the King.").also {
+ setQuestStage(player!!, questName, 45)
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ 47 -> {
+ when(stage){
+ 0 -> playerl("Glough! I don't know what you're up to but I know you paid Charlie to get those rocks!").also { stage++ }
+ 1 -> npcl("You're a fool human! You have no idea what's going on.").also { stage++ }
+ 2 -> playerl("I know the Grand Tree's dying! And I think you're part of the reason.").also { stage++ }
+ 3 -> npcl("How dare you accuse me! I'm the head tree guardian! Guards! Guards!").also { stage++ }
+ 4 -> {
+ GameWorld.Pulser.submit(object : Pulse(0) {
+ var count = 0
+ val npc = NPC.create(163,Location.create(2477, 3462, 1), null)
+ val ladderClimbAnimation = Animation(828)
+ val cell = Location.create(2464, 3496, 3);
+ override fun pulse(): Boolean {
+ when (count) {
+ 0 -> {
+ // Spawn in the gnome guard
+ lock(player!!, 10)
+ npc.init();
+ forceWalk(npc, player!!.location.transform(Direction.WEST,2), "SMART")
+ player!!.dialogueInterpreter.sendDialogues(npc, FacialExpression.ANNOYED, "Come with me!")
+ }
+ 2 -> {
+ // Walk to the ladder
+ forceWalk(npc, Location.create(2476, 3462, 1), "SMART")
+ }
+ 4 -> {
+ unlock(player!!)
+ forceWalk(player!!, Location.create(2477, 3463, 1), "SMART")
+ }
+ 6 -> {
+ player!!.faceLocation(Location.create(2476, 3463, 1))
+ }
+ 7 -> {
+ player!!.animator.animate(ladderClimbAnimation)
+ }
+ 8 -> {
+ npc.clear();
+ setQuestStage(player!!, questName, 50)
+ teleport(player!!, cell)
+ player!!.unlock()
+ return true;
+ }
+ }
+ count++
+ return false
+ }
+ }).also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ 55 -> {
+ when(stage){
+ 0 -> playerl("I know what you're up to Glough!").also { stage++ }
+ 1 -> npcl("You have no idea human!").also { stage++ }
+ 2 -> playerl("You may be able to make a fleet but the tree gnomes will never follow you into battle against humans.").also { stage++ }
+ 3 -> npcl("So, you know more than I thought! The gnomes fear humanity more than any other race. I just need to give them a push in the right direction. There's nothing you can do traveller! Leave before it's too late!").also { stage++ }
+ 4 -> playerl("King Narnode won't allow it!").also { stage++ }
+ 5 -> npcl("The King's a fool and a coward! He'll bow to me! You'll soon be back in that cage!").also { stage = END_DIALOGUE }
+ }
+ }
+ 60 -> {
+ when(stage){
+ 0 -> playerl("I'm going to stop you, Glough!").also { stage++ }
+ 1 -> npcl("You're becoming quite annoying traveller!").also { stage++ }
+ 2 -> npcl("Glough is searching his pockets.").also { stage++ }
+ 3 -> npcl("Where are that darn key?").also { stage++ }
+ 4 -> npcl("Leave human, before I have you put in the cage!").also { stage = END_DIALOGUE }
+ }
+ }
+ else -> {
+ when (stage) {
+ 0 -> playerl("Hello there!").also { stage++ }
+ 1 -> npcl("You shouldn't be here human!").also { stage++ }
+ 2 -> playerl("What do you mean?").also { stage++ }
+ 3 -> npcl("The Gnome Stronghold is for gnomes alone!").also { stage++ }
+ 4 -> playerl("Surely not!").also { stage++ }
+ 5 -> npcl("We don't need your sort round here!").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GloughsJournal.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GloughsJournal.kt
new file mode 100644
index 000000000..d517cc1f3
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/GloughsJournal.kt
@@ -0,0 +1,164 @@
+package content.region.kandarin.seers.quest.elementalworkshop
+
+import core.api.setQuestStage
+import core.game.dialogue.DialoguePlugin
+import core.game.dialogue.book.Book
+import core.game.dialogue.book.BookLine
+import core.game.dialogue.book.Page
+import core.game.dialogue.book.PageSet
+import core.game.node.entity.player.Player
+import core.plugin.Initializable
+import org.rs09.consts.Items
+
+/**
+ * Gloughs Journal book handler for The Grand Tree quest
+ *
+ * @author crop & szu
+ */
+@Initializable
+class GloughsJournal : Book {
+
+ constructor(player: Player?) : super(player, "Glough's Journal", Items.GLOUGHS_JOURNAL_785, *arrayOf(
+ PageSet(
+ Page(
+ BookLine("
The migration failed!", 55),
+ BookLine("After spending half", 56),
+ BookLine("a century hiding", 57),
+ BookLine("underground you", 58),
+ BookLine("you would think", 59),
+ BookLine("that the great", 60),
+ BookLine("migration would have", 61),
+ BookLine("improved life on", 62),
+ BookLine("Gielinor for tree gnomes.", 63),
+ BookLine("However, rather", 64),
+ BookLine("than the great liberation", 65),
+ ),
+ Page(
+ BookLine("promised to us by", 65),
+ BookLine("King Healthorg at the", 66),
+ BookLine("end of the last age,", 67),
+ BookLine("we have been forced", 68),
+ BookLine("to live in hiding,", 69),
+ BookLine("up trees or in the", 70),
+ BookLine("gnome maze, laughed", 71),
+ BookLine("at and mocked by man.", 72),
+ BookLine("Living in constant", 73),
+ BookLine("fear of human aggression", 74),
+ BookLine("we are in a no better", 75),
+ )
+ ),
+ PageSet(
+ Page(
+ BookLine("we are in a no better", 55),
+ BookLine("situation now than", 56),
+ BookLine("when we lived", 57),
+ BookLine("in the caves!", 58),
+ BookLine("Change must come soon!", 59),
+ BookLine("They must be stopped!", 60),
+ BookLine("Today I heard of three", 61),
+ BookLine("more gnomes slain", 62),
+ BookLine("by Khazard's human", 63),
+ BookLine("troops for fun,", 64),
+ BookLine("I can't control", 65),
+ ),
+ Page(
+ BookLine("my anger!", 66),
+ BookLine("Humanity seems to", 67),
+ BookLine("have acquired a", 68),
+ BookLine("level of arrogance", 69),
+ BookLine("comparable to that", 70),
+ BookLine("of Zamorak, killing", 71),
+ BookLine("and pillaging at will!", 72),
+ BookLine("We are small and at", 73),
+ BookLine("heart not warriors", 74),
+ BookLine("but something must", 75),
+ )
+ ),
+ PageSet(
+ Page(
+ BookLine("be done! We will", 55),
+ BookLine("pick up arms and", 56),
+ BookLine("go forth into the", 57),
+ BookLine("human world! We will", 58),
+ BookLine("defend ourselves and", 59),
+ BookLine("we will pursue justice", 60),
+ BookLine("for all gnomes who", 61),
+ BookLine("fell at the hands", 62),
+ BookLine("of humans!", 63),
+ BookLine("Gaining support.", 64),
+ BookLine("", 65),
+ ),
+ Page(
+ BookLine("Some of the local", 66),
+ BookLine("gnomes seem strangely", 67),
+ BookLine("deluded about humans,", 68),
+ BookLine("many actually believe", 69),
+ BookLine("that humans are not", 70),
+ BookLine("all naturally evil", 71),
+ BookLine("but instead vary", 72),
+ BookLine("from person to person.", 73),
+ BookLine("This sort of talk", 74),
+ BookLine("could be the end", 75),
+ )
+ ),
+ PageSet(
+ Page(
+ BookLine("for the tree gnomes", 55),
+ BookLine("and I must continue", 56),
+ BookLine("to convince my fellow", 57),
+ BookLine("gnome folk the cold", 58),
+ BookLine("truth about these", 59),
+ BookLine("human creatures!", 60),
+ BookLine("How they will not", 61),
+ BookLine("stop until all gnome", 62),
+ BookLine("life is destroyed!", 63),
+ BookLine("Unless we can ", 64),
+ BookLine("destroy them first!", 65),
+ )
+ )
+ )
+ ) {}
+
+ constructor() {
+ /**
+ * empty.
+ */
+ }
+
+ override fun finish() {
+ }
+
+ override fun display(set: Array) {
+ player.lock()
+ player.interfaceManager.open(getInterface())
+
+ for (i in 55..76) {
+ player.packetDispatch.sendString("", getInterface().id, i)
+ }
+ player.packetDispatch.sendString("", getInterface().id, 77)
+ player.packetDispatch.sendString("", getInterface().id, 78)
+ player.packetDispatch.sendString(getName(), getInterface().id, 6)
+ for (page in set) {
+ for (line in page.lines) {
+ player.packetDispatch.sendString(line.message, getInterface().id, line.child)
+ }
+ }
+ player.packetDispatch.sendInterfaceConfig(getInterface().id, 51, index < 1)
+ val lastPage = index == sets.size - 1
+ player.packetDispatch.sendInterfaceConfig(getInterface().id, 53, lastPage)
+ if (lastPage) {
+ finish()
+ }
+ player.unlock()
+ }
+
+ override fun newInstance(player: Player): DialoguePlugin {
+ return GloughsJournal(player)
+ }
+
+ override fun getIds(): IntArray {
+ // This is all handled in `BookreadOption.java` you need to manually
+ // register a new dialogue key for your file there.
+ return intArrayOf(49610762)
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt
new file mode 100644
index 000000000..c60b9e46f
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt
@@ -0,0 +1,193 @@
+package content.region.kandarin.quest.grandtree
+
+import content.global.handlers.item.BookreadOption
+import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName
+import core.api.*
+import core.game.interaction.IntType
+import core.game.interaction.InteractionListener
+import core.game.node.entity.npc.NPC
+import core.game.node.entity.player.Player
+import core.game.node.item.GroundItemManager
+import core.game.node.item.Item
+import core.game.node.scenery.Scenery
+import core.game.node.scenery.SceneryBuilder
+import core.game.world.map.Location
+import core.game.world.update.flag.context.Animation
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+
+class GrandTreeListeners: InteractionListener {
+
+ val roots = arrayOf(
+ Location(2467,9896,0),
+ Location(2468,9890,0),
+ Location(2465,9891,0),
+ Location(2465,9891,0),
+ Location(2473,9897,0),
+ )
+
+ fun unlockTUZODoor(player: Player) {
+ if (getAttribute(player, "/save:grandtree:twig1", false) &&
+ getAttribute(player, "/save:grandtree:twig2", false) &&
+ getAttribute(player, "/save:grandtree:twig3", false) &&
+ getAttribute(player, "/save:grandtree:twig4", false)
+ ){
+ sendDialogue(player,"With a grinding of machinery, a trapdoor snaps open!")
+ //SceneryBuilder.replace(Scenery(2444, Location(2487,3464,2), 22 , 2), Scenery(2445, Location(2487,3464,2), 22 , 2),20)
+ }
+ }
+
+ override fun defineDestinationOverrides() {
+ setDest(IntType.NPC, intArrayOf(NPCs.CHARLIE_673),"talk-to"){ player, _ ->
+ return@setDest player.location;
+ }
+ }
+
+ override fun defineListeners() {
+ on(NPCs.KING_NARNODE_SHAREEN_670, IntType.NPC, "talk-to"){ player, npc ->
+ val aboveground = 9782;
+ if(player.location.regionId == aboveground)
+ openDialogue(player, KingNarnodeDialogue(), npc)
+ else
+ openDialogue(player, KingNarnodeUnderGroundDialogue(), npc)
+ return@on true
+ }
+ on(NPCs.HAZELMERE_669, IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, HazelmereDialogue(), npc)
+ return@on true
+ }
+ on(NPCs.GLOUGH_671, IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, GloughDialogue(), npc)
+ return@on true
+ }
+ on(intArrayOf(NPCs.SHIPYARD_WORKER_675, NPCs.SHIPYARD_WORKER_38, NPCs.SHIPYARD_WORKER_39), IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, ShipyardWorkerGenericDialogue(), npc)
+ return@on true
+ }
+ on(NPCs.CHARLIE_673, IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, CharlieDialogue(), npc)
+ return@on true
+ }
+ on(NPCs.CAPTAIN_ERRDO_3811, IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, CaptainErrdoDialogue(), npc)
+ return@on true
+ }
+ on(NPCs.ANITA_672, IntType.NPC, "talk-to"){ player, npc ->
+ openDialogue(player, AnitaDialogue(), npc)
+ return@on true
+ }
+ on(2444, IntType.SCENERY, "open"){ player, node ->
+ if(node.location == Location(2487,3464,2) && !isQuestComplete(player, questName)){
+ if(getAttribute(player, "/save:grandtree:twig1", false) &&
+ getAttribute(player, "/save:grandtree:twig2", false) &&
+ getAttribute(player, "/save:grandtree:twig3", false) &&
+ getAttribute(player, "/save:grandtree:twig4", false)){
+ player.animator.animate(Animation(828))
+ BlackDemonCutscene(player).start()
+ }
+ }
+ return@on true;
+ }
+
+ on(2446, IntType.SCENERY, "open"){ player, node ->
+ if(node.location == Location(2463, 3497, 0) && isQuestComplete(player!!, questName)){
+ player.animator.animate(Animation(828))
+ // Go to tunnels
+ teleport(player, Location(2464, 9897, 0))
+ }
+ return@on true;
+ }
+
+ onUseWith(IntType.SCENERY, 788, 2436){ player, used, with ->
+ SceneryBuilder.replace(Scenery(2436, Location(2482,3462,1)),Scenery(2437, Location(2482,3462,1)),2)
+ sendDialogue(player,"You found a scroll!")
+ addItemOrDrop(player, Items.INVASION_PLANS_794)
+ if(questStage(player!!, questName) < 60)
+ setQuestStage(player!!, questName, 60)
+ return@onUseWith true;
+ }
+ onUseWith(IntType.SCENERY, Items.TWIGS_789, 2440){ player, used, with ->
+ setAttribute(player, "/save:grandtree:twig1", true)
+ removeItem(player, used.asItem());
+ GroundItemManager.create(used.asItem(), with.location, player)
+ unlockTUZODoor(player)
+ return@onUseWith true;
+ }
+ onUseWith(IntType.SCENERY, Items.TWIGS_790, 2441){ player, used, with ->
+ setAttribute(player, "/save:grandtree:twig2", true)
+ removeItem(player, used.asItem());
+ GroundItemManager.create(used.asItem(), with.location, player)
+ unlockTUZODoor(player)
+ return@onUseWith true;
+ }
+ onUseWith(IntType.SCENERY, Items.TWIGS_791, 2442){ player, used, with ->
+ setAttribute(player, "/save:grandtree:twig3", true)
+ removeItem(player, used.asItem());
+ GroundItemManager.create(used.asItem(), with.location, player)
+ unlockTUZODoor(player)
+ return@onUseWith true;
+ }
+ onUseWith(IntType.SCENERY, Items.TWIGS_792, 2443){ player, used, with ->
+ setAttribute(player, "/save:grandtree:twig4", true)
+ removeItem(player, used.asItem());
+ GroundItemManager.create(used.asItem(), with.location, player)
+ unlockTUZODoor(player)
+ return@onUseWith true;
+ }
+ // Removing twigs
+ on(Items.TWIGS_789, IntType.GROUNDITEM, "take"){ player, node ->
+ setAttribute(player, "/save:grandtree:twig1", false)
+ return@on true;
+ }
+ on(Items.TWIGS_790, IntType.GROUNDITEM, "take"){ player, node ->
+ setAttribute(player, "/save:grandtree:twig2", false)
+ return@on true;
+ }
+ on(Items.TWIGS_791, IntType.GROUNDITEM, "take"){ player, node ->
+ setAttribute(player, "/save:grandtree:twig3", false)
+ return@on true;
+ }
+ on(Items.TWIGS_792, IntType.GROUNDITEM, "take"){ player, node ->
+ setAttribute(player, "/save:grandtree:twig4", false)
+ return@on true;
+ }
+ on(2435, IntType.SCENERY, "search"){ player, _ ->
+ if(questStage(player, questName) == 47){
+ sendItemDialogue(player, Items.GLOUGHS_JOURNAL_785,"You've found Glough's Journal!")
+ addItemOrDrop(player, Items.GLOUGHS_JOURNAL_785)
+ }
+ return@on true;
+ }
+
+ on(Items.GLOUGHS_JOURNAL_785, IntType.ITEM, "read"){ player, _ ->
+ openDialogue(player, BookreadOption().getDialId(Items.GLOUGHS_JOURNAL_785))
+ return@on true;
+ }
+
+ on(Items.TRANSLATION_BOOK_784, IntType.ITEM, "read"){ player, _ ->
+ openDialogue(player, BookreadOption().getDialId(Items.TRANSLATION_BOOK_784))
+ return@on true;
+ }
+
+ // Roots for Daconia rock
+ on(32319, IntType.SCENERY, "search"){ player, node ->
+ if(questStage(player, questName) < 99 || player.hasItem(Item(Items.DACONIA_ROCK_793))){ return@on true; }
+ // RNG for which root the rock is under
+ if(node.location == roots[getAttribute(player,"grandtree:rock",1)]){
+ sendItemDialogue(player, Item(Items.DACONIA_ROCK_793), "You've found a Daconia rock!")
+ addItemOrDrop(player,Items.DACONIA_ROCK_793)
+ }
+ return@on true;
+ }
+ // Gate Karamja
+ on(2439, IntType.SCENERY, "open"){ player, _ ->
+ openDialogue(player, ShipyardWorkerDialogue(), NPC(NPCs.SHIPYARD_WORKER_675))
+ return@on true;
+ }
+ on(2438, IntType.SCENERY, "open"){ player, _ ->
+ openDialogue(player, ShipyardWorkerDialogue(), NPC(NPCs.SHIPYARD_WORKER_675))
+ return@on true;
+ }
+ }
+}
+
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt
new file mode 100644
index 000000000..f8331207c
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt
@@ -0,0 +1,59 @@
+package content.region.kandarin.quest.grandtree
+
+import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName
+import core.api.*
+import core.game.dialogue.DialogueFile
+import core.game.interaction.MovementPulse
+import core.game.node.entity.impl.PulseType
+import core.game.node.item.Item
+import core.game.node.scenery.Scenery
+import core.game.node.scenery.SceneryBuilder
+import core.game.system.task.Pulse
+import core.game.world.GameWorld
+import core.game.world.map.Direction
+import core.game.world.map.Location
+import core.game.world.map.RegionManager
+import core.game.world.map.path.Pathfinder
+import core.game.world.update.flag.context.Animation
+import core.tools.END_DIALOGUE
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+
+class HazelmereDialogue : DialogueFile() {
+
+ override fun handle(componentID: Int, buttonID: Int) {
+ when (questStage(player!!, questName)) {
+ 10 -> {
+ if(player!!.hasItem(Item(Items.BARK_SAMPLE_783))){
+ when (stage) {
+ 0 -> sendDialogue(player!!,"The mage starts to speak but all you hear is").also { stage++ }
+ 1 -> npcl("Blah. Blah, blah, blah, blah...blah!").also { stage++ }
+ 2 -> sendDialogue(player!!,"You give the bark sample to Hazelmere. The mage carefully examines the sample.").also { stage++ }
+ 3 -> npcl("Blah, blah...Daconia...blah, blah.").also { stage++ }
+ 4 -> playerl("Can you write this down and I'll try and translate it?").also { stage++ }
+ 5 -> npcl("Blah, blah?").also { stage++ }
+ 6 -> sendDialogue(player!!,"You make a writing motion. The mages scribbles something down on a scroll. Hazelmere has given you the scroll.").also {
+ if(removeItem(player!!, Items.BARK_SAMPLE_783)){
+ addItemOrDrop(player!!, Items.HAZELMERES_SCROLL_786)
+ }
+ setQuestStage(player!!, questName, 20)
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ }
+ 20 -> {
+ when (stage) {
+ 0 -> npcl("Blah, blah....Daconia...blah, blah.").also { stage++ }
+ 1 -> sendDialogue(player!!,"You still can't understand Hazelmere. The mage wrote it down for you on a scroll.").also {
+ if(!player!!.hasItem(Item(Items.HAZELMERES_SCROLL_786))){
+ addItemOrDrop(player!!, Items.HAZELMERES_SCROLL_786)
+ }
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ else -> npcl("Blah, blah...blah, blah.").also { stage = END_DIALOGUE }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt
new file mode 100644
index 000000000..609b53751
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt
@@ -0,0 +1,507 @@
+package content.region.kandarin.quest.grandtree
+
+import content.region.kandarin.quest.grandtree.TheGrandTree.Companion.questName
+import core.api.*
+import core.game.dialogue.DialogueFile
+import core.game.interaction.MovementPulse
+import core.game.node.entity.impl.PulseType
+import core.game.node.item.Item
+import core.game.node.scenery.Scenery
+import core.game.node.scenery.SceneryBuilder
+import core.game.system.task.Pulse
+import core.game.world.GameWorld
+import core.game.world.map.Direction
+import core.game.world.map.Location
+import core.game.world.map.RegionManager
+import core.game.world.map.path.Pathfinder
+import core.game.world.update.flag.context.Animation
+import core.tools.END_DIALOGUE
+import org.rs09.consts.Items
+import org.rs09.consts.NPCs
+
+class KingNarnodeDialogue : DialogueFile() {
+
+ val trapdoorLocation = Location(2464,3497,0);
+ val closedTrapDoor = Scenery(2446, Location(2463,3497,0), 22, 0)
+ val openedTrapDoor = Scenery(2445, Location(2463,3497,0), 22, 0)
+ val tunnels = Location(2464, 9897, 0);
+ val ladderClimbAnimation = Animation(828)
+
+ fun leadDownLadder(){
+ // Animate Narnode to walk to the trapdoor and climb the ladder
+ GameWorld.Pulser.submit(object : Pulse(0) {
+ var count = 0
+ override fun pulse(): Boolean {
+ when (count) {
+ 0 -> {
+ forceWalk(player!!, trapdoorLocation, "SMART")
+ lock(player!!,10)
+ npc!!.pulseManager.run(object : MovementPulse(npc, player, Pathfinder.SMART) {
+ override fun pulse(): Boolean {
+ return false
+ }
+ }, PulseType.STANDARD)
+ npc!!.sendChat("Down here!")
+ SceneryBuilder.replace(closedTrapDoor,openedTrapDoor,10)
+ }
+ 4 -> {
+ player!!.faceLocation(trapdoorLocation.transform(Direction.WEST, 1))
+ player!!.animator.animate(ladderClimbAnimation)
+ }
+ 5 -> {
+ teleport(player!!, tunnels);
+ npc!!.pulseManager.clear();
+ }
+ 7 -> {
+ // We are now underground
+ val undergroundNarnode = RegionManager.getNpc(player!!.location, NPCs.KING_NARNODE_SHAREEN_670, 16)
+ forceWalk(undergroundNarnode!!,player!!.location.transform(Direction.EAST,1), "SMART")
+ unlock(player!!)
+ openDialogue(player!!, KingNarnodeUnderGroundDialogue(), undergroundNarnode)
+ }
+ 10 -> return true;
+ }
+ count++
+ return false
+ }
+ })
+ }
+ override fun handle(componentID: Int, buttonID: Int) {
+ when (questStage(player!!, questName)) {
+ 0 -> {
+ when (stage) {
+ 0 -> npcl("Welcome Traveller. I am King Narnode. It's nice to see an outsider.").also { stage++ }
+ 1 -> playerl("Hi! It seems to be a very busy settlement.").also{ stage++ }
+ 2 -> npcl("For now.").also { stage++ }
+ 3 -> options("You seem worried, what's up?","I'll be off now.").also { stage++ }
+ 4 -> when (buttonID) {
+ 1 -> playerl("You seem worried, what's up?").also { stage = 5 }
+ 2 -> playerl("I'll be off now.").also { stage = 25 }
+ }
+ 5 -> npcl("Traveller, can I speak to you in strictest confidence?").also { stage++ }
+ 6 -> playerl("Of course sire.").also { stage++ }
+ 7 -> npcl("Not here, follow me.").also {
+ stage = END_DIALOGUE;
+ // Animate Narnode to walk to the trapdoor and climb the ladder
+ leadDownLadder()
+ }
+ 25 -> npcl("Enjoy your stay with us. There are many things to see in my kingdom.").also { stage = END_DIALOGUE }
+ }
+ }
+ 10 -> {
+ when (stage) {
+ 0 -> {
+ // Did the player destroy/drop the quest items
+ if(!player!!.hasItem(Item(Items.BARK_SAMPLE_783)) || !player!!.hasItem(Item(Items.TRANSLATION_BOOK_784))) {
+ npcl("You dropped something I gave you earlier. Please take better care of my thing!")
+ if(!player!!.hasItem(Item(Items.BARK_SAMPLE_783))) {
+ addItemOrDrop(player!!,Items.BARK_SAMPLE_783)
+ }
+ if(!player!!.hasItem(Item(Items.TRANSLATION_BOOK_784))) {
+ addItemOrDrop(player!!,Items.TRANSLATION_BOOK_784)
+ }
+ stage = END_DIALOGUE;
+ } else {
+ npcl("Traveller, any word from Hazelmere?")
+ stage++;
+ }
+ }
+ 1 -> playerl("Not yet.").also { stage = END_DIALOGUE }
+ }
+ }
+ 20 -> {
+ when (stage) {
+ 0 -> npcl("Welcome Traveller. I am King Narnode. It's nice to see an outsider.").also {
+ // Reset correct answered options
+ setAttribute(player!!, "/save:grandtree:opt1", false)
+ setAttribute(player!!, "/save:grandtree:opt2", false)
+ setAttribute(player!!, "/save:grandtree:opt3", false)
+ stage++
+ }
+ 1 -> playerl("Hello again, Your Highness.").also{ stage++ }
+ 2 -> npcl("Hello Traveller, did you speak to Hazelmere?").also { stage++ }
+ 3 -> playerl("Yes! I managed to find him.").also{ stage++ }
+ 4 -> npcl("Do you understand what he said?").also { stage++ }
+ 5 -> options("I think so!","No, I need to go back.").also { stage++ }
+ 6 -> when (buttonID) {
+ 1 -> playerl("I think so!").also { stage = 10 }
+ 2 -> playerl("No, I need to go back.").also { stage = END_DIALOGUE }
+ }
+ 10 -> npcl("So what did he say?").also { stage++ }
+ 11 -> options("King Narnode must be stopped, he is a madman!","Praise be to the great Zamorak!", "Do you have any bread? I do like bread.", "The time has come to attack!","None of the above.").also { stage++ }
+ 12 -> when (buttonID) {
+ 1 -> playerl("King Narnode must be stopped, he is a madman!").also { stage++ }
+ 2 -> playerl("Praise be to the great Zamorak!").also { stage++ }
+ 3 -> playerl("Do you have any bread? I do like bread.").also { stage++ }
+ 4 -> playerl("The time has come to attack!").also { stage++ }
+ 5 -> options("The tree is fine, you have nothing to fear.","You must come and see me!", "The tree needs watering as there has been drought.","Grave danger lies ahead, only the bravest will linger.","None of the above.").also { stage = 20 }
+ }
+ 13 -> options("The tree is fine, you have nothing to fear.","You must come and see me!", "The tree needs watering as there has been drought.","Grave danger lies ahead, only the bravest will linger.","None of the above.").also { stage = 20 }
+ 20 -> when (buttonID) {
+ 1 -> playerl("The tree is fine, you have nothing to fear.").also { stage++ }
+ 2 -> playerl("You must come and see me!").also { stage++ }
+ 3 -> playerl("The tree needs watering as there has been drought.").also { stage++ }
+ 4 -> playerl("Grave danger lies ahead, only the bravest will linger.").also { stage++ }
+ 5 -> options("Time is of the essence! We must move quickly.","There is no need for haste, just send a runner.", "A man came to me with the King's seal.","You must act now, or we will all die!","None of the above.").also { stage = 30 }
+ }
+ 21 -> options("Time is of the essence! We must move quickly.","There is no need for haste, just send a runner.", "Time passes us by.","You must act now, or we will all die!","None of the above.").also { stage = 31 }
+ // Right
+ 30 -> when (buttonID) {
+ 1 -> playerl("Time is of the essence! We must move quickly.").also { stage = 33 }
+ 2 -> playerl("There is no need for haste, just send a runner.").also { stage = 33 }
+ 3 -> playerl("A man came to me with the King's seal.").also {
+ setAttribute(player!!, "/save:grandtree:opt1", true)
+ stage = 32
+ }
+ 4 -> playerl("You must act now, or we will all die!").also { stage = 33 }
+ 5 -> options("Only Adamantite is any use.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 41 }
+ }
+ // Wrong
+ 31 -> when (buttonID) {
+ 1 -> playerl("Time is of the essence! We must move quickly.").also { stage = 33 }
+ 2 -> playerl("There is no need for haste, just send a runner.").also { stage = 33 }
+ 3 -> playerl("Time passes us by.").also { stage = 33 }
+ 4 -> playerl("You must act now, or we will all die!").also { stage = 33 }
+ 5 -> options("Only Adamantite is any use.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 41 }
+ }
+ 32 -> options("I gave the man Daconia rocks.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 40 }
+ 33 -> options("Only Adamantite is any use.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 41 }
+ // Right
+ 40 -> when (buttonID) {
+ 1 -> playerl("I gave the man Daconia rocks.").also {
+ setAttribute(player!!, "/save:grandtree:opt2", true)
+ stage = 42
+ }
+ 2 -> playerl("You must use force!").also { stage = 43 }
+ 3 -> playerl("Use a bucket of milk from a scared cow.").also { stage = 43 }
+ 4 -> playerl("Take this banana to him, he will understand.").also { stage = 43 }
+ 5 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","The tree will die in five days!").also { stage = 51 }
+ }
+ // Wrong
+ 41 -> when (buttonID) {
+ 1 -> playerl("Only Adamantite is any use.").also { stage = 43 }
+ 2 -> playerl("You must use force!").also { stage = 43 }
+ 3 -> playerl("Use a bucket of milk from a scared cow.").also { stage = 43 }
+ 4 -> playerl("Take this banana to him, he will understand.").also { stage = 43 }
+ 5 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","The tree will die in five days!").also { stage = 51 }
+ }
+ 42 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","And Daconia rocks will kill the tree!").also { stage = 50 }
+ 43 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","The tree will die in five days!").also { stage = 51 }
+ // Right
+ 50 -> when (buttonID) {
+ 1 -> playerl("All with be fine on the third night.").also { stage = 52 }
+ 2 -> playerl("You must wait till the second night.").also { stage = 52 }
+ 3 -> playerl("Nothing will help us now!").also { stage = 52 }
+ 4 -> playerl("And Daconia rocks will kill the tree!").also {
+ setAttribute(player!!, "/save:grandtree:opt3", true)
+ stage = 52
+ }
+ }
+ // Wrong
+ 51 -> when (buttonID) {
+ 1 -> playerl("All with be fine on the third night.").also { stage++ }
+ 2 -> playerl("You must wait till the second night.").also { stage++ }
+ 3 -> playerl("Nothing will help us now!").also { stage++ }
+ 4 -> playerl("The tree will die in five days!").also { stage++ }
+ }
+ 52 -> {
+ if(getAttribute(player!!, "/save:grandtree:opt1", false)
+ && getAttribute(player!!, "/save:grandtree:opt2", false)
+ && getAttribute(player!!, "/save:grandtree:opt3", false)){
+ npcl("Of course! I should've known! Someone must've forged my royal seal. Hazelmere thought I sent him for the Daconia stones!").also { stage = 60 }
+ } else {
+ npcl("Wait a minute! That doesn't sound like Hazelmere! Are you sure you translated correctly?").also { stage++ }
+ }
+ }
+ 53 -> playerl("Erm...I think so.").also { stage++ }
+ 54 -> npcl(" I'm sorry Traveller but this is no good. The translation must be perfect or the information's no use. Please come back when you know exactly what Hazelmere said.").also { stage = END_DIALOGUE }
+ 60 -> playerl("What are Daconia stones?").also { stage++ }
+ 61 -> npcl("Hazelmere created the Daconia stones. They are a safety measure, in case the tree grew out of control. They're the only thing that can kill the tree.").also { stage++ }
+ 62 -> npcl("This is terrible! The stones must be recovered!").also { stage++ }
+ 63 -> playerl("Can I help?").also { stage++ }
+ 64 -> npcl("First, I must warn the tree guardians. Please, could you tell the chief tree guardian, Glough. He lives in a tree house just in front of the Grand Tree.").also { stage++ }
+ 65 -> npcl("If he's not there he will be at his girlfriend Anita's place. Meet me back here once you've told him.").also { stage++ }
+ 66 -> playerl("Ok! I'll be back soon.").also {
+ setQuestStage(player!!, questName, 40)
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ 40 -> {
+ when(stage) {
+ 0 -> npcl("Hello Traveller, did you speak to Glough?").also { stage++ }
+ 1 -> playerl("Not yet.").also { stage++ }
+ 2 -> npcl("OK. He lives just in front of the Grand Tree. Let me know when you’ve talked to him.").also{ stage = END_DIALOGUE }
+ }
+ }
+ 45 -> {
+ when(stage) {
+ 0 -> playerl("Hello, Your Highness. Have you any news on the Daconia stones?").also { stage++ }
+ 1 -> npcl("It's OK Traveller, thanks to Glough! He found a human sneaking around! He had three Daconia rocks on him!").also { stage++ }
+ 2 -> playerl("Wow! That was quick!").also { stage++ }
+ 3 -> npcl("Yes Glough really knows what he's doing. The human has been detained until we know who else is involved. Maybe Glough was right, maybe humans are invading!").also { stage++ }
+ 4 -> playerl("I doubt it, can I speak to the prisoner?").also { stage++ }
+ 5 -> npcl("Certainly. He's on the top level of the tree. Be careful, it's a long way down!").also {
+ setQuestStage(player!!, questName, 46)
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ 46 -> {
+ when(stage){
+ 0 -> npcl("Hello Traveller. If you wish to talk to the prisoner go to the top of the tree, you'll find him there.").also { stage++ }
+ 1 -> playerl("Thanks.").also { stage = END_DIALOGUE }
+ }
+ }
+ 55 -> {
+ when(stage){
+ 0 -> playerl("King Nardone, I need to talk!").also { stage++ }
+ 1 -> npcl("Traveller, what are you doing here? The stronghold has been put on full alert! It's not safe for you here!").also { stage++ }
+ 2 -> playerl("Your Highness, I believe Glough is killing the trees in order to make a mass fleet of warships!").also { stage++ }
+ 3 -> npcl("That's an absurd accusation!").also { stage++ }
+ 4 -> playerl("His hatred for humanity is stronger than you know!").also { stage++ }
+ 5 -> npcl("That's enough Traveller, you sound as paranoid as him! Traveller please leave! It's bad enough having one human locked up.").also { stage = END_DIALOGUE }
+ }
+ }
+ 60 -> {
+ if(player!!.hasItem(Item(Items.INVASION_PLANS_794))){
+ when(stage){
+ 0 -> playerl("Hi, Your Highness, did you think about what I said?").also { stage++ }
+ 1 -> npcl("Look, if you're right about Glough I would have him arrested but there's no reason for me to think he's lying.").also { stage++ }
+ 2 -> playerl("Look, I found this at Glough's home!").also { stage++ }
+ 3 -> sendDialogue(player!!, "You give the King the invasion plans.").also { stage++ }
+ 4 -> npcl("If these are to be believed then this is terrible! But it's not proof, anyone could have made these. Traveller, I understand your concern.").also { stage++ }
+ 5 -> npcl("I had guards search Glough's house but they found nothing suspicious, just these odd twigs.").also { stage++ }
+ 6 -> sendDialogue(player!!, "The King has given you some twigs lashed together.").also{
+ addItemOrDrop(player!!, Items.TWIGS_789)
+ addItemOrDrop(player!!, Items.TWIGS_790)
+ addItemOrDrop(player!!, Items.TWIGS_791)
+ addItemOrDrop(player!!, Items.TWIGS_792)
+ stage++
+ }
+ 7 -> npcl("On the other hand, if Glough's right about the humans we will need an army of gnomes to protect ourselves. ").also { stage++ }
+ 8 -> npcl("So I've decided to allow Glough to raise a mighty gnome army. The Grand Tree's still slowly dying. If it is human sabotage we must respond!").also{
+ setQuestStage(player!!, questName, 70)
+ removeItem(player!!, Item(Items.INVASION_PLANS_794), Container.INVENTORY)
+ stage = END_DIALOGUE
+ }
+ }
+ } else {
+ when(stage){
+ 0 -> playerl("Hello, Your Highness.").also { stage++ }
+ 1 -> npcl("Please Traveller, if the gnomes see me talking to you they'll revolt against me.").also { stage++ }
+ 2 -> playerl("That's crazy!").also { stage++ }
+ 3 -> npcl("Glough's scared the whole town, he expects the humans to attack any day. He's even begun to recruit hundreds of gnome soldiers.").also { stage++ }
+ 4 -> playerl("Don't you understand he's creating his own army?!").also { stage++ }
+ 5 -> npcl("Please Traveller, leave before it's too late!").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ 70 -> {
+ when(stage){
+ 0 -> npcl("Please Traveller, take my advice and leave!").also {
+ if(!player!!.hasItem(Item(Items.TWIGS_789)) || !player!!.hasItem(Item(Items.TWIGS_790)) || !player!!.hasItem(Item(Items.TWIGS_791)) || !player!!.hasItem(Item(Items.TWIGS_792))) {
+ stage++
+ } else {
+ stage = END_DIALOGUE
+ }
+ }
+ 1 -> playerl("I've lost those twigs you gave me.").also{ stage++ }
+ 2 -> {
+ if(player!!.inventory.freeSlots() < 4) {
+ npcl("Hmm. Looks like you can't carry anymore. Put 4 things down and come back to me.").also { stage = END_DIALOGUE }
+ } else {
+ npcl("King Narnode gives you 4 twigs.").also {
+ addItemOrDrop(player!!, Items.TWIGS_789)
+ addItemOrDrop(player!!, Items.TWIGS_790)
+ addItemOrDrop(player!!, Items.TWIGS_791)
+ addItemOrDrop(player!!, Items.TWIGS_792)
+ stage = END_DIALOGUE
+ }
+ }
+ }
+ }
+ }
+ 98,99 -> {
+ leadDownLadder()
+ }
+ 100 -> {
+ when (stage) {
+ 0 -> npcl("Thanks again for your help!").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ }
+}
+
+class KingNarnodeUpstairsDialogue : DialogueFile(){
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(stage){
+ 0 -> playerl("I don't think you can trust Glough, Your Highness. He seems to have an unnatural hatred for humans.").also { stage++ }
+ 1 -> npcl("I know he can be a bit extreme at times. But he's the best tree guardian I have, he has made the gnomes paranoid about humans though.").also { stage++ }
+ 2 -> npcl("I'm afraid Glough has placed guards on the front gate to stop you escaping! Let my glider pilot fly you away until things calm down around here.").also { stage++ }
+ 3 -> playerl("Well, OK.").also { stage++ }
+ 4 -> npcl("I'm sorry again Traveller!").also { stage = END_DIALOGUE }
+ }
+ }
+
+}
+
+class KingNarnodeUnderGroundDialogue : DialogueFile() {
+ private fun leadUpLadder(){
+ val ladderLoc = Location.create(2464, 9897, 0)
+ val ladderClimbAnimation = Animation(828)
+ val ladderExit = Location.create(2464, 3497, 0)
+ GameWorld.Pulser.submit(object : Pulse(0) {
+ var count = 0
+ override fun pulse(): Boolean {
+ when (count) {
+ 0 -> {
+ forceWalk(player!!, ladderLoc, "SMART")
+ lock(player!!,10)
+ npc!!.pulseManager.run(object : MovementPulse(npc, player, Pathfinder.SMART) {
+ override fun pulse(): Boolean {
+ return false
+ }
+ }, PulseType.STANDARD)
+ npc!!.sendChat("Up here!")
+ }
+ 4 -> {
+ player!!.faceLocation(ladderLoc.transform(Direction.WEST, 1))
+ player!!.animator.animate(ladderClimbAnimation)
+ }
+ 5 -> {
+ teleport(player!!, ladderExit);
+ npc!!.pulseManager.clear();
+ unlock(player!!)
+ }
+ 10 -> return true
+ }
+ count++
+ return false
+ }
+ })
+ }
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(questStage(player!!, questName)) {
+ 98 -> when (stage) {
+ 0 -> npcl("Traveller, you're wounded! What happened?").also { stage++ }
+ 1 -> playerl("It's Glough! He set a demon on me!").also { stage++ }
+ 2 -> npcl("What?! Glough?! With a demon?!").also { stage++ }
+ 3 -> playerl("Glough has a store of Daconia rocks further up the passage! He's been accessing the roots from a secret passage at his home.").also { stage++ }
+ 4 -> npcl("Never! Not Glough! He's a good gnome at heart! Guard!").also { stage++ }
+ 5 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"Sire!").also{ stage++ }
+ 6 -> npcl("Go and check out that passage!").also { stage++ }
+ 7 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"We found Glough hiding under a horde of Daconia rocks!").also{ stage++ }
+ 8 -> playerl("That's what I've been trying to tell you! Glough's been fooling you!").also { stage++ }
+ 9 -> npcl("I... I don't know what to say! How could I have been so blind?! Guard! Call off the military training! The humans are not attacking!").also { stage++ }
+ 10 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"Yes sir!").also{ stage++ }
+ 11 -> npcl("You have my full apologies Traveller! And my gratitude! A reward will have to wait though, the tree is still dying!").also {stage++}
+ 12 -> npcl("The guards are clearing Glough's rock supply now but there must be more Daconia hidden somewhere in the roots! Help us search, we have little time!").also {
+ setQuestStage(player!!, questName, 99)
+ // position of the daconia rock
+ if(getAttribute(player!!,"treegnome:rock",0) == 0){
+ val answer = (1..5).random()
+ setAttribute(player!!,"/save:treegnome:rock",answer)
+ }
+ stage = END_DIALOGUE
+ }
+ }
+
+ 99 -> {
+ if(player!!.hasItem(Item(Items.DACONIA_ROCK_793))){
+ when(stage){
+ 0 -> npcl("Traveller, have you managed to find the Daconia?").also { stage++ }
+ 1 -> playerl("Is this it?").also { stage++ }
+ 2 -> npcl("Yes! Excellent, well done!").also { stage++ }
+ 3 -> sendDialogue(player!!,"You give the King the Daconia rock.").also { stage++ }
+ 4 -> npcl("It's incredible, the tree's health is improving already! I don't know what to say, we owe you so much! To think Glough had me fooled all along!").also { stage++ }
+ 5 -> playerl("All that matters now is that humans and gnomes can live together in peace!").also { stage++ }
+ 6 -> npcl("I'll drink to that! From now on I vow to make this stronghold a welcoming place for all! I'll grant you access to all our facilities.").also { stage++ }
+ 7 -> playerl("Thanks! I think!").also { stage++ }
+ 8 -> npcl("It should make your stay here easier. You can use the spirit tree to transport yourself, as well as the gnome glider. I also give you access to our mine.").also { stage++ }
+ 9 -> playerl("Mine?").also { stage++ }
+ 10 -> npcl("Very few know of the secret mine under the Grand Tree. If you push on the roots just to my north they will separate and let you pass.").also { stage++ }
+ 11 -> playerl("Strange!").also { stage++ }
+ 12 -> npcl("That's magic trees for you! All the best Traveller and thanks again!").also { stage++ }
+ 13 -> playerl("You too, Your Highness!").also {
+ finishQuest(player!!, questName)
+ removeItem(player!!, Items.DACONIA_ROCK_793)
+ stage = END_DIALOGUE
+ }
+ }
+ } else {
+ when (stage) {
+ 0 -> npcl("Traveller, have you managed to find the Daconia?").also { stage++ }
+ 1 -> playerl("No sign of it so far.").also { stage++ }
+ 2 -> npcl("The tree will still die if we don't find it! It could be anywhere!").also { stage++ }
+ 3 -> playerl("Don't worry, Your Highness! We'll find it!").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ 100 -> {
+ when (stage) {
+ 0 -> npcl("Thanks again for your help!").also { stage = END_DIALOGUE }
+ }
+ }
+
+ else -> when (stage) {
+ 0 -> npcl("Down here.").also { stage++ }
+ 1 -> playerl("So what is this place?").also { stage++ }
+ 2 -> npcl("These, my friend, are the foundations of the stronghold.").also { stage++ }
+ 3 -> playerl("They look like roots to me.").also { stage++ }
+ 4 -> npcl("Not just any roots Traveller! These were created by gnome mages eons ago, since then they have grown to become a mighty stronghold!").also { stage++ }
+ 5 -> playerl("Impressive. What exactly is the problem?").also { stage++ }
+ 6 -> npcl("In the last two months our tree guardians have reported continuing deterioration of the Grand Tree's health. I've never seen this before! It could be the end for us all!").also { stage++ }
+ 7 -> playerl("You mean the tree is ill?").also { stage++ }
+ 8 -> npcl(" In effect yes. Would you be willing to help us discover what is happening to the tree?").also { stage++ }
+ 9 -> options("I'm sorry, I don't want to get involved.", "I'd be happy to help!").also { stage++ }
+ 10 -> when (buttonID) {
+ 1 -> playerl("I'm sorry, I don't want to get involved.").also { stage = 15 }
+ 2 -> playerl("I'd be happy to help!").also { stage = 20 }
+ }
+
+ 15 -> npcl("I understand Traveller. Please keep this to yourself.").also { stage++ }
+ 16 -> playerl("Of course.").also { stage++ }
+ 17 -> npcl("I'll show you the way back up.").also { stage++ }
+ 18 -> {
+ npcl("Up here.")
+ leadUpLadder();
+ stage = END_DIALOGUE
+ }
+
+ 20 -> npcl("Thank Guthix for your arrival! The first task is to find out what's killing the tree.").also { stage++ }
+ 21 -> playerl("Do you have an idea?").also { stage++ }
+ 22 -> npcl("My top tree guardian, Glough, believes it's human sabotage. I'm not so sure! The only way to know for sure is to talk to Hazelmere.").also { stage++ }
+ 23 -> playerl("Who's Hazelmere?").also { stage++ }
+ 24 -> npcl("Hazelmere is one of the mages that created the Grand Tree. He is the only one that has survived from that time. Take this bark sample to him, he will be able to help!").also { stage++ }
+ 25 -> sendItemDialogue(
+ player!!,
+ Items.BARK_SAMPLE_783,
+ "The king shows you a sample of bark."
+ ).also { stage++ }
+
+ 26 -> npcl("The mage only talks in the old tongue, you'll need this.").also { stage++ }
+ 27 -> sendItemDialogue(
+ player!!,
+ Items.TRANSLATION_BOOK_784,
+ "The king shows you a translation book."
+ ).also { stage++ }
+
+ 28 -> playerl("What is it?").also { stage++ }
+ 29 -> npcl("It's a translation book, you'll need it to translate what Hazelmere says. Do that carefully! His words are our only hope!").also { stage++ }
+ 30 -> npcl("You'll find his dwellings high upon a towering hill, on an island east of Yanille. I'll show you the way back up.").also { stage++ }
+ 31 -> if (player!!.inventory.freeSlots() >= 2) {
+ npcl("Up here.")
+ stage = END_DIALOGUE
+ setQuestStage(player!!, questName, 10)
+ addItemOrDrop(player!!, Items.BARK_SAMPLE_783)
+ addItemOrDrop(player!!, Items.TRANSLATION_BOOK_784)
+ leadUpLadder();
+ } else {
+ npcl("You don't have inventory space for my book or the bark! Clear some space and speak to me again")
+ }.also { stage = END_DIALOGUE }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt
new file mode 100644
index 000000000..d109f5bff
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt
@@ -0,0 +1,117 @@
+package content.region.kandarin.quest.grandtree
+
+import core.api.getAttribute
+import core.api.questStage
+import core.api.setAttribute
+import core.game.dialogue.DialogueFile
+import core.game.global.action.DoorActionHandler
+import core.game.node.scenery.Scenery
+import core.game.world.map.Location
+import core.tools.END_DIALOGUE
+
+class ShipyardWorkerDialogue : DialogueFile(){
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(stage){
+ 0 -> npcl("Hey you! What are you up to?").also {
+ if(questStage(player!!, TheGrandTree.questName) == 55) {
+ setAttribute(player!!, "/save:grandtree:opt1", false)
+ setAttribute(player!!, "/save:grandtree:opt2", false)
+ setAttribute(player!!, "/save:grandtree:opt3", false)
+ }
+ stage++
+ }
+ 1 -> playerl("I'm trying to open the gate!").also { stage++ }
+ 2 -> npcl("I can see that! Why?").also { stage++ }
+ 3 -> options("I'm from the Ministry of Health and Safety.","Glough sent me.","I'm just looking around.").also { stage++ }
+ 4 -> when(buttonID){
+ 1 -> playerl("I'm from the Ministry of Health and Safety.").also { stage = 40}
+ 2 -> playerl("Glough sent me.").also{ stage = 50}
+ 3 -> playerl("I'm just looking around.").also { stage = 10 }
+ }
+ 10 -> playerl("I'm just looking around.").also { stage++ }
+ 11 -> npcl("This ain't a museum! Leave now!").also { stage++ }
+ 12 -> playerl("I'll leave when I choose!").also { stage++ }
+ 13 -> npcl("Well you're not on the list so you're not coming in. Go away.").also { stage++ }
+ 14 -> playerl("Well I'll just stand here then until you let me in.").also { stage++ }
+ 15 -> npcl("You do that!").also { stage++ }
+ 16 -> playerl("I will!").also { stage++ }
+ 17 -> npcl("Yeah?").also { stage++ }
+ 18 -> playerl("Yeah!").also { stage++ }
+ 19 -> npcl("...").also { stage++ }
+ 20 -> playerl("...").also { stage++ }
+ 21 -> playerl("So are you going to let me in then?").also { stage++ }
+ 22 -> npcl("No.").also { stage++ }
+ 23 -> playerl("...").also { stage++ }
+ 24 -> npcl("...").also { stage++ }
+ 25 -> playerl("You bored yet?").also { stage++ }
+ 26 -> npcl("No, I can stand here all day.").also { stage++ }
+ 27 -> playerl("...").also { stage++ }
+ 28 -> npcl("...").also { stage++ }
+ 29 -> playerl("Alright you win. I'll find another way in.").also { stage++ }
+ 30 -> npcl("No you won't.").also { stage++ }
+ 31 -> playerl("Yes I will.").also { stage++ }
+ 32 -> npcl("I'm not starting that again. Maybe if I ignore you you'll go away...").also { stage =
+ END_DIALOGUE
+ }
+ 40 -> npcl("Never 'erd of 'em.").also { stage++ }
+ 41 -> playerl("You will respect my authority!").also { stage++ }
+ 42 -> npcl("Get out of here before I give you a beating!").also { stage = END_DIALOGUE }
+ 50 -> npcl("Hmm... really? What for?").also { stage++ }
+ 51 -> playerl("You're wasting my time! Take me to your superior!").also { stage++ }
+ 52 -> npcl("OK. Password.").also { stage++ }
+ 53 -> options("Ka.","Ko.","Ke.").also { stage++ }
+ 54 -> when(buttonID){
+ 1 -> playerl("Ka.").also {
+ setAttribute(player!!, "/save:grandtree:opt1", true)
+ stage++
+ }
+ 2 -> playerl("Ko.").also { stage++ }
+ 3 -> playerl("Ke.").also { stage++ }
+ }
+ 55 -> options("Lo.","Lu.","Le.").also { stage++ }
+ 56 -> when(buttonID){
+ 1 -> playerl("Lo.").also { stage++ }
+ 2 -> playerl("Lu.").also {
+ setAttribute(player!!, "/save:grandtree:opt2", true)
+ stage++
+ }
+ 3 -> playerl("Le.").also { stage++ }
+ }
+ 57 -> options("Mon.","Min.","Men.").also { stage++ }
+ 58 -> when(buttonID){
+ 1 -> playerl("Mon.").also { stage++ }
+ 2 -> playerl("Min.").also {
+ setAttribute(player!!, "/save:grandtree:opt3", true)
+ stage++
+ }
+ 3 -> playerl("Men.").also { stage++ }
+ }
+ // Correct answer Ka-Lu-Min:
+ 59 -> {
+ if(getAttribute(player!!, "/save:grandtree:opt1", false)
+ && getAttribute(player!!, "/save:grandtree:opt2", false)
+ && getAttribute(player!!, "/save:grandtree:opt3", false)
+ ) {
+ DoorActionHandler.autowalkFence(player!!, Scenery(2438, Location(2945, 3041, 0)), 3727, 3728)
+ npcl("Sorry to have kept you.").also { stage = END_DIALOGUE }
+ } else {
+ npcl("You have no idea!").also { stage = END_DIALOGUE }
+ }
+ }
+ }
+ }
+}
+
+class ShipyardWorkerGenericDialogue: DialogueFile(){
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(stage){
+ 0 -> playerl("Hello.").also { stage++ }
+ 1 -> npcl("Hello matey!").also { stage++ }
+ 2 -> playerl("How are you?").also { stage++ }
+ 3 -> npcl("Tired!").also { stage++ }
+ 4 -> playerl("You shouldn't work so hard!").also { stage = END_DIALOGUE }
+ }
+ }
+
+}
+
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt b/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt
new file mode 100644
index 000000000..e8886c140
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt
@@ -0,0 +1,98 @@
+package content.region.kandarin.quest.grandtree
+
+import core.api.addItemOrDrop
+import core.game.node.entity.player.Player
+import core.game.node.entity.player.link.quest.Quest
+import core.game.node.entity.skill.Skills
+import core.game.node.item.Item
+import core.plugin.Initializable
+import org.rs09.consts.Items
+
+@Initializable
+class TheGrandTree: Quest("The Grand Tree", 71, 70, 5, 150, 0, 1, 160) {
+ override fun newInstance(`object`: Any?): Quest {
+ return this
+ }
+
+ override fun finish(player: Player?) {
+ super.finish(player)
+ player ?: return
+ var ln = 10
+ player.packetDispatch.sendItemZoomOnInterface(Items.DACONIA_ROCK_793, 230, 277, 5)
+ drawReward(player,"5 Quest Points", ln++)
+ drawReward(player,"7900 Agility XP", ln++)
+ drawReward(player,"18,400 Attack XP", ln++)
+ drawReward(player,"2150 Magic XP", ln++)
+ player.skills.addExperience(Skills.AGILITY, 7900.0)
+ player.skills.addExperience(Skills.ATTACK, 18400.0)
+ player.skills.addExperience(Skills.MAGIC, 2150.0)
+ player.questRepository.syncronizeTab(player)
+ }
+
+ override fun drawJournal(player: Player?, stage: Int) {
+ super.drawJournal(player, stage)
+ var line = 12
+ player?: return
+ line(player, "I can start this quest at the !!Grand Tree?? in the !!Gnome??", line++, stage > 0)
+ line(player, "!!Stronghold?? by speaking to !!King Narnode Shareen.??", line++, stage > 0)
+ line++
+ if(stage == 0) {
+ line(player, "I must have:", line++)
+ line(player, "!!Level 25 Agility.??", line++)
+ line(player, "!!High enough combat to defeat a level 172 demon.??", line++)
+ }
+ if(stage >= 10){
+ line(player, "King Narnode Shareen suspects sabotage on the Grand Tree and", line++, stage > 10)
+ line(player, "wants to confirm it by consulting with Hazelmere.", line++, stage > 10)
+ line++
+ line(player, "Hazelmere's dwelling is located on a towering hill, on an island ", line++, stage > 10)
+ line(player, "east of Yanille.", line++, stage > 10)
+ line++
+ }
+ if(stage >= 20){
+ line(player, "Report back to King Narnode Shareen.", line++, stage > 20)
+ line++
+ }
+ if(stage >= 40){
+ line(player, "King Narnode suspects that someone has forged his royal seal.", line++, stage > 40)
+ line(player, "Find Glough and notify him about the situation.", line++, stage > 40)
+ line++
+ }
+ if(stage >= 45){
+ line(player, "Glough says the humans are going to invade! Report back to the king.", line++, stage > 45)
+ line++
+ }
+ if(stage >= 46){
+ line(player, "Talk to the prisoner at the top of the tree", line++, stage > 46)
+ line++
+ }
+ if(stage >= 47){
+ line(player, "Search Glough's home for clues.", line++, stage > 47)
+ line++
+ }
+ if(stage >= 55){
+ line(player, "Glough has placed guards on the front gate to stop you escaping!", line++, stage > 55)
+ line(player, "Use King Narnode's glider pilot fly you away until things calm down.", line++, stage > 55)
+ if(player.hasItem(Item(Items.LUMBER_ORDER_787))){
+ line(player, "Bring the lumber order to Charlie", line++, stage > 55)
+ }
+ line++
+
+ }
+ if(stage >= 60){
+ line(player, "Search Glough's girlfriend's house for his chest keys.", line++, stage > 60)
+ }
+ if(stage >= 60){
+ if(player.hasItem(Item(Items.GLOUGHS_KEY_788))){
+ line(player, "Find a use for Gloughs key and report back to the king.", line++, stage > 60)
+ }
+ }
+ if(stage >= 70){
+ line(player, "Find a use for the strange twigs from King Narnode Shareen.", line++, stage > 70)
+ }
+ }
+
+ companion object {
+ const val questName = "The Grand Tree"
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt b/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt
new file mode 100644
index 000000000..9ea417c89
--- /dev/null
+++ b/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt
@@ -0,0 +1,169 @@
+package content.region.kandarin.quest.grandtree
+
+import core.game.dialogue.DialoguePlugin
+import core.game.dialogue.book.Book
+import core.game.dialogue.book.BookLine
+import core.game.dialogue.book.Page
+import core.game.dialogue.book.PageSet
+import core.game.node.entity.player.Player
+import core.plugin.Initializable
+import org.rs09.consts.Items
+
+/**
+ * Translation Book handler for The Grand Tree quest
+ *
+ * @author crop & szu
+ */
+@Initializable
+class TranslationBook : Book {
+
+ constructor(player: Player?) : super(player, "Translation Book", Items.TRANSLATION_BOOK_784, *arrayOf(
+ PageSet(
+ Page(
+ BookLine("Gnome", 55),
+ BookLine("English translation", 56),
+ BookLine("written by Anita", 57),
+ BookLine("", 58),
+ BookLine("This text contains", 59),
+ BookLine("the ancient Gnome words", 60),
+ BookLine("I have managed to", 61),
+ BookLine("translate thus far.", 62),
+ BookLine("", 63),
+ ),
+ Page(
+ BookLine("-A-", 66),
+ BookLine("arpos: rocks", 67),
+ BookLine("ando: gate", 68),
+ BookLine("andra: city", 69),
+ BookLine("ataris: cow", 70),
+ BookLine("-C-", 71),
+ BookLine("cef: threat", 72),
+ BookLine("cheray: lazy", 73),
+ BookLine("Cinqo: King", 74),
+ BookLine("cretor: bucket", 75),
+ )
+ ),
+ PageSet(
+ Page(
+ BookLine("-E-", 55),
+ BookLine("eis: me", 56),
+ BookLine("es: a", 57),
+ BookLine("et: and", 58),
+ BookLine("eto: will", 59),
+ BookLine("-G-", 60),
+ BookLine("gandius: jungle", 61),
+ BookLine("Gal: All", 62),
+ BookLine("gentis: leaf", 63),
+ BookLine("gutus: banana", 64),
+ BookLine("gomondo: branch", 65),
+ ),
+ Page(
+ BookLine("-H-", 66),
+ BookLine("har: old", 67),
+ BookLine("harij: harpoon", 68),
+ BookLine("hewo: grass", 69),
+ BookLine("", 70),
+ BookLine("-I-", 71),
+ BookLine("ip: you", 72),
+ BookLine("imindus: quest", 73),
+ BookLine("irno: translate", 74),
+ BookLine("", 75),
+ )
+ ),
+ PageSet(
+ Page(
+ BookLine("-K-", 55),
+ BookLine("kar: no", 56),
+ BookLine("kai: boat", 57),
+ BookLine("ko: sail", 58),
+ BookLine("", 59),
+ BookLine("-L-", 60),
+ BookLine("lauf: eye", 61),
+ BookLine("laquinay: common sense", 62),
+ BookLine("lemanto: man", 63),
+ BookLine("lemantolly: stupid man", 64),
+ BookLine("lovos: gave", 65),
+ ),
+ Page(
+ BookLine("-M-", 66),
+ BookLine("meriz: kill", 67),
+ BookLine("mina: time(s)", 68),
+ BookLine("mos: coin", 69),
+ BookLine("mi: I", 70),
+ BookLine("mond: seal", 71),
+ BookLine("", 72),
+ )
+ ),
+ PageSet(
+ Page(
+ BookLine("-P-", 55),
+ BookLine("por: long", 56),
+ BookLine("prit: with", 57),
+ BookLine("priw: tree", 58),
+ BookLine("pro: to", 59),
+ BookLine("", 60),
+ BookLine("-Q-", 61),
+ BookLine("Qui: guard", 62),
+ BookLine("Quir: guardian", 63),
+ BookLine("-R-", 64),
+ BookLine("rentos: agility", 65),
+ ),
+ Page(
+ BookLine("-S-", 66),
+ BookLine("sarko: Begone", 67),
+ BookLine("sind: big", 68),
+ BookLine("", 69),
+ BookLine("-T-", 70),
+ BookLine("ta: the", 71),
+ BookLine("tuzo: open", 72),
+ BookLine("-U-", 73),
+ BookLine("Undri: lands", 74),
+ BookLine("Umesco: Soul", 75),
+ )
+ )
+ )
+ ) {}
+
+ constructor() {
+ /**
+ * empty.
+ */
+ }
+
+ override fun finish() {
+ }
+
+ override fun display(set: Array) {
+ player.lock()
+ player.interfaceManager.open(getInterface())
+
+ for (i in 55..76) {
+ player.packetDispatch.sendString("", getInterface().id, i)
+ }
+ player.packetDispatch.sendString("", getInterface().id, 77)
+ player.packetDispatch.sendString("", getInterface().id, 78)
+ player.packetDispatch.sendString(getName(), getInterface().id, 6)
+ for (page in set) {
+ for (line in page.lines) {
+ player.packetDispatch.sendString(line.message, getInterface().id, line.child)
+ }
+ }
+ player.packetDispatch.sendInterfaceConfig(getInterface().id, 51, index < 1)
+ val lastPage = index == sets.size - 1
+ player.packetDispatch.sendInterfaceConfig(getInterface().id, 53, lastPage)
+ if (lastPage) {
+ finish()
+ }
+ player.unlock()
+ }
+
+ override fun newInstance(player: Player): DialoguePlugin {
+ return TranslationBook(player)
+ }
+
+ override fun getIds(): IntArray {
+ // This is all handled in `BookreadOption.java` you need to manually
+ // register a new dialogue key for your file there.
+ return intArrayOf(49610763)
+ }
+}
\ No newline at end of file