diff --git a/Server/data/configs/ground_spawns.json b/Server/data/configs/ground_spawns.json index 1893b6df3..a2f7b1173 100644 --- a/Server/data/configs/ground_spawns.json +++ b/Server/data/configs/ground_spawns.json @@ -251,6 +251,10 @@ "item_id": "960", "loc_data": "{1,2851,3239,0,160}-{1,2847,3238,0,160}-{1,2845,3232,0,160}-{1,2856,3231,0,160}-{1,2857,3236,0,160}-{1,2846,3384,0,160}-{1,2848,3383,0,160}-{1,2550,3575,0,200}-{1,2553,3576,0,200}-{1,2554,3575,0,200}-{1,2556,3573,0,200}-{1,3216,3665,0,200}-{1,3224,3668,0,200}-{1,3245,3678,0,200}-{1,3230,3686,0,200}-{1,3216,3677,0,200}-{1,3219,3680,0,200}-" }, + { + "item_id": "964", + "loc_data": "{1,2977,3529,0,90}-{1,2978,3531,0,90}-" + }, { "item_id": "966", "loc_data": "{1,3237,3696,0,150}-" diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json index b928857e7..1c38971dc 100644 --- a/Server/data/configs/item_configs.json +++ b/Server/data/configs/item_configs.json @@ -4736,8 +4736,6 @@ "name": "Ghost's skull", "examine": "Ooooh spooky!", "archery_ticket_price": "0", - "destroy": "true", - "destroy_message": "If you get rid of the skull you'll have to search for it again.", "durability": null, "tradeable": "false" }, diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java deleted file mode 100644 index eb76716f4..000000000 --- a/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java +++ /dev/null @@ -1,214 +0,0 @@ -package content.region.misthalin.draynor.quest.anma; - -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.quest.Quest; -import core.game.node.item.Item; -import content.region.misthalin.lumbridge.quest.therestlessghost.RestlessGhost; -import content.data.Quests; - -/** - * Handles the dialogue used for the old crone. - * @author Vexia - */ -public final class OldCronDialogue extends DialoguePlugin { - - /** - * The crone made amulet item. - */ - public static final Item CRONE_AMULET = new Item(10500); - - /** - * The quest used. - */ - private Quest quest; - - /** - * Constructs a new {@code OldCronDialogue} {@code Object}. - */ - public OldCronDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code OldCronDialogue} {@code Object}. - * @param player the player. - */ - public OldCronDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new OldCronDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); - switch (quest.getStage(player)) { - case 16: - case 17: - case 18: - player("I'm here about the farmers east of here."); - break; - default: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, old woman."); - stage = 1; - break; - } - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (quest.getStage(player)) { - case 18: - switch (stage) { - case 0: - if (!player.hasItem(CRONE_AMULET)) { - player("Would you be able to replace the amulet you made? I", "seem to have lost it."); - stage = 4; - break; - } - npc("Yes?"); - stage++; - break; - case 1: - player("Well, to tell the truth, I just came back to chat with", "you. Any news?"); - stage++; - break; - case 2: - npc("Disgraceful! Deliver that amulet; a young lady's", "happiness depends upon it."); - stage++; - break; - case 3: - end(); - break; - case 4: - npc("Here you are; luckily, I saved some of Alice's hair in", "case you were careless. Which you were."); - stage++; - break; - case 5: - if (!player.getInventory().hasSpaceFor(RestlessGhost.AMULET)) { - npc("You don't have enough space in your inventory."); - stage = 3; - break; - } - if (!player.getInventory().containsItem(RestlessGhost.AMULET) && !player.getEquipment().containsItem(RestlessGhost.AMULET)) { - npc("You need to bring me a ghostspeak amulet."); - stage = 3; - break; - } - player.getInventory().add(CRONE_AMULET); - end(); - break; - } - break; - case 17: - switch (stage) { - case 0: - player("I'm here to see if you are ready to do your mystical", "stuff with my ghostspeak amulet."); - stage++; - break; - case 1: - if (!player.getInventory().hasSpaceFor(RestlessGhost.AMULET)) { - npc("I most certainly am, but you don't have enough", "space in your backpack."); - stage++; - break; - } - if (!player.getInventory().containsItem(RestlessGhost.AMULET) && !player.getEquipment().containsItem(RestlessGhost.AMULET)) { - npc("I most certainly am, but you don't have an ghostspeak", "amulet."); - stage++; - } else { - npc("I most certainly am; there you go."); - stage += 2; - } - break; - case 2: - end(); - break; - case 3: - player("Wow, that was quick and painless."); - stage++; - break; - case 4: - npc("Just being a good neighbour."); - stage++; - break; - case 5: - player.getInventory().add(CRONE_AMULET); - quest.setStage(player, 18); - end(); - break; - } - break; - case 16: - switch (stage) { - case 0: - player("Alice and her husband are having trouble talking to one", "another and said you might be able to help."); - stage++; - break; - case 1: - npc("Ah, I know them; shame about those cows. Why would", "they think that I could help?"); - stage++; - break; - case 2: - player("Alice seems to think you could alter a ghostspeak amulet", "in order to allow them to communicate."); - stage++; - break; - case 3: - npc("Well, the poor young lady has such family problems; I", "quite feel her pain. I'd be happy to help."); - stage++; - break; - case 4: - npc("You seem to have one of her golden hairs on your", "shoulder, so I can use that..."); - stage++; - break; - case 5: - interpreter.sendDialogue("In a flash, the crone whisks away an unseen hair from your", "shoulder."); - stage++; - break; - case 6: - npc("Talk to me again with a ghostspeak amulet and some", "space in your backpack and I'll be ready to work on", "the little good deed. The way I plan is quite simple,", "really."); - stage++; - break; - case 7: - npc("I can mirror part of the unused mystical essence of the", "ghostspeak amulet, bind it with Alice's hair and thus", "create a second amulet."); - stage++; - break; - case 8: - npc("The second amulet will be useful for the purpose you", "desire, thought it won't work for any other ghost or", "human other than the farmer and his wife."); - stage++; - break; - case 9: - quest.setStage(player, 17); - end(); - break; - } - break; - default: - switch (stage) { - case 1: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I lived here when this was all just fields, you know."); - stage = 2; - break; - case 2: - end(); - break; - } - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 1695 }; - } -} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCroneDialogue.kt b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCroneDialogue.kt new file mode 100644 index 000000000..46f47c201 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCroneDialogue.kt @@ -0,0 +1,164 @@ +package content.region.misthalin.draynor.quest.anma + +import content.data.Quests +import core.api.addItem +import core.api.freeSlots +import core.api.getQuestStage +import core.api.inEquipmentOrInventory +import core.api.sendDialogue +import core.api.sendMessage +import core.api.setQuestStage +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class OldCroneDialogue : InteractionListener { + + override fun defineListeners() { + on(NPCs.OLD_CRONE_1695, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, OldCroneDialogueFile(), node as NPC) + return@on true + } + } +} + +class OldCroneDialogueFile : DialogueLabeller() { + + override fun addConversation() { + + exec { player, npc -> + when (getQuestStage(player, Quests.ANIMAL_MAGNETISM)) { + 16, 17, 18 -> { + loadLabel(player, "about_the_farmers") + } + else -> { + loadLabel(player, "hello_old") + } + } + } + + label("hello_old") { + player(FacialExpression.HALF_GUILTY, "Hello, old woman.") + npc("I lived here when this was all just fields, you know.") + goto("nowhere") + } + + label("about_the_farmers") { + player("I'm here about the farmers east of here.") + + exec { player, npc -> + when (getQuestStage(player, Quests.ANIMAL_MAGNETISM)) { + 16 -> { + loadLabel(player, "pre_hair_stage_16") + } + 17 -> { + loadLabel(player, "pre_stage_17") + } + 18 -> { + //get a replacement crone amulet + if (!inEquipmentOrInventory(player, Items.CRONE_MADE_AMULET_10500)) { + loadLabel(player, "replace_crone_amulet") + } else { + //chat + loadLabel(player, "post_crone_amulet_chat") + } + } + } + + } + } + + label("pre_hair_stage_16") { + player("Alice and her husband are having trouble talking to one", "another and said you might be able to help.") + npc("Ah, I know them; shame about those cows. Why would", "they think that I could help?") + player("Alice seems to think you could alter a ghostspeak amulet", "in order to allow them to communicate.") + npc("Well, the poor young lady has such family problems; I", "quite feel her pain. I'd be happy to help.") + npc("You seem to have one of her golden hairs on your", "shoulder, so I can use that...") + + exec { player, npc -> + sendDialogue(player, "In a flash, the crone whisks away an unseen hair from your shoulder.") + setQuestStage(player, Quests.ANIMAL_MAGNETISM, 17) + loadLabel(player, "post_hair_stage_16") + } + } + + label("post_hair_stage_16") { + npc("Talk to me again with a ghostspeak amulet and some", "space in your backpack and I'll be ready to work on", "the little good deed. The way I plan is quite simple,", "really.") + npc("I can mirror part of the unused mystical essence of the", "ghostspeak amulet, bind it with Alice's hair and thus", "create a second amulet.") + npc("The second amulet will be useful for the purpose you", "desire, though it won't work for any other ghost or", "human other than the farmer and his wife.") + + exec { player, npc -> + loadLabel(player, "nowhere") + } + } + + label("pre_stage_17") { + player("I'm here to see if you are ready to do your mystical", "stuff with my ghostspeak amulet.") + + exec { player, npc -> + if (!inEquipmentOrInventory(player, Items.GHOSTSPEAK_AMULET_552)) { + loadLabel(player, "no_ghostspeak_amulet") + } else if (freeSlots(player) == 0) { + loadLabel(player, "no_free_space") + } else { + loadLabel(player, "crone_made_amulet") + } + } + } + + label("no_ghostspeak_amulet") { + npc("I most certainly am, but you don't have an ghostspeak", "amulet.") + goto("nowhere") + } + + label("no_free_space") { + npc("I most certainly am, but you don't have enough", "space in your backpack.") + goto("nowhere") + } + + label("crone_made_amulet") { + npc("I most certainly am; there you go.") + player("Wow, that was quick and painless.") + npc("Just being a good neighbour.") + + exec { player, npc -> + if (addItem(player, Items.CRONE_MADE_AMULET_10500)) { + setQuestStage(player, Quests.ANIMAL_MAGNETISM, 18) + loadLabel(player, "nowhere") + } else { + loadLabel(player, "no_free_space") + } + } + } + + label("replace_crone_amulet") { + player("Would you be able to replace the amulet you made? I", "seem to have lost it.") + npc("Here you are; luckily, I saved some of Alice's hair in", "case you were careless. Which you were.") + + exec { player, npc -> + if (freeSlots(player) > 0) { + if (addItem(player, Items.CRONE_MADE_AMULET_10500)) { + loadLabel(player, "nowhere") + } else { + sendMessage(player, "You don't have enough inventory space to accept this amulet.") + } + } else { + sendMessage(player, "You don't have enough inventory space to accept this amulet.") + } + } + + goto("nowhere") + } + + label("post_crone_amulet_chat") { + npc("Yes?") + player("Well, to tell the truth, I just came back to chat with", "you. Any news?") + npc("Disgraceful! Deliver that amulet; a young lady's", "happiness depends upon it.") + goto("nowhere") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/FatherAereckDefaultDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FatherAereckDefaultDialogue.kt new file mode 100644 index 000000000..fd66eb1e4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FatherAereckDefaultDialogue.kt @@ -0,0 +1,215 @@ +package content.region.misthalin.lumbridge.dialogue; + +import content.data.Quests +import content.region.misthalin.lumbridge.quest.therestlessghost.FatherAereckQuestDialogueFile +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.diary.DiaryType +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +/** +* Handles the main entry dialogue for Father Aereck in Lumbridge. +**/ +class FatherAereckDefaultDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.FATHER_AERECK_456, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, FatherAereckDefaultDialogueFile(), node as NPC) + return@on true + } + } +} + +/** +* This includes the default dialogue and gravestones. +*/ +class FatherAereckDefaultDialogueFile : DialogueLabeller() { + override fun addConversation() { + + //allows skipping the main dialogue authentically while Restless Ghost quest is started + exec { player, npc -> + when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) { + 0 -> { + loadLabel(player, "main_entry_transcript") + } + 10, 20, 30, 40 -> { + //passthrough for mid-quest dialogue skip + open(player, FatherAereckQuestDialogueFile(), npc) + } + else -> { + loadLabel(player, "main_entry_transcript") + } + } + } + + label("main_entry_transcript") { + npc(FacialExpression.FRIENDLY, "Welcome to the church of holy Saradomin.") + goto("main_opts") + } + + label("main_opts") { + exec { player, npc -> + if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) == 0) { + loadLabel(player, "not_started_quest_main_opts") + } else if (isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) { + loadLabel(player, "post_quest_main_opts") + } else { + //this shouldn't be needed although in case some how we get here + loadLabel(player, "mid_quest_main_opts") + } + } + } + + label("post_quest_main_opts") { + options( + DialogueOption( + "change_grave", + "Can you change my gravestone now?", + expression = ChatAnim.HALF_ASKING + ), + DialogueOption( + "who_sara", + "Who's Saradomin?", + expression = ChatAnim.HALF_ASKING + ), + DialogueOption( + "nice_place", + "Nice place you've got here.", + expression = ChatAnim.FRIENDLY + ) + ) + } + + label("not_started_quest_main_opts") { + options( + DialogueOption( + "who_sara", + "Who's Saradomin?", + expression = ChatAnim.HALF_ASKING + ), + DialogueOption( + "nice_place", + "Nice place you've got here.", + expression = ChatAnim.FRIENDLY + ), + DialogueOption( + "start_restless_ghost_quest", + "I'm looking for a quest!", + expression = ChatAnim.FRIENDLY + ) + ) + } + + label("mid_quest_main_opts") { + options( + DialogueOption( + "who_sara", + "Who's Saradomin?", + expression = ChatAnim.HALF_ASKING + ), + DialogueOption( + "nice_place", + "Nice place you've got here.", + expression = ChatAnim.FRIENDLY + ) + ) + } + + label("change_grave") { + npc("Certainly. All proceeds are donated to the", "Varrockian Guards' Widows & Orphans Fund.") + goto("gravestone_iface") + } + + label("who_sara") { + npc(FacialExpression.HALF_ASKING, "Surely you have heard of our god, Saradomin?") + npc(FacialExpression.AMAZED, "He who created the forces of goodness and purity in this", "world? I cannot believe your ignorance!") + npc("This is the god with more followers than any other ...at", "least in this part of the world.") + npc(FacialExpression.HALF_ASKING, "He who forged the world as we know it, along with his", "brothers Guthix and Zamorak?") + + goto("oh_that_sara") + } + + label("oh_that_sara") { + options( + DialogueOption( + "that_sara", + "Oh, THAT Saradomin.", + expression = FacialExpression.AMAZED + ), + DialogueOption( + "not_from_this_world", + "Oh, sorry, I'm not from this world.", + expression = FacialExpression.GUILTY + ) + ) + } + + label("that_sara") { + npc("There is only one Saradomin.") + player("Yeah. I, uh, thought you said something else.") + + goto("nowhere") + } + + label("not_from_this_world") { + npc(FacialExpression.SUSPICIOUS, "..."); + npc(FacialExpression.SUSPICIOUS, "That's...strange.") + npc("I thought things not from this world were all, you know,", "slime and tentacles.") + goto("like_my_disguise") + } + + label("like_my_disguise") { + options( + DialogueOption( + "disguise_not_me", + "Not me." + ), + DialogueOption( + "like_disguise", + "I am! Do you like my disguise?", + expression = FacialExpression.FRIENDLY + ), + ) + } + + label("disguise_not_me") { + npc("Well, I can see that. Still, there's something special about", "you.") + player("Thanks, I think.") + + goto("nowhere") + } + + label("like_disguise") { + npc("Argh! Avaunt, foul creature from another dimension!", "Avaunt! Begone in the name of Saradomin!") + player("Okay, okay, I was only joking!") + + goto("nowhere") + } + + label("nice_place") { + npc(FacialExpression.HALF_ASKING, "It is, isn't it? It was built over two centuries ago."); + + goto("nowhere") + } + + label("gravestone_iface") { + exec { player, npc -> + openInterface(player, Components.GRAVESTONE_SHOP_652) + if (isQuestComplete(Quests.THE_RESTLESS_GHOST)) { + player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 15); + } + loadLabel(player, "nowhere") + } + } + + label("start_restless_ghost_quest") { + open(player!!, FatherAereckQuestDialogueFile(), npc!!) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/FatherUrhneyDefaultDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FatherUrhneyDefaultDialogue.kt new file mode 100644 index 000000000..ac522db5f --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FatherUrhneyDefaultDialogue.kt @@ -0,0 +1,145 @@ +package content.region.misthalin.lumbridge.dialogue; + +import content.data.Quests +import content.region.misthalin.lumbridge.quest.therestlessghost.* +import core.api.addItem +import core.api.freeSlots +import core.api.getQuestStage +import core.api.sendItemDialogue +import core.api.sendMessage +import core.api.setQuestStage +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +class FatherUrhneyDefaultDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.FATHER_URHNEY_458, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, FatherUrhneyDefaultDialogueFile(), node as NPC) + return@on true + } + } +} + +class FatherUrhneyDefaultDialogueFile: DialogueLabeller() { + override fun addConversation() { + + npc(FacialExpression.ANGRY, "Go away! I'm meditating!"); + + exec { player, npc -> + when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) { + 0 -> { + loadLabel(player, "pre_quest_opts") + } + 10 -> { + loadLabel(player, "mid_quest_opts") + } + else -> { + loadLabel(player, "post_quest_opts") + } + } + } + + label("pre_quest_opts") { + options( + DialogueOption( + "thats_friendly", + "Well, that's friendly." + ), + DialogueOption( + "repo_house", + "I've come to repossess your house." + ) + ) + } + + label("mid_quest_opts") { + options( + DialogueOption( + "thats_friendly", + "Well, that's friendly." + ), + DialogueOption( + "father_aereck_sent", + "Father Aereck sent me to talk to you." + ), + DialogueOption( + "repo_house", + "I've come to repossess your house." + ) + ) + } + + label("post_quest_opts") { + options( + DialogueOption( + "thats_friendly", + "Well, that's friendly." + ), + DialogueOption( + "ive_lost_amulet", + "I've lost the Amulet of Ghostspeak." + ), + DialogueOption( + "repo_house", + "I've come to repossess your house." + ) + ) + } + + label("thats_friendly") { + npc(FacialExpression.ANGRY, "I SAID go AWAY.") + player("Okay, okay... sheesh, what a grouch.") + goto("nowhere") + } + + label("repo_house") { + npc(FacialExpression.ANGRY, "Under what grounds???") + goto("repo_opts") + } + + label("repo_opts") { + options( + DialogueOption( + "mtg_repay", + "Repeated failure on mortgage repayments." + ), + DialogueOption( + "want_house", + "I don't know, I just wanted this house." + ) + ) + } + + label("mtg_repay") { + npc(FacialExpression.ANNOYED, "What?") + npc(FacialExpression.ANGRY, "I don't have a mortgage! I built this house.") + player("Sorry. I must have got the wrong address. All the", "houses look the same around here.") + npc(FacialExpression.ANGRY, "What? What houses? What ARE you talking about???") + player("Never mind.") + goto("nowhere") + } + + label("want_house") { + npc(FacialExpression.ANGRY, "Oh... go away and stop wasting my time!") + goto("nowhere") + } + + //needs to be down here for some stupid reason + label("father_aereck_sent") { + open(player!!, FatherUrhneyQuestDialogueFile(), npc!!) + } + + //needs to be down here for some stupid reason + label("ive_lost_amulet") { + open(player!!, FatherUrhneyQuestAmuletDialogueFile(), npc!!) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java deleted file mode 100644 index acf0ca8c2..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java +++ /dev/null @@ -1,345 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import core.game.component.Component; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.link.diary.DiaryType; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; -import core.game.dialogue.DialoguePlugin; -import content.data.Quests; - - -/** - * Represents the father aereck dialogue plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class FatherAereckDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code FatherAereckDialogue} {@code Object}. - */ - public FatherAereckDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code FatherAereckDialogue} {@code Object}. - * - * @param player the player. - */ - public FatherAereckDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new FatherAereckDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - int questStage = player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player); - if (questStage == 10) { - npc("Have you got rid of the ghost yet?"); - stage = 520; - return true; - } - if (questStage == 20) { - player("I had a talk with Father Urhney. He has given me this", "funny amulet to talk to the ghost with."); - stage = 530; - return true; - } - if (questStage == 30) { - player("I've found out that the ghost's corpse has lost its skull.", "If I can find the skull, the ghost should leave."); - stage = 540; - return true; - } - if (questStage == 40) { - player("I've finally found the ghost's skull!"); - stage = 550; - return true; - } - npc("Welcome to the church of holy Saradomin, my", "friend! What can I do for you today?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - if (player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { - interpreter.sendOptions("What would you like to say?", "Can you change my gravestone now?", "Who's Saradomin?", "Nice place you've got here."); - stage = 1; - } else { - interpreter.sendOptions("What would you like to say?", "Can you change my gravestone now?", "Who's Saradomin?", "Nice place you've got here.", "I'm looking for a quest."); - stage = 500; - } - break; - case 500: - switch (buttonId) { - case 1: - npc("Certainly. All proceeds are donated to the", "Varrockian Guards' Widows & Orphans Fund."); - stage = 10; - break; - case 2: - npc("Surely you have heard of our god, Saradomin?"); - stage = 20; - break; - case 3: - npc("It is, isn't it? It was built over two centuries ago."); - stage = 300; - break; - case 4: - player("I'm looking for a quest."); - stage = 505; - break; - } - break; - case 505: - npc("That's lucky, I need someone to do a quest for me."); - stage = 506; - break; - case 506: - options("Ok, let me help then.", "Sorry, I don't have time right now."); - stage = 507; - break; - case 507: - switch (buttonId) { - case 1: - player("Ok, let me help then."); - stage = 510; - break; - case 2: - player("Sorry, I don't have time right now."); - stage = 508; - break; - } - break; - case 508: - npc("Oh well. If you do have some spare time on your", "hands, come back and talk to me."); - stage = 509; - break; - case 509: - end(); - break; - case 510: - player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).start(player); - player.getQuestRepository().syncronizeTab(player); - npc("Thank you. The problem is, there is a ghost in the", "church graveyard. I would like you to get rid of it."); - stage = 511; - break; - case 511: - npc("If you need any help, my friend Father Urhney is an", "expert on ghosts."); - stage = 512; - break; - case 512: - npc("I believe he is currently living as a hermit in Lumbridge", "swamp. He has a little shack in the south-west of the", "swamps."); - stage = 513; - break; - case 513: - npc("Exit the graveyard through the south gate to reach the", "swamp. I'm sure if you told him that I sent you he'd", "be willing to help."); - stage = 514; - break; - case 514: - npc("My name is Father Aereck by the way. Pleased to", "meet you."); - stage = 515; - break; - case 515: - player("Likewise."); - stage = 516; - break; - case 516: - npc("Take care travelling through the swamps, I have heard", "they can be quite dangerous."); - stage = 517; - break; - case 517: - player("I will, thanks."); - stage = 518; - break; - case 518: - end(); - break; - case 520: - if (!player.getGameAttributes().getAttributes().containsKey("restless-ghost:urhney")) { - player("I can't find Father Urhney at the moment."); - stage = 521; - break; - } - break; - case 521: - npc("Well, you can get to the swamp he lives in by going", "south through the cemetery."); - stage = 522; - break; - case 522: - npc("You'll have to go right into the western depths of the", "swamp, near the coastline. That is where his house is."); - stage = 523; - break; - case 523: - end(); - break; - case 530: - npc("I always wondered what that amulet was... Well, I hope", "it's useful. Tell me when you get rid of the ghost!"); - stage = 531; - break; - case 531: - end(); - break; - case 540: - npc("That WOULD explain it."); - stage = 541; - break; - case 541: - npc("Hmmmmm. Well, I haven't seen any skulls."); - stage = 542; - break; - case 542: - player("Yes, I think a warlock has stolen it."); - stage = 543; - break; - case 543: - npc("I hate warlocks."); - stage = 544; - break; - case 544: - npc("Ah well, good luck!"); - stage = 545; - break; - case 545: - end(); - break; - case 550: - npc("Great! Put it in the ghost's coffin and see what", "happens!"); - stage = 545; - break; - case 1: - switch (buttonId) { - case 1: - npc("Certainly. All proceeds are donated to the", "Varrockian Guards' Widows & Orphans Fund."); - stage = 10; - break; - case 2: - npc("Surely you have heard of our god, Saradomin?"); - stage = 20; - break; - case 3: - npc("It is, isn't it? It was built over two centuries ago."); - stage = 300; - break; - } - - break; - case 10: - end(); - player.getInterfaceManager().open(new Component(652)); - player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 15); - break; - case 20: - npc("He who created the forces of goodness and purity in this", "world? I cannot believe your ignorance!"); - stage = 21; - break; - case 21: - npc("This is the god with more followers than any other ...at", "least in this part of the world."); - stage = 22; - break; - case 22: - npc("He who forged the world as we know it, along with his", "brothers Guthix and Zamorak?"); - stage = 23; - break; - case 23: - options("Oh, THAT Saradomin.", "Oh, sorry, I'm not from this world."); - stage = 24; - break; - case 24: - switch (buttonId) { - case 1: - npc("There is only one Saradomin."); - stage = 200; - break; - case 2: - npc("..."); - stage = 250; - break; - } - - break; - case 200: - player("Yeah. I, uh, thought you said something else."); - stage = 201; - break; - case 201: - end(); - break; - case 250: - npc("That's...strange."); - stage = 251; - break; - case 251: - npc("I thought things not from this world were all, you know,", "slime and tentacles."); - stage = 270; - break; - case 270: - options("Not me.", "I am! Do you like my disguise?"); - stage = 271; - break; - case 271: - - switch (buttonId) { - case 1: - npc("Well, I can see that. Still, there's something special about", "you."); - stage = 253; - break; - case 2: - npc("Argh! Avaunt, foul creature from another dimension!", "Avaunt! Begone in the name of Saradomin!"); - stage = 291; - break; - } - break; - case 291: - player("Okay, okay, I was only joking!"); - stage = 292; - break; - case 292: - end(); - break; - case 253: - player("Thanks, I think."); - stage = 254; - break; - case 254: - end(); - break; - case 300: - end(); - break; - case 570: - interpreter.sendDialogues(player, null, "Yes, I have!"); - stage = 571; - break; - case 571: - interpreter.sendDialogues(npc, null, "Thank you for getting rid of that awful ghost for me!", "May Saradomin always smile upon you!"); - stage = 572; - break; - case 572: - interpreter.sendDialogues(player, null, "I'm looking for a new quest."); - stage = 573; - break; - case 573: - interpreter.sendDialogues(npc, null, "Sorry, I only had the one quest."); - stage = 300; - break; - } - - return true; - } - - @Override - public int[] getIds() { - return new int[]{456}; - } -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckQuestDialogueFile.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckQuestDialogueFile.kt new file mode 100644 index 000000000..6d8cce233 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckQuestDialogueFile.kt @@ -0,0 +1,122 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage +import core.api.setVarbit +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs + +/** +* Handles the Dialogue for Father Aereck in Lumbridge. +* Specifically for The Restless Ghost quest. +* // https://runescape.fandom.com/wiki/Transcript:The_Restless_Ghost#Starting_out +*/ + +class FatherAereckQuestDialogueFile : DialogueLabeller() { + + override fun addConversation() { + + //passthrough for mid-quest dialogue skip + exec { player, npc -> + when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) { + 10 -> { + loadLabel(player, "quest_stage_10") + } + 20 -> { + loadLabel(player, "quest_stage_20") + } + 30 -> { + loadLabel(player, "quest_stage_30") + } + 40 -> { + loadLabel(player, "quest_stage_40") + } + else -> { + loadLabel(player, "quest_main_entry") + } + } + } + + label("quest_main_entry") { + npc("That's lucky, I need someone to do a quest for me.") + exec { player, npc -> + setQuestStage(player, Quests.THE_RESTLESS_GHOST, 10) + //ensures the varbits is set to default state + setVarbit(player, 2128, 0, true) + setVarbit(player, 2130, 0, true) + } + goto("start_quest_opts") + } + + label("start_quest_opts") { + options( + DialogueOption( + "let_me_help", + "Ok, let me help then." + ), + DialogueOption( + "no_time", + "Sorry, I don't have time right now" + ) + ) + } + + label("let_me_help") { + npc("Thank you. The problem is, there is a ghost in the", "church graveyard. I would like you to get rid of it.") + npc("If you need any help, my friend Father Urhney is an", "expert on ghosts.") + npc("I believe he is currently living as a hermit in Lumbridge", "swamp. He has a little shack in the south-west of the", "swamps.") + npc("Exit the graveyard through the south gate to reach the", "swamp. I'm sure if you told him that I sent you he'd", "be willing to help.") + + npc("My name is Father Aereck by the way. Pleased to", "meet you.") + player("Likewise.") + + npc("Take care travelling through the swamps, I have heard", "they can be quite dangerous.") + player("I will, thanks.") + + goto("nowhere") + } + + label("no_time") { + npc("Oh well. If you do have some spare time on your", "hands, come back and talk to me.") + goto("nowhere") + } + + //mid quest dialogue + label("quest_stage_10") { + npc(FacialExpression.HALF_ASKING, "Have you got rid of the ghost yet?") + player(FacialExpression.GUILTY, "I can't find Father Urhney at the moment." ) + + npc(FacialExpression.THINKING, "Well, you can get to the swamp he lives in by going", "south through the cemetery.") + npc("You'll have to go right into the western depths of the", "swamp, near the coastline. That is where his house is.") + } + + //mid quest dialogue + label("quest_stage_20") { + player("I had a talk with Father Urhney. He has given me this", "funny amulet to talk to the ghost with.") + npc(FacialExpression.HALF_ASKING, "I always wondered what that amulet was... Well, I hope", "it's useful. Tell me when you get rid of the ghost!") + } + + //mid quest dialogue + label("quest_stage_30") { + player("I've found out that the ghost's corpse has lost its skull.", "If I can find the skull, the ghost should leave.") + npc(FacialExpression.AMAZED, "That WOULD explain it.") + npc(FacialExpression.THINKING, "Hmmmmm. Well, I haven't seen any skulls.") + + player("Yes, I think a warlock has stolen it.") + npc("I hate warlocks.") + npc("Ah well, good luck!") + } + + //mid quest dialogue + label("quest_stage_40") { + player(FacialExpression.AMAZED, "I've finally found the ghost's skull!") + npc("Great! Put it in the ghost's coffin and see what", "happens!"); + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java deleted file mode 100644 index 219c0c562..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java +++ /dev/null @@ -1,285 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import content.data.Quests; -import core.game.dialogue.FacialExpression; -import core.game.node.entity.npc.NPC; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.diary.DiaryType; -import core.plugin.Initializable; -import core.game.node.item.Item; -import core.game.dialogue.DialoguePlugin; - -/** - * Represents the father urgney dialogue plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class FatherUhrneyDialogue extends DialoguePlugin { - - /** - * Constructs a new {@code FatherUhrneyDialogue} {@code Object}. - */ - public FatherUhrneyDialogue() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code FatherUhrneyDialogue} {@code Object}. - * @param player the player. - */ - public FatherUhrneyDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - return new FatherUhrneyDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - npc(FacialExpression.ANGRY, "Go away! I'm meditating!"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 0) { - options("Well, that's friendly.", "I've come to repossess your house."); - stage = 1; - } else if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 10) { - options("Well, that's friendly.", "Father Aereck sent me to talk to you.", "I've come to repossess your house."); - stage = 500; - } else if (player.getGameAttributes().getAttributes().containsKey("restless-ghost:urhney") || player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { - options("Well, that's friendly.", "I've lost the Amulet of Ghostspeak.", "I've come to repossess your house."); - stage = 514; - } - break; - case 500: - switch (buttonId) { - case 1: - player("Well, that's friendly."); - stage = 10; - break; - case 2: - player("Father Aereck sent me to talk to you."); - stage = 501; - break; - case 3: - player("I've come to repossess your house."); - stage = 20; - break; - } - break; - case 501: - npc(FacialExpression.ANGRY, "I suppose I'd better talk to you then. What problems", "has he got himself into this time?"); - stage = 502; - break; - case 502: - player("He's got a ghost haunting his graveyard."); - stage = 503; - break; - case 503: - npc(FacialExpression.ANGRY, "Oh, the silly fool."); - stage = 504; - break; - case 504: - npc(FacialExpression.ANGRY, "I leave town for just five months, and ALREADY he", "can't manage."); - stage = 505; - break; - case 505: - npc(FacialExpression.SAD, "(sigh)"); - stage = 506; - break; - case 506: - npc(FacialExpression.ANGRY, "Well, I can't go back and exorcise it. I vowed not to", "leave this place. Until I had done a full two years of", "prayer and meditation."); - stage = 507; - break; - case 507: - npc(FacialExpression.NEUTRAL, "Tell you what I can do though; take this amulet."); - stage = 508; - break; - case 508: - if (player.getInventory().freeSlots() == 0) { - end(); - player.getPacketDispatch().sendMessage("You don't have enough inventory space to accept this amulet."); - break; - } - interpreter.sendItemMessage(552, "Father Urhney hands you an amulet."); - player.getInventory().add(new Item(552, 1)); - player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 20); - player.getGameAttributes().setAttribute("/save:restless-ghost:urhney", true); - stage = 509; - break; - case 509: - npc(FacialExpression.NEUTRAL, "It is an Amulet of Ghostspeak."); - stage = 510; - break; - case 510: - npc(FacialExpression.NEUTRAL, "So called, because when you wear it you can speak to", "ghosts. A lot of ghosts are doomed to be ghosts because", "they have left some important task uncompleted."); - stage = 511; - break; - case 511: - npc(FacialExpression.NEUTRAL, "Maybe if you know what this task is, you can get rid of", "the ghost. I'm not making any guarantees mind you,", "but it is the best I can do right now."); - stage = 512; - break; - case 512: - player("Thank you. I'll give it a try!"); - stage = 513; - break; - case 513: - end(); - break; - case 514: - switch (buttonId) { - case 1: - player("Well, that's friendly."); - stage = 10; - break; - case 2: - player(FacialExpression.NEUTRAL, "I've lost the Amulet of Ghostspeak."); - stage = 515; - break; - case 3: - player("I've come to repossess your house."); - stage = 20; - break; - } - break; - case 515: - if (player.getInventory().contains(552, 1) || player.getEquipment().contains(552, 1)) { - interpreter.sendDialogue("Father Urhney sighs."); - stage = 516; - break; - } - if (player.getBank().contains(552, 1)) { - interpreter.sendDialogue("Father Urhney sighs."); - stage = 517; - break; - } - interpreter.sendDialogue("Father Urhney sighs."); - stage = 519; - break; - case 516: - npc("What are you talking about? I can see you've got it", "with you!"); - stage = 518; - break; - case 517: - npc(FacialExpression.ANGRY, "You come here wasting my time... Has it even", "occurred to you to look in your bank? Now GO", "AWAY!"); - stage = 518; - break; - case 518: - end(); - break; - case 519: - npc(FacialExpression.ANGRY, "How careless can you get? Those things aren't easy to", "come by you know! It's a good job I've got a spare."); - stage = 520; - break; - case 520: - player.getInventory().add(new Item(552)); - interpreter.sendItemMessage(552, "Father Urhney hands you an amulet."); - player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 12); - stage = 521; - break; - case 521: - npc(FacialExpression.ANGRY, "Be more careful this time."); - stage = 522; - break; - case 522: - player("Ok, I'll try to be."); - stage = 523; - break; - case 523: - end(); - break; - case 1: - switch (buttonId) { - case 1: - player("Well, that's friendly."); - stage = 10; - break; - case 2: - player("I've come to repossess your house."); - stage = 20; - break; - - } - break; - case 10: - npc("I SAID go AWAY."); - stage = 11; - break; - case 11: - player("Ok, ok... sheesh, what a grouch."); - stage = 12; - break; - case 12: - end(); - break; - case 20: - npc("Under what grounds???"); - stage = 21; - break; - case 21: - options("Repeated failure on mortgage repayments.", "I don't know, I just wanted this house."); - stage = 22; - break; - case 22: - switch (buttonId) { - case 1: - player("Repeated failure on mortgage repayments."); - stage = 100; - break; - case 2: - player("I don't know. I just wanted this house..."); - stage = 200; - break; - - } - break; - case 100: - npc("What?"); - stage = 101; - break; - case 101: - npc("I don't have a mortgage! I built this house."); - stage = 102; - break; - case 102: - player("Sorry. I must have got the wrong address. All the", "houses look the same around here."); - stage = 103; - break; - case 103: - npc("What? What houses? What ARE you talking about???"); - stage = 104; - break; - case 104: - player("Never mind."); - stage = 105; - break; - case 105: - end(); - break; - case 200: - npc("Oh... go away and stop wasting my time!"); - stage = 201; - break; - case 201: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 458 }; - } -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUrhneyQuestDialogueFile.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUrhneyQuestDialogueFile.kt new file mode 100644 index 000000000..7b9b2c971 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUrhneyQuestDialogueFile.kt @@ -0,0 +1,127 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests +import core.api.addItem +import core.api.anyInEquipment +import core.api.anyInInventory +import core.api.freeSlots +import core.api.getQuestStage +import core.api.inBank +import core.api.inInventory +import core.api.sendDialogue +import core.api.sendItemDialogue +import core.api.sendMessage +import core.api.setQuestStage +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import org.rs09.consts.Items + +class FatherUrhneyQuestDialogueFile : DialogueLabeller() { + override fun addConversation() { + //mid quest asking for amulet + + npc(FacialExpression.ANGRY, "I suppose I'd better talk to you then. What problems", "has he got himself into this time?"); + player("He's got a ghost haunting his graveyard."); + + npc(FacialExpression.ANGRY, "Oh, the silly fool."); + npc(FacialExpression.ANGRY, "I leave town for just five months, and ALREADY he", "can't manage."); + npc(FacialExpression.SAD, "(sigh)"); + npc(FacialExpression.ANGRY, "Well, I can't go back and exorcise it. I vowed not to", "leave this place. Until I had done a full two years of", "prayer and meditation."); + npc(FacialExpression.NEUTRAL, "Tell you what I can do though; take this amulet."); + + goto("take_amulet") + + label("take_amulet") { + exec { player, npc -> + if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) in 10..19) { + item(Item(Items.GHOSTSPEAK_AMULET_552), "Father Urhney hands you an amulet.") + if (freeSlots(player) >= 1) { + if (addItem(player, Items.GHOSTSPEAK_AMULET_552, 1)) { + + setQuestStage(player, Quests.THE_RESTLESS_GHOST, 20) + + loadLabel(player, "post_take_amulet") + } + } else { + sendMessage(player, "You don't have enough inventory space to accept this amulet.") + } + + } + } + + goto("nowhere") + } + + label("post_take_amulet") { + npc(FacialExpression.NEUTRAL, "It is an Amulet of Ghostspeak.") + npc(FacialExpression.NEUTRAL, "So called, because when you wear it you can speak to", "ghosts. A lot of ghosts are doomed to be ghosts because", "they have left some important task uncompleted.") + npc(FacialExpression.NEUTRAL, "Maybe if you know what this task is, you can get rid of", "the ghost. I'm not making any guarantees mind you,", "but it is the best I can do right now.") + player("Thank you. I'll give it a try!") + + goto("nowhere") + } + + //because end() breaks shit + label("nowhere") {} + } +} + +class FatherUrhneyQuestAmuletDialogueFile : DialogueLabeller() { + override fun addConversation() { + + //mid or after finishing quest and needing another one or doing the drop trick + + exec { player, npc -> + line("Father Urhney sighs.") + loadLabel(player, "amulet_main_flow") + } + + label("amulet_main_flow") { + exec { player, npc -> + if (anyInEquipment(player, Items.GHOSTSPEAK_AMULET_552) || anyInInventory(player, Items.GHOSTSPEAK_AMULET_552)) { + loadLabel(player, "amulet_equip_resp") + } else if (inBank(player, Items.GHOSTSPEAK_AMULET_552)) { + loadLabel(player, "amulet_in_bank_resp") + } else { + loadLabel(player, "give_amulet") + } + } + } + + label("amulet_equip_resp") { + npc(FacialExpression.ANNOYED, "What are you talking about? I can see you've got it", "with you!") + goto("nowhere") + } + + label("amulet_in_bank_resp") { + npc(FacialExpression.ANGRY, "You come here wasting my time... Has it even", "occurred to you to look in your bank? Now GO", "AWAY!") + goto("nowhere") + } + + label("give_amulet") { + npc(FacialExpression.ANGRY, "How careless can you get? Those things aren't easy to", "come by you know! It's a good job I've got a spare.") + + exec { player, npc -> + if (freeSlots(player) >= 1) { + if (addItem(player, Items.GHOSTSPEAK_AMULET_552, 1)) { + item(Item(Items.GHOSTSPEAK_AMULET_552), "Father Urhney hands you an amulet.") + + player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 1, 12) + loadLabel(player, "give_amulet_response") + } + } else { + sendMessage(player, "You don't have enough inventory space to accept this amulet.") + loadLabel(player, "nowhere") + } + } + } + + label("give_amulet_resp") { + npc(FacialExpression.ANGRY, "Be more careful this time.") + player("Ok, I'll try to be.") + goto("nowhere") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java deleted file mode 100644 index 11fd553b1..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java +++ /dev/null @@ -1,112 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import content.region.misthalin.draynor.quest.anma.OldCronDialogue; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.quest.Quest; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.ClassScanner; - -import static core.api.ContentAPIKt.*; -import content.data.Quests; - - -/** - * Represents the restless ghost quest. - * @author Vexia - * - */ -@Initializable -public class RestlessGhost extends Quest { - /** - * The ghost speak amulet. - */ - public static final Item AMULET = new Item(552); - - /** - * Constructs a new {@Code RestlessGhost} {@Code Object} - */ - public RestlessGhost() { - super(Quests.THE_RESTLESS_GHOST, 25, 24, 1, 107, 0, 4, 5); - } - - @Override - public Quest newInstance(Object object) { - ClassScanner.definePlugin(new OldCronDialogue()); - return this; - } - - @Override - public void drawJournal(Player player, int stage) { - super.drawJournal(player, stage); - if (stage == 0) { - player.getPacketDispatch().sendString("I can start this quest by speaking to Father Aereck in the", 275, 4+ 7); - player.getPacketDispatch().sendString("church next to Lumbridge Castle.", 275, 5+ 7); - player.getPacketDispatch().sendString("I must be unafraid of a Level 13 Skeleton ", 275, 6+ 7); - } - if (stage == 10) { - player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); - player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); - player.getPacketDispatch().sendString("I should find Father Urhney who is an expert on ghosts. ", 275, 6+ 7); - player.getPacketDispatch().sendString("He lives in a shack in Lumbridge Swamp.", 275, 7+ 7); - - } - if (stage == 20) { - player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); - player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); - player.getPacketDispatch().sendString("I should find Father Urhney who is an expert on ghosts. ", 275, 6+ 7); - player.getPacketDispatch().sendString("He lives in a shack in Lumbridge Swamp.", 275, 7+ 7); - player.getPacketDispatch().sendString("I should talk to the Ghost to find out why it is haunting the", 275, 8+ 7); - player.getPacketDispatch().sendString("graveyard crypt", 275, 9+ 7); - } - if (stage == 30) { - player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); - player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); - player.getPacketDispatch().sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6+ 7); - player.getPacketDispatch().sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7+ 7); - player.getPacketDispatch().sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8+ 7); - player.getPacketDispatch().sendString("peace because an evil wizard had stolen his skull.", 275, 9+ 7); - player.getPacketDispatch().sendString("I should go and search the Wizard's Tower South West of", 275, 10+ 7); - player.getPacketDispatch().sendString("Lumbridge for the Ghost's Skull.", 275, 11+ 7); - } - if (stage == 40) { - player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); - player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); - player.getPacketDispatch().sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6+ 7); - player.getPacketDispatch().sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7+ 7); - player.getPacketDispatch().sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8+ 7); - player.getPacketDispatch().sendString("peace because an evil wizard had stolen his skull.", 275, 9+ 7); - player.getPacketDispatch().sendString("I found the Ghost's Skull in the basement of the Wizards'", 275, 10+ 7); - player.getPacketDispatch().sendString("Tower. It was guarded by a skeleton, but I took it anyways.", 275, 11+ 7); - player.getPacketDispatch().sendString("I should take the Skull back to the Ghost so it can rest.", 275, 12+ 7); - } - if (stage == 100) { - player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); - player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); - player.getPacketDispatch().sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6+ 7); - player.getPacketDispatch().sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7+ 7); - player.getPacketDispatch().sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8+ 7); - player.getPacketDispatch().sendString("peace because an evil wizard had stolen his skull.", 275, 9+ 7); - player.getPacketDispatch().sendString("I found the Ghost's Skull in the basement of the Wizards'", 275, 10+ 7); - player.getPacketDispatch().sendString("Tower. It was guarded by a skeleton, but I took it anyways.", 275, 11+ 7); - player.getPacketDispatch().sendString("I placed the Skull in the Ghost's coffin, and allowed it to", 275, 12+ 7); - player.getPacketDispatch().sendString("rest in peace once more, with gratitude for my help.", 275, 13+ 7); - player.getPacketDispatch().sendString("QUEST COMPLETE!", 275, 16+ 7); - } - } - - @Override - public void finish(Player player) { - super.finish(player); - player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); - player.getPacketDispatch().sendString("1125 Prayer XP", 277, 9 + 2); - player.getPacketDispatch().sendItemZoomOnInterface(964, 240, 277, 3 + 2); - player.getSkills().addExperience(Skills.PRAYER, 1125); - player.getInterfaceManager().closeChatbox(); - player.getPacketDispatch().sendString("You have completed The Restless Ghost Quest!", 277, 2 + 2); - setVarp(player, 728, 31, true); - player.getGameAttributes().removeAttribute("restless-ghost:urhney"); - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.kt new file mode 100644 index 000000000..a5d15a0d3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.kt @@ -0,0 +1,102 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost + +import core.game.node.entity.skill.Skills +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.item.Item +import core.plugin.Initializable +import core.api.* +import content.data.Quests +import org.rs09.consts.Items + +/** + * Represents the restless ghost quest. + * @author Beck, Vexia + */ +@Initializable +class RestlessGhost : Quest(Quests.THE_RESTLESS_GHOST, 25, 24, 1, 107, 0, 4, 5) { + + //This is required for some reason + override fun newInstance(obj: Any?): Quest { + return this + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + + when (stage) { + 0 -> { + player.packetDispatch.sendString("I can start this quest by speaking to Father Aereck in the", 275, 4 + 7) + player.packetDispatch.sendString("church next to Lumbridge Castle.", 275, 5 + 7) + player.packetDispatch.sendString("I must be unafraid of a Level 13 Skeleton.", 275, 6 + 7) + } + 10 -> { + player.packetDispatch.sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4 + 7) + player.packetDispatch.sendString("the graveyard next to the church.", 275, 5 + 7) + player.packetDispatch.sendString("I should find Father Urhney who is an expert on ghosts. ", 275, 6 + 7) + player.packetDispatch.sendString("He lives in a shack in Lumbridge Swamp.", 275, 7 + 7) + } + 20 -> { + player.packetDispatch.sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4 + 7) + player.packetDispatch.sendString("the graveyard next to the church.", 275, 5 + 7) + player.packetDispatch.sendString("I should find Father Urhney who is an expert on ghosts. ", 275, 6 + 7) + player.packetDispatch.sendString("He lives in a shack in Lumbridge Swamp.", 275, 7 + 7) + player.packetDispatch.sendString("I should talk to the Ghost to find out why it is haunting the", 275, 8 + 7) + player.packetDispatch.sendString("graveyard crypt", 275, 9 + 7) + } + 30 -> { + player.packetDispatch.sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4 + 7) + player.packetDispatch.sendString("the graveyard next to the church.", 275, 5 + 7) + player.packetDispatch.sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6 + 7) + player.packetDispatch.sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7 + 7) + player.packetDispatch.sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8 + 7) + player.packetDispatch.sendString("peace because an evil wizard had stolen his skull.", 275, 9 + 7) + player.packetDispatch.sendString("I should go and search the Wizard's Tower South West of", 275, 10 + 7) + player.packetDispatch.sendString("Lumbridge for the Ghost's Skull.", 275, 11 + 7) + } + 40 -> { + player.packetDispatch.sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4 + 7) + player.packetDispatch.sendString("the graveyard next to the church.", 275, 5 + 7) + player.packetDispatch.sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6 + 7) + player.packetDispatch.sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7 + 7) + player.packetDispatch.sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8 + 7) + player.packetDispatch.sendString("peace because an evil wizard had stolen his skull.", 275, 9 + 7) + player.packetDispatch.sendString("I found the Ghost's Skull in the basement of the Wizards'", 275, 10 + 7) + player.packetDispatch.sendString("Tower. It was guarded by a skeleton, but I took it anyways.", 275, 11 + 7) + player.packetDispatch.sendString("I should take the Skull back to the Ghost so it can rest.", 275, 12 + 7) + } + 100 -> { + player.packetDispatch.sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4 + 7) + player.packetDispatch.sendString("the graveyard next to the church.", 275, 5 + 7) + player.packetDispatch.sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6 + 7) + player.packetDispatch.sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7 + 7) + player.packetDispatch.sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8 + 7) + player.packetDispatch.sendString("peace because an evil wizard had stolen his skull.", 275, 9 + 7) + player.packetDispatch.sendString("I found the Ghost's Skull in the basement of the Wizards'", 275, 10 + 7) + player.packetDispatch.sendString("Tower. It was guarded by a skeleton, but I took it anyways.", 275, 11 + 7) + player.packetDispatch.sendString("I placed the Skull in the Ghost's coffin, and allowed it to", 275, 12 + 7) + player.packetDispatch.sendString("rest in peace once more, with gratitude for my help.", 275, 13 + 7) + player.packetDispatch.sendString("QUEST COMPLETE!", 275, 16 + 7) + } + } + } + + override fun finish(player: Player) { + super.finish(player) + + player.packetDispatch.sendString("1 Quest Point", 277, 8 + 2) + player.packetDispatch.sendString("1125 Prayer XP", 277, 9 + 2) + player.packetDispatch.sendItemZoomOnInterface(964, 240, 277, 3 + 2) + + player.skills.addExperience(Skills.PRAYER, 1125.0) + player.interfaceManager.closeChatbox() + + player.packetDispatch.sendString("You have completed The Restless Ghost Quest!", 277, 2 + 2) + + //post quest skeleton scenery and altar visually correct + setVarbit(player, 2128, 1, true) + setVarbit(player, 2130, 1, true) + + //setVarp(player, 728, 31, true) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java deleted file mode 100644 index 41b9f046b..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java +++ /dev/null @@ -1,252 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import content.data.Quests; -import core.game.node.entity.npc.NPC; -import core.plugin.Initializable; -import core.game.node.entity.player.Player; -import core.game.dialogue.DialoguePlugin; -import core.game.dialogue.FacialExpression; - -/** - * Handles the RestlessGhostDialogue dialogue. - * @author 'Vexia - */ -@Initializable -public class RestlessGhostDialogue extends DialoguePlugin { - - public RestlessGhostDialogue() { - - } - - public RestlessGhostDialogue(Player player) { - super(player); - } - - @Override - public DialoguePlugin newInstance(Player player) { - - return new RestlessGhostDialogue(player); - } - - @Override - public boolean open(Object... args) { - npc = (NPC) args[0]; - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello ghost, how are you?"); - stage = 0; - return true; - } - - @Override - public boolean handle(int interfaceId, int buttonId) { - switch (stage) { - case 0: - if (!player.getEquipment().contains(552, 1)) { - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooo wooo wooooo!"); - stage = 1; - } else { - if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 20) { - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Not very good actually."); - stage = 500; - break; - } - if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 30) { - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing finding my skull?"); - stage = 520; - break; - } - if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 40) { - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing finding my skull?"); - stage = 550; - break; - } - interpreter.sendDialogues(npc, null, "Fine, thanks."); - stage = 990; - } - break; - case 990: - end(); - break; - case 500: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's the problem then?"); - stage = 501; - break; - case 501: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Did you just understand what I said???"); - stage = 502; - break; - case 502: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yep, now tell me what the problem is."); - stage = 503; - break; - case 503: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "WOW! This is INCREDIBLE! I didn't expect anyone", "to ever understand me again!"); - stage = 504; - break; - case 504: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, Ok, I can understand you!"); - stage = 505; - break; - case 505: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "But have you any idea WHY you're doomed to be a", "ghost?"); - stage = 506; - break; - case 506: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, to be honest... I'm not sure."); - stage = 507; - break; - case 507: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I've been told a certain task may need to be completed", "so you can rest in peace."); - stage = 508; - break; - case 508: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I should think it is probably because a warlock has come", "along and stolen my skull. If you look inside my coffin", "there, you'll find my corpse without a head on it."); - stage = 509; - break; - case 509: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you know where this warlock might be now?"); - stage = 510; - break; - case 510: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I think it was one of the warlocks who lives in the big", "tower by the sea south-west from here."); - stage = 511; - break; - case 511: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok. I will try and get the skull back for you, then you", "can rest in peace."); - player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 30); - stage = 512; - break; - case 512: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ooh, thank you. That would be such a great relief!"); - stage = 513; - break; - case 513: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is so dull being a ghost..."); - stage = 514; - break; - case 514: - end(); - break; - case 520: - if (player.getInventory().contains(964, 1)) { - - break; - } else { - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I can't find it at the moment."); - stage = 521; - } - break; - case 521: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah well. Keep on looking."); - stage = 522; - break; - case 522: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm pretty sure it's somewhere in the tower south-west", "from here. There's a lot of levels to the tower, though. I", "suppose it might take a little while to find."); - stage = 523; - break; - case 523: - end(); - break; - case 550: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have found it!"); - stage = 551; - break; - case 551: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hurrah! Now I can stop being a ghost! You just need", "to put it on my coffin there, and I will be free!"); - stage = 523; - break; - case 1: - interpreter.sendOptions("Select an Option", "Sorry, I don't speak ghost.", "Ooh... THAT'S interesting.", "Any hints where I can find some treasure?"); - stage = 2; - break; - case 2: - switch (buttonId) { - case 1: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't speak ghost."); - stage = 10; - break; - case 2: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ooh... THAT'S interesting."); - stage = 20; - break; - case 3: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Any hints where I can find some treasure?"); - stage = 30; - break; - - } - break; - case 10: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo woo?"); - stage = 11; - break; - case 11: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nope, still don't understand you."); - stage = 12; - break; - case 12: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "WOOOOOOOOO!"); - stage = 13; - break; - case 13: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Never mind."); - stage = 14; - break; - case 14: - end(); - break; - case 30: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooooooo woo! Wooooo woo wooooo woowoowoo wooo", "Woo woooo. Wooooo woo woo? Wooooooooooooooooooo!"); - stage = 31; - break; - case 31: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't speak ghost."); - stage = 32; - break; - case 32: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo woo?"); - stage = 11; - break; - case 20: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo woooo. Woooooooooooooooooo!"); - stage = 21; - break; - case 21: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Did he really?"); - stage = 22; - break; - case 22: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo."); - stage = 23; - break; - case 23: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "My brother had EXACTLY the same problem."); - stage = 24; - break; - case 24: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo Wooooo!"); - stage = 25; - break; - case 25: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooooo Woo woo woo!"); - stage = 26; - break; - case 26: - interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye. Thanks for the chat."); - stage = 27; - break; - case 27: - interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooo wooo?"); - stage = 28; - break; - case 28: - end(); - break; - } - return true; - } - - @Override - public int[] getIds() { - return new int[] { 457 }; - } -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostListeners.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostListeners.kt new file mode 100644 index 000000000..2a98a16c0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostListeners.kt @@ -0,0 +1,276 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests +import core.api.* +import core.game.global.action.DropListener +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +/** +* Authenticity source Aug 18 2009 +* https://www.youtube.com/watch?v=ikbX12Xywxs +* https://www.youtube.com/watch?v=gC3qR9tKJMI +* * Author Beck, Vexia +**/ +class RestlessGhostListeners : InteractionListener { + + companion object { + private const val CLOSED_COFFIN = Scenery.COFFIN_2145 + private const val INCOMPLETE_COFFIN_OPEN = Scenery.COFFIN_15052 + private const val COMPLETE_COFFIN_OPEN = Scenery.COFFIN_15053 + private const val ALTAR_WITH_SKULL = Scenery.ALTAR_15050 + private const val ALTAR_NO_SKULL = Scenery.ALTAR_15051 + + private fun createRestlessGhostNPC() : NPC { + val restlessGhostNPC = NPC(NPCs.RESTLESS_GHOST_457, Location(3250, 3195, 0)) + restlessGhostNPC.setAttribute("spawned:npc", true) + restlessGhostNPC.isRespawn = false + restlessGhostNPC.direction = Direction.SOUTH + restlessGhostNPC.init() + restlessGhostNPC.isWalks = false + restlessGhostNPC.isNeverWalks = true + return restlessGhostNPC + } + + //Scenery 15057 changes to 15060 hidden and plays animation, resets in ~2mins if player still doing quest, otherwise it stays at 15060 forever + private fun animSkeleAlive(player: Player) { + + //set scenery to 15060 which hides the ground skeleton + setVarbit(player, 2128, 1, true) + + // TODO: Scenery skeleton id 15057 turns into a hidden 15060 then with an animation, uses varbit 2128, client side only + // TODO: find animation and maybe sfx of the skeleton coming alive, from a still scenery 15057 (15060 is the post animation?) of a skeleton slumped on the ground against the wall and then rises to life + // TODO: convert to queuescript on Scenery objects when engine is capable to be attached to them. + // https://www.youtube.com/watch?v=gC3qR9tKJMI + + // Use world pulse in the mean time, in the edge case where a player logs off in middle of the script + if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) in 30..40) { + submitWorldPulse(object : Pulse(200) { + override fun pulse(): Boolean { + //resets the skeleton on the ground + setVarbit(player, 2128, 0, true) + return true + } + }) + } + } + + private fun createLevel13SkeletonNPC(player: Player) : NPC { + val skele = NPC(NPCs.SKELETON_459, Location(3120, 9568, 0)) + skele.setAttribute("spawned:npc", true) + skele.setAttribute("target", player) + skele.isRespawn = false + skele.init() + skele.properties.combatPulse.style = CombatStyle.MELEE + skele.attack(player) + + return skele + } + + fun toggleCoffinSceneryObj(player: Player, coffin: core.game.node.scenery.Scenery) { + + lock(player, 2) + + when (coffin.id) { + //opened + COMPLETE_COFFIN_OPEN, + INCOMPLETE_COFFIN_OPEN -> { + //close it + visualize(player, Animations.HUMAN_CLOSE_CHEST_535, -1) + SceneryBuilder.replace(coffin, coffin.transform(CLOSED_COFFIN)) + } + CLOSED_COFFIN -> { + //open it + visualize(player, Animations.HUMAN_OPEN_CHEST_536, -1) + + if (isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) { + //full skele with skull + SceneryBuilder.replace(coffin, coffin.transform(COMPLETE_COFFIN_OPEN)) + } else { + SceneryBuilder.replace(coffin, coffin.transform(INCOMPLETE_COFFIN_OPEN)) + } + } + } + + } + } + + override fun defineListeners() { + on(CLOSED_COFFIN, IntType.SCENERY, "open") { player, node -> + + sendMessage(player, "You open the coffin.") + + playGlobalAudio(player.location, Sounds.COFFIN_OPEN_54) + + toggleCoffinSceneryObj(player, node as core.game.node.scenery.Scenery) + + if (!isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) { + val ghostExists = RegionManager.getLocalNPCs(node.centerLocation).find { it.id == NPCs.RESTLESS_GHOST_457 } + + //not within rendering distance or doesn't exist at all + if (ghostExists == null) { + //spawn the ghost in + val ghost = createRestlessGhostNPC() + + //despawn ghost after awhile and shut the coffin + // TODO: convert to queuescript on Scenery objects when engine is capable to be attached to them. + // Use world pulse in the mean time, in the edge case where a player logs off in middle of the script + /* queueScript(player, 200) { _ -> + ghost.clear() + toggleCoffinSceneryObj(player, node) + return@queueScript stopExecuting(player) + } */ + + submitWorldPulse(object : Pulse(200) { + override fun pulse(): Boolean { + ghost.clear() + toggleCoffinSceneryObj(player, node) + return true + } + }) + } + } + + return@on true + } + + onUseWith(IntType.SCENERY, Items.GHOSTS_SKULL_553, CLOSED_COFFIN) { player, used, with -> + sendMessage(player, "Maybe I should open it first.") + return@onUseWith true + } + + on(COMPLETE_COFFIN_OPEN, IntType.SCENERY, "close") { player, node -> + + sendMessage(player, "You close the coffin.") + playGlobalAudio(player.location, Sounds.COFFIN_CLOSE_53) + toggleCoffinSceneryObj(player, node as core.game.node.scenery.Scenery) + + return@on true + } + + on(COMPLETE_COFFIN_OPEN, IntType.SCENERY, "search") { player, node -> + sendDialogue(player, "There's a nice and complete skeleton in here!") + return@on true + } + + on(INCOMPLETE_COFFIN_OPEN, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the coffin and find some human remains.") + return@on true + } + + on(INCOMPLETE_COFFIN_OPEN, IntType.SCENERY, "close") { player, node -> + + sendMessage(player, "You close the coffin.") + playGlobalAudio(player.location, Sounds.COFFIN_CLOSE_53) + toggleCoffinSceneryObj(player, node as core.game.node.scenery.Scenery) + + return@on true + } + + onUseWith(IntType.SCENERY, Items.GHOSTS_SKULL_553, INCOMPLETE_COFFIN_OPEN) { player, used, with -> + if (removeItem(player, used)) { + sendItemDialogue(player, Items.GHOSTS_SKULL_553, "You put the skull in the coffin.") + finishQuest(player, Quests.THE_RESTLESS_GHOST) + + with as core.game.node.scenery.Scenery + SceneryBuilder.replace(with, with.transform(COMPLETE_COFFIN_OPEN)) + } + + return@onUseWith true + } + + on(ALTAR_WITH_SKULL, IntType.SCENERY, "search") { player, node -> + + if (!inInventory(player, Items.GHOSTS_SKULL_553) && !inBank(player, Items.GHOSTS_SKULL_553)) { + if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) !in 30..40) { + sendMessage(player, "You search the altar and find nothing.") + } else { + if (freeSlots(player) >= 1) { + if (addItem(player, Items.GHOSTS_SKULL_553)) { + setQuestStage(player, Quests.THE_RESTLESS_GHOST, 40) + + //update altar to without the skull, altar is now scenery 15051 + setVarbit(player, 2130, 1, true) + + //if skeleton scenery is visible such first time coming alive + //so that it can only be killed/spawned to attack once to prevent some sort of griefing exploit + if (getVarbit(player, 2128) == 0) { + sendMessage(player, "The skeleton in the corner suddenly comes to life!") + + animSkeleAlive(player) + + //spawn in skeleton + val s = createLevel13SkeletonNPC(player) + + // despawn after awhile if it never dies so there isnt a group of them for next visitor lol + + // TODO: convert to queuescript on Scenery objects when engine is capable to be attached to them. + // Use world pulse in the mean time, in the edge case where a player logs off in middle of the script + + /* queueScript(player, 200) { _ -> + s.clear() + return@queueScript stopExecuting(player) + } */ + + submitWorldPulse(object : Pulse(200) { + override fun pulse(): Boolean { + s.clear() + return true + } + }) + } + } + } else { + sendMessage(player, "You don't have enough inventory space.") + } + } + } + + return@on true + } + + on(ALTAR_NO_SKULL, IntType.SCENERY, "search") { player, node -> + //Mainly for a weird edge case if some how the varbit wasn't set correctly + if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) !in 30..40) { + sendMessage(player, "You search the altar and find nothing.") + } else { + if (!inInventory(player, Items.GHOSTS_SKULL_553) && !inBank(player, Items.GHOSTS_SKULL_553)) { + //guard clause if for when player does the drop trick, etc + if (!addItem(player, Items.GHOSTS_SKULL_553)) { + sendMessage(player, "You don't have enough inventory space.") + } + } else { + // TODO: Authenticity check needed for exact message + sendMessage(player, "You already have the Ghost's Skull!") + } + } + return@on true + } + + on(Items.GHOSTS_SKULL_553, IntType.ITEM, "drop") { player, node -> + DropListener.drop(player, node.asItem()) + + if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) in 30..40) { + //update altar to one with the skull, altar is now scenery 15060 + setVarbit(player, 2130, 0, true) + } + + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostNPCDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostNPCDialogue.kt new file mode 100644 index 000000000..619db934d --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostNPCDialogue.kt @@ -0,0 +1,156 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests +import core.api.getQuestStage +import core.api.inEquipment +import core.api.inInventory +import core.api.setQuestStage +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.npc.NPC +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class RestlessGhostNPCDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.RESTLESS_GHOST_457, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, RestlessGhostNPCDialogueFile(), node as NPC) + return@on true + } + } +} + +class RestlessGhostNPCDialogueFile : DialogueLabeller() { + override fun addConversation() { + player(FacialExpression.HALF_GUILTY, "Hello ghost, how are you?") + + exec { player, npc -> + if (!inEquipment(player, Items.GHOSTSPEAK_AMULET_552)) { + loadLabel(player, "woo") + } else { + when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) { + 20 -> { + loadLabel(player, "not_very_good") + } + 30, 40 -> { + loadLabel(player, "finding_my_skull") + } + } + } + } + + npc("Fine, thanks.") + + label("finding_my_skull") { + npc("How are you doing finding my skull?") + + exec { player, npc -> + if (inInventory(player, Items.GHOSTS_SKULL_553)) { + loadLabel(player, "found_it") + } else { + loadLabel(player, "not_found_it") + } + } + } + + label("found_it") { + player(FacialExpression.FRIENDLY, "I have found it!") + npc(FacialExpression.HAPPY, "Hurrah! Now I can stop being a ghost! You just need", "to put it on my coffin there, and I will be free!") + } + + label("not_found_it") { + player(FacialExpression.HALF_GUILTY, "Sorry, I can't find it at the moment.") + npc(FacialExpression.HALF_GUILTY, "Ah well. Keep on looking.") + npc(FacialExpression.HALF_GUILTY, "I'm pretty sure it's somewhere in the tower south-west", "from here. There's a lot of levels to the tower, though. I", "suppose it might take a little while to find.") + } + + label("not_very_good") { + npc(FacialExpression.HALF_WORRIED, "Not very good actually.") + player(FacialExpression.HALF_ASKING, "What's the problem then?") + npc(FacialExpression.THINKING, "Did you understand what I said???") + player(FacialExpression.FRIENDLY, "Yep, now tell me what the problem is.") + npc(FacialExpression.AMAZED, "WOW! This is INCREDIBLE! I didn't expect anyone", "to ever understand me again!") + player(FacialExpression.FRIENDLY, "Ok, Ok, I can understand you!") + player(FacialExpression.HALF_ASKING, "But have you any idea WHY you're doomed to be a", "ghost?") + npc(FacialExpression.HALF_GUILTY, "Well, to be honest... I'm not sure.") + player(FacialExpression.FRIENDLY, "I've been told a certain task may need to be completed", "so you can rest in peace.") + npc(FacialExpression.HALF_GUILTY, "I should think it is probably because a warlock has come", "along and stolen my skull. If you look inside my coffin", "there, you'll find my corpse without a head on it.") + player(FacialExpression.HALF_ASKING, "Do you know where this warlock might be now?") + npc(FacialExpression.HALF_GUILTY, "I think it was one of the warlocks who lives in the big", "tower by the sea south-west from here.") + player(FacialExpression.FRIENDLY, "Ok. I will try and get the skull back for you, then you", "can rest in peace.") + + exec { player, npc -> + setQuestStage(player, Quests.THE_RESTLESS_GHOST, 30) + loadLabel(player, "great_relief") + } + } + + label("great_relief") { + npc(FacialExpression.HALF_WORRIED, "Ooh, thank you. That would be such a great relief!") + npc(FacialExpression.SAD, "It is so dull being a ghost...") + } + + label("woo") { + npc(ChatAnim.HALF_GUILTY, "Wooo wooo wooooo!") + goto("no_amulet_opts") + } + + label("no_amulet_opts") { + options( + DialogueOption( + "dont_speak_ghost", + "Sorry, I don't speak ghost.", + expression = ChatAnim.HALF_GUILTY + ), + DialogueOption( + "thats_interesting", + "Ooh... THAT's interesting.", + expression = ChatAnim.HALF_GUILTY + ), + DialogueOption( + "find_treasure", + "Any hints where I can find some treasure?", + ) + ) + } + + label("dont_speak_ghost") { + npc(FacialExpression.HALF_GUILTY, "Woo woo?") + player(FacialExpression.HALF_GUILTY, "Nope, still don't understand you.") + + npc(FacialExpression.HALF_GUILTY, "WOOOOOOOOO!") + player(FacialExpression.HALF_GUILTY, "Never mind.") + } + + label("thats_interesting") { + npc(FacialExpression.HALF_GUILTY, "Woo woooo. Woooooooooooooooooo!") + player(FacialExpression.HALF_GUILTY, "Did he really?") + + npc(FacialExpression.HALF_GUILTY, "Woo.") + player(FacialExpression.HALF_GUILTY, "My brother had EXACTLY the same problem.") + + npc(FacialExpression.HALF_GUILTY, "Woo Wooooo!") + npc(FacialExpression.HALF_GUILTY, "Wooooo Woo woo woo!") + + player(FacialExpression.HALF_GUILTY, "Goodbye. Thanks for the chat.") + npc(FacialExpression.HALF_GUILTY, "Wooo wooo?") + } + + label("find_treasure") { + npc(FacialExpression.HALF_GUILTY, "Wooooooo woo! Wooooo woo wooooo woowoowoo wooo", "Woo woooo. Wooooo woo woo? Wooooooooooooooooooo!") + player(FacialExpression.HALF_GUILTY, "Sorry, I don't speak ghost.") + + npc(FacialExpression.HALF_GUILTY, "Woo woo?") + player(FacialExpression.HALF_GUILTY, "Nope, still don't understand you.") + + npc(FacialExpression.HALF_GUILTY, "WOOOOOOOOO!") + player(FacialExpression.HALF_GUILTY, "Never mind.") + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java deleted file mode 100644 index d19f260a1..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java +++ /dev/null @@ -1,273 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import content.data.Quests; -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.CombatStyle; -import core.game.node.entity.npc.AbstractNPC; -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.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.plugin.Initializable; -import core.plugin.Plugin; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the restless ghost plugin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class RestlessGhostPlugin extends OptionHandler { - - /** - * Represents the close animation of a content. - */ - private static final Animation OPEN_ANIM = new Animation(536); - - /** - * Represents the close animation of a content. - */ - private static final Animation CLOSE_ANIM = new Animation(535); - - /** - * Represents the skull item. - */ - private static final Item SKULL = new Item(964); - - /** - * Represents the ghost npc spawned. - */ - private static RestlessGhostNPC GHOST; - - /** - * Represents the coffin inds. - */ - private static final int[] COFFIN_IDS = new int[] { 2145, 15061, 15052, 15053, 15050, 15051 }; - - /** - * Represents the options. - */ - private static final String[] OPTIONS = new String[] { "open", "close", "search" }; - - @Override - public Plugin newInstance(Object arg) throws Throwable { - for (int coffin : COFFIN_IDS) { - for (String option : OPTIONS) { - SceneryDefinition.forId(coffin).getHandlers().put("option:" + option, this); - } - } - new RestlessGhostNPC().newInstance(arg); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - if (GHOST == null) { - GHOST = new RestlessGhostNPC(457, Location.create(3250, 3195, 0)); - GHOST.init(); - GHOST.setInvisible(true); - } - final int id = ((Scenery) node).getId(); - final Scenery object = (Scenery) node; - switch (option) { - case "open": - switch (id) { - default: - toggleCoffin(player, object); - break; - } - case "close": - switch (id) { - case 15052: - case 15053: - toggleCoffin(player, object); - break; - } - break; - case "search": - switch (id) { - case 15052: - player.getPacketDispatch().sendMessage("You search the coffin and find some human remains."); - break; - case 15053: - player.getDialogueInterpreter().sendDialogue("There's a nice and complete skeleton in here!"); - break; - case 15050: - searchAltar(player, object); - break; - case 15051: - if (!player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST) && !player.getBank().containsItem(SKULL) && !player.getInventory().containsItem(SKULL)) { - player.getInventory().add(SKULL); - player.getPacketDispatch().sendMessage("You find another skull."); - } - player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 40); - break; - case 2145: - toggleCoffin(player, object); - break; - } - break; - } - return true; - } - - /** - * Method used to toggle the coffin. - * @param player the player. - * @param object the object. - */ - private void toggleCoffin(final Player player, final Scenery object) { - final boolean open = object.getId() == 2145; - player.lock(2); - player.animate(open ? OPEN_ANIM : CLOSE_ANIM); - SceneryBuilder.replace(object, object.transform(open ? 15061 : 2145)); - player.getPacketDispatch().sendMessage("You " + (open ? "open" : "close") + " the coffin."); - if (open && !player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { - sendGhost(); - } - } - - /** - * Method used to send the restless ghost npc. - */ - private void sendGhost() { - if (!GHOST.isInvisible()) { - return; - } - GHOST.setInvisible(false); - GameWorld.getPulser().submit(new Pulse(100, GHOST) { - @Override - public boolean pulse() { - GHOST.setInvisible(true); - return true; - } - }); - } - - /** - * Method used to search the altar. - * @param player the player. - * @param object the object. - */ - private void searchAltar(final Player player, final Scenery object) { - final boolean hasSkull = object.getId() == 15051; - if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) != 30) { - player.getPacketDispatch().sendMessage("You search the altar and find nothing."); - return; - } - if (!hasSkull) { - if (!player.getInventory().add(SKULL)) { - GroundItemManager.create(SKULL, player); - } - setVarp(player, 728, 5, true); - player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 40); - player.getPacketDispatch().sendMessage("The skeleton in the corner suddenly comes to life!"); - sendSkeleton(player); - } - } - - /** - * Method used to send the skeleton. - * @param player the player. - */ - private void sendSkeleton(final Player player) { - final NPC skeleton = NPC.create(459, Location.create(3120, 9568, 0)); - skeleton.setWalks(false); - skeleton.setRespawn(false); - skeleton.setAttribute("player", player); - skeleton.init(); - skeleton.getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); - skeleton.getProperties().getCombatPulse().attack(player); - } - - /** - * Handles the temple guardian npc. - * @author 'Vexia - */ - public static final class RestlessGhostNPC extends AbstractNPC { - - /** - * The NPC ids of NPCs using this plugin. - */ - private static final int[] ID = { 459, 457 }; - - /** - * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. - */ - public RestlessGhostNPC() { - super(0, null); - } - - /** - * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. - * @param id The NPC id. - * @param location The location. - */ - private RestlessGhostNPC(int id, Location location) { - super(id, location, false); - } - - @Override - public AbstractNPC construct(int id, Location location, Object... objects) { - return new RestlessGhostNPC(id, location); - } - - @Override - public void init() { - super.init(); - this.getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); - } - - @Override - public void tick() { - super.tick(); - final Player pl = getAttribute("player", null); - if (pl != null) { - if (getAttribute("dead", false) || !getLocation().withinDistance(pl.getLocation(), 16)) { - clear(); - return; - } - } - } - - @Override - public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { - final Player player = ((Player) entity); - final Player pl = getAttribute("player", null); - return pl == null ? false : pl == player ? true : false; - } - - @Override - public void finalizeDeath(Entity killer) { - super.finalizeDeath(killer); - removeAttribute("player"); - } - - @Override - public boolean isHidden(final Player player) { - final Player pl = getAttribute("player", null); - if (this.getRespawnTick() > GameWorld.getTicks()) { - return true; - } - return player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST) || (pl != null && player != pl); - } - - @Override - public int[] getIds() { - return ID; - } - - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java deleted file mode 100644 index 4a899c64a..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java +++ /dev/null @@ -1,51 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import content.data.Quests; -import core.api.Container; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.scenery.Scenery; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Items; - -import static core.api.ContentAPIKt.removeItem; - -/** - * Represents the plugin used to add the skull to the cofin. - * @author 'Vexia - * @version 1.0 - */ -@Initializable -public final class RestlessGhostSkull extends UseWithHandler { - - /** - * Constructs a new {@code RestlessGhostSkull} {@code Object}. - */ - public RestlessGhostSkull() { - super(964); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - addHandler(2145, OBJECT_TYPE, this); - addHandler(15052, OBJECT_TYPE, this); - addHandler(15061, OBJECT_TYPE, this); - return this; - } - - @Override - public boolean handle(NodeUsageEvent event) { - final Scenery object = (Scenery) event.getUsedWith(); - if (object.getId() == 2145) { - event.getPlayer().getDialogueInterpreter().sendDialogue("Maybe I should open it first."); - return true; - } - if (removeItem(event.getPlayer(), Items.SKULL_964, Container.INVENTORY)) { - event.getPlayer().getPacketDispatch().sendMessage("You put the skull in the coffin."); - event.getPlayer().getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).finish(event.getPlayer()); - } - return true; - } - -} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/SkullDropPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/SkullDropPlugin.java deleted file mode 100644 index 0fdaf0b68..000000000 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/SkullDropPlugin.java +++ /dev/null @@ -1,32 +0,0 @@ -package content.region.misthalin.lumbridge.quest.therestlessghost; - -import core.cache.def.impl.ItemDefinition; -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; - -/* - * 8 - */ -@Initializable -public class SkullDropPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ItemDefinition.forId(964).getHandlers().put("option:drop", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - player.getPacketDispatch().sendMessage("You can't drop this! Return it to the ghost."); - return true; - } - - @Override - public boolean isWalk() { - return false; - } -}