diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt index f43ac6bed..acc48c6f6 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt @@ -215,8 +215,7 @@ class EWListeners : InteractionListener { /* * * * * * * * * * * * * * * * * Workshop Area listeners * * * * * * * * * * * * * * * */ - // Center hatch, inaccessible - // NOTE: REMOVE ME/ADD CORRECT CHECKS FOR ELEMENTAL WORKSHOP II + // Center hatch, inaccessible until unlocked during EW2 on(Scenery.HATCH_18595, IntType.SCENERY, "open") { player, _ -> sendDialogue(player, "You're unable to open the locked hatch.") return@on true @@ -258,41 +257,135 @@ class EWListeners : InteractionListener { } // Workbenches/Anvil + // Before completing EW1 you can only smith and elemental shield. During EW2 you have the option to make a shield, claw, or helm. onUseWith(IntType.SCENERY, Items.ELEMENTAL_METAL_2893, Scenery.WORKBENCH_3402) { player, used, workbench -> - // Warn player their smithing level is too low to make the shield - if (player.skills.getLevel(Skills.SMITHING) < 20) { - sendMessage(player, "You need a smithing level of 20 to create an elemental shield.") - return@onUseWith true - } - // Warn player they don't have the required book in their inventory - if (!player.inventory.containsAtLeastOneItem(intArrayOf(Items.SLASHED_BOOK_9715, Items.BATTERED_BOOK_2886))) { - sendDialogue(player, "This workbench is too complicated. You need instructions to follow.") - return@onUseWith true - } - // Warn player they don't have a hammer in their inventory - if (!inInventory(player, Items.HAMMER_2347)) { - sendDialogue(player, "You don't have a tool available to shape the metal.") - return@onUseWith true - } - // Sanity error check (Should never get thrown) - if (!player.inventory.containsAll(*elementalShieldReqItems)) { - log(this::class.java, Log.ERR, "${player.username} tried to forge an elemental shield without all the required items.") - return@onUseWith false - } - // Successfully smith the elemental shield - lock(player, (animationDuration(smithElementalShield) + 2)) - runTask(player) { - face(player, workbench) - animate(player, smithElementalShield) - playAudio(player, smithElementalShieldSFX) - replaceSlot(player, used.asItem().slot, elementalShield) - rewardXP(player, Skills.SMITHING, 20.0) - sendMessage(player, "Following the instructions in the book you make an elemental shield.") - } - // Check to see if the quest is completed, if not, complete the quest - if (!player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).isCompleted(player)) { - player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).finish(player) + // if elemental workshop II is in progress, display a dialogue. otherwise, revert to smithing the elemental shield only. + if(getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) >= 5) { + sendDialogueOptions(player, "What would you like to make...", "An elemental shield.", "An elemental claw.", "An elemental helm.") + addDialogueAction(player) { _, buttonId -> + when (buttonId) { + 2 -> { // ele shield + // Warn player their smithing level is too low to make the shield + if (player.skills.getLevel(Skills.SMITHING) < 20) { + sendMessage(player, "You need a smithing level of 20 to create an elemental shield.") + return@addDialogueAction + } + // Warn player they don't have the required book in their inventory + if (!player.inventory.containsAtLeastOneItem(intArrayOf(Items.SLASHED_BOOK_9715, Items.BATTERED_BOOK_2886))) { + sendDialogue(player, "This workbench is too complicated. You need instructions to follow.") + return@addDialogueAction + } + // Warn player they don't have a hammer in their inventory + if (!inInventory(player, Items.HAMMER_2347)) { + sendDialogue(player, "You don't have a tool available to shape the metal.") + return@addDialogueAction + } + // Successfully smith the elemental shield + lock(player, (animationDuration(smithElementalShield) + 2)) + runTask(player) { + face(player, workbench) + animate(player, smithElementalShield) + playAudio(player, smithElementalShieldSFX) + replaceSlot(player, used.asItem().slot, elementalShield) + rewardXP(player, Skills.SMITHING, 20.0) + sendMessage(player, "Following the instructions in the book you make an elemental shield.") + } + } + 3 -> { // ele claw + // Warn player their smithing level is too low to make the shield + if (player.skills.getLevel(Skills.SMITHING) < 20) { + sendMessage(player, "You need a smithing level of 20 to create an elemental claw.") + return@addDialogueAction + } + // Warn player they don't have the required book in their inventory + if (!player.inventory.containsAtLeastOneItem(intArrayOf(Items.CRANE_SCHEMATIC_9718))) { + sendDialogue(player, "This workbench is too complicated. You need instructions to follow.") + return@addDialogueAction + } + // Warn player they don't have a hammer in their inventory + if (!inInventory(player, Items.HAMMER_2347)) { + sendDialogue(player, "You don't have a tool available to shape the metal.") + return@addDialogueAction + } + // Successfully smith the elemental shield + lock(player, (animationDuration(smithElementalShield) + 2)) + runTask(player) { + face(player, workbench) + animate(player, smithElementalShield) + playAudio(player, smithElementalShieldSFX) + replaceSlot(player, used.asItem().slot, Item(Items.CRANE_CLAW_9720)) + rewardXP(player, Skills.SMITHING, 20.0) + sendMessage(player, "Following the instructions from the schematic you make an elemental claw.") + } + } + 4 -> { // ele helm + // Warn player their smithing level is too low to make the helm + if (player.skills.getLevel(Skills.SMITHING) < 30) { + sendMessage(player, "You need a smithing level of 30 to create an elemental helm.") + return@addDialogueAction + } + // Warn player they don't have the required book in their inventory + if (!player.inventory.containsAtLeastOneItem(intArrayOf(Items.BEATEN_BOOK_9717))) { + sendDialogue(player, "This workbench is too complicated. You need instructions to follow.") + return@addDialogueAction + } + // Warn player they don't have a hammer in their inventory + if (!inInventory(player, Items.HAMMER_2347)) { + sendDialogue(player, "You don't have a tool available to shape the metal.") + return@addDialogueAction + } + // Successfully smith the elemental helm + lock(player, (animationDuration(smithElementalShield) + 2)) + runTask(player) { + face(player, workbench) + animate(player, smithElementalShield) + playAudio(player, smithElementalShieldSFX) + replaceSlot(player, used.asItem().slot, Item(Items.ELEMENTAL_HELMET_9729)) + rewardXP(player, Skills.SMITHING, 20.0) + sendMessage(player, "Following the instructions in the book you make an elemental helm.") + } + } + } + } + + // EW1 fallback + } else { + // Warn player their smithing level is too low to make the shield + if (player.skills.getLevel(Skills.SMITHING) < 20) { + sendMessage(player, "You need a smithing level of 20 to create an elemental shield.") + return@onUseWith true + } + // Warn player they don't have the required book in their inventory + if (!player.inventory.containsAtLeastOneItem(intArrayOf(Items.SLASHED_BOOK_9715, Items.BATTERED_BOOK_2886))) { + sendDialogue(player, "This workbench is too complicated. You need instructions to follow.") + return@onUseWith true + } + // Warn player they don't have a hammer in their inventory + if (!inInventory(player, Items.HAMMER_2347)) { + sendDialogue(player, "You don't have a tool available to shape the metal.") + return@onUseWith true + } + // Sanity error check (Should never get thrown) + if (!player.inventory.containsAll(*elementalShieldReqItems)) { + log(this::class.java, Log.ERR, "${player.username} tried to forge an elemental shield without all the required items.") + return@onUseWith false + } + // Successfully smith the elemental shield + lock(player, (animationDuration(smithElementalShield) + 2)) + runTask(player) { + face(player, workbench) + animate(player, smithElementalShield) + playAudio(player, smithElementalShieldSFX) + replaceSlot(player, used.asItem().slot, elementalShield) + rewardXP(player, Skills.SMITHING, 20.0) + sendMessage(player, "Following the instructions in the book you make an elemental shield.") + } + // Check to see if the quest is completed, if not, complete the quest + if (!player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).isCompleted(player)) { + player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).finish(player) + } } + return@onUseWith true } diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/BeatenBook.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/BeatenBook.kt index 481d92f11..cafc8526f 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/BeatenBook.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/BeatenBook.kt @@ -1,4 +1,227 @@ package content.region.kandarin.seers.quest.elementalworkshop2 -class BeatenBook { +import content.data.Quests +import content.global.handlers.iface.* +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2Varbit +import core.game.interaction.InteractionListener +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Starts the Elemental Workshop II Quest + * Found at Dig Site Library + */ + +class BeatenBook : InteractionListener { + companion object { + private const val TITLE = "Book of the Elemental Helm" + private val CONTENTS = arrayOf( + // pages 1-2 + PageSet( + Page( + BookLine("This is the second book in", 55), + BookLine("a series which aims to", 56), + BookLine("preserve the knowledge", 57), + BookLine("gained by artisans of the", 58), + BookLine("early Fifth Age. A", 59), + BookLine("thorough grasp of the", 60), + BookLine("processes and techniques", 61), + BookLine("described in my earlier", 62), + BookLine("work, 'Book of the", 63), + BookLine("Elemental Shield', is", 64), + BookLine("necessary to comprehend", 65), + ), + Page( + BookLine("the concepts involved in", 66), + BookLine("the more technical", 67), + BookLine("chapters of this book.", 68), + BookLine("", 69), + BookLine("", 70), + BookLine("", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76), + ) + ), + // pages 3-4 + PageSet( + Page( + BookLine("Some years following the", 55), + BookLine("original discovery of the", 56), + BookLine("elemental ore, further", 57), + BookLine("investigation was", 58), + BookLine("performed by a", 59), + BookLine("metallurgist called", 60), + BookLine("Vitruvius in collaboration", 61), + BookLine("with a freelance mage.", 62), + BookLine("Over the course of two", 63), + BookLine("years they did many", 64), + BookLine("tests on the ore and", 65), + ), + Page( + BookLine("refined metal, aiming to", 66), + BookLine("optimise the process by", 67), + BookLine("which the metal was", 68), + BookLine("extracted from its impure", 69), + BookLine("ore. From the data they", 70), + BookLine("gathered, they discovered", 71), + BookLine("the optimum temperature", 72), + BookLine("and carbon/ore ratio for", 73), + BookLine("the production of", 74), + BookLine("elemental metal of the", 75), + BookLine("highest quality. The", 76), + ) + ), + // pages 5-6 + PageSet( + Page( + BookLine("quality of the resulting", 55), + BookLine("metal was assessed on the", 56), + BookLine("basis of its ultimate tensile", 57), + BookLine("strength, hardness (as", 58), + BookLine("compared to a standard", 59), + BookLine("diamond-tipped probe),", 60), + BookLine("magical absorption", 61), + BookLine("capacity per unit mass,", 62), + BookLine("grain size and elastic", 63), + BookLine("deformation modulus.", 64), + BookLine("Their most significant", 65), + ), + Page( + BookLine("discovery in this period,", 66), + BookLine("however, was the novel", 67), + BookLine("technique of 'priming' the", 68), + BookLine("ore.", 69), + BookLine("", 70), + BookLine("", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76), + ) + ), + // pages 7-8 + PageSet( + Page( + BookLine("At the time, the", 55), + BookLine("significance of priming", 56), + BookLine("was not fully appreciated.", 57), + BookLine("However, the records kept", 58), + BookLine("by Vitruvius state that his", 59), + BookLine("apprentice, in an", 60), + BookLine("unsuccessful attempt to", 61), + BookLine("animate a small ingot of", 62), + BookLine("elemental metal as part of", 63), + BookLine("a student prank,", 64), + BookLine("accidentally instilled his", 65), + ), + Page( + BookLine("entire consciousness into", 66), + BookLine("the primed ingot. An", 67), + BookLine("unfortunate side-effect of", 68), + BookLine("this process was to", 69), + BookLine("reduce the apprentice's", 70), + BookLine("body to a dead shell.", 71), + BookLine("Attempts to return his", 72), + BookLine("consciousness to his body", 73), + BookLine("were regrettably", 74), + BookLine("unsuccessful.", 75), + BookLine("", 76), + ) + ), + // pages 9-10 + PageSet( + Page( + BookLine("Vitruvius discovered that", 55), + BookLine("the mental energy was so", 56), + BookLine("firmly bound to the", 57), + BookLine("elemental metal that no", 58), + BookLine("dissipation was detectable.", 59), + BookLine("Similar experiments with", 60), + BookLine("unprimed bars initially", 61), + BookLine("yielded comparable", 62), + BookLine("results, but the mental", 63), + BookLine("energy quickly left the", 64), + BookLine("bars and dissipated within", 65), + ), + Page( + BookLine("such a short period that", 66), + BookLine("no practical applications", 67), + BookLine("seemed feasible. However", 68), + BookLine("the primed elemental", 69), + BookLine("metal showed considerably", 70), + BookLine("more promise.", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76), + ) + ), + // pages 11-12 + PageSet( + Page( + BookLine("Researchers have", 55), + BookLine("continued to use the", 56), + BookLine("terminology defined by", 57), + BookLine("Vitruvius for this field of", 58), + BookLine("study. In his own", 59), + BookLine("notebooks, Vitruvius", 60), + BookLine("referred to his", 61), + BookLine("preparation technique as", 62), + BookLine("'priming', and he referred", 63), + BookLine("to his apprentice as 'Idiot'", 64), + BookLine("", 65), + ), + Page( + BookLine("", 66), + BookLine("", 67), + BookLine("", 68), + BookLine("", 69), + BookLine("", 70), + BookLine("", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.BEATEN_BOOK_9717, IntType.ITEM, "read") { player, _ -> + // the first time you open the book, the scroll will drop. + if (getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) == 1) { + addItemOrDrop(player, Items.SCROLL_9721) + sendMessage(player, "The book has two parts; an introduction and an instruction section.") + sendMessage(player, "You flip the book open to the introduction and start reading.") + + // todo the dialogue and openbook should run sequentially, but i've messed around with queuescript and can't figure it out. + // this also applies to EW1 listener that gives the slashed book and battered key back in EWListeners.kt + sendItemDialogue(player, Items.SCROLL_9721, "You find a slip of paper that has been used for a bookmark. You put it in your pack to study later.") + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 2) + setVarbit(player, EW2Varbit, 2, true) + // storeBookInHouse(player, node) // todo uncomment this when poh costume room is in + } else { + // storeBookInHouse(player, node) // todo uncomment this when poh costume room is in + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + } + return@on true + } + } } \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/EW2Listeners.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/EW2Listeners.kt index 866cf47aa..732a1a7d2 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/EW2Listeners.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/EW2Listeners.kt @@ -1,11 +1,20 @@ package content.region.kandarin.seers.quest.elementalworkshop2 import content.data.Quests +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2CranePos +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2CraneState +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2HatchVarbit +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2MachineryVarbit import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2Varbit import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.build.LandscapeParser.removeScenery import org.rs09.consts.* class EW2Listeners : InteractionListener { @@ -16,18 +25,290 @@ class EW2Listeners : InteractionListener { on(Scenery.BOOKCASE_17382, IntType.SCENERY, "search") { player, _ -> if (isQuestComplete(player, Quests.ELEMENTAL_WORKSHOP_I) && !inInventory(player, Items.BEATEN_BOOK_9717) && + !inBank(player, Items.BEATEN_BOOK_9717) && hasLevelStat(player, Skills.MAGIC, 20) && hasLevelStat(player, Skills.SMITHING, 30) ) { sendItemDialogue(player, Items.BEATEN_BOOK_9717, "You find an old-looking book.") addItemOrDrop(player, Items.BEATEN_BOOK_9717) - //setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 1) - setVarbit(player, EW2Varbit, 1, true) + + if(getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) == 0) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 1) + setVarbit(player, EW2Varbit, 1, true) + } } else { sendMessage(player, "You search the books...") sendMessage(player, "You find nothing of interest.") } return@on true } + + // the scroll that drops with the beaten book + on(Items.SCROLL_9721, IntType.ITEM, "read") { player, _ -> + openInterface(player, 222) + setInterfaceText(player, "", 222, 1) + setInterfaceText(player, "Down", 222, 2) + setInterfaceText(player, "2 N", 222, 3) + setInterfaceText(player, "2 E", 222, 4) + setInterfaceText(player, "2 N", 222, 5) + setInterfaceText(player, "2 E", 222, 6) + setInterfaceText(player, "10 N", 222, 7) + setInterfaceText(player, "4 W", 222, 8) + setInterfaceText(player, "Pipe 3.", 222, 9) + + if(getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) == 2) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 3) + setVarbit(player, EW2Varbit, 3, true) + } + if(getVarbit(player, EW2MachineryVarbit) == 0) + setVarbit(player, EW2MachineryVarbit, 1, true) + return@on true + } + + // machinery where you find the key. + on(Scenery.MACHINERY_18594, IntType.SCENERY, "search") { player, _ -> + if(!inInventory(player, Items.KEY_9722)) { + sendItemDialogue(player, Items.KEY_9722, "You find a key hidden in the third pipe.") + addItemOrDrop(player, Items.KEY_9722) + } + if(getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) == 3) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 4) + setVarbit(player, EW2Varbit, 4) + } + return@on true + } + + // unlocking the hatch + onUseWith(IntType.SCENERY, Items.KEY_9722, Scenery.HATCH_18595) { player, _, _ -> + sendItemDialogue(player, Items.KEY_9722, "The key fits the lock in the hatch perfectly.") + setVarbit(player, EW2HatchVarbit, 1, true) + return@onUseWith true + } + + // stairs back up to EW1 + on(Scenery.STAIRS_18598, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, location(2720, 9892, 0)) + sendMessage(player, "You climb up the stairs.") + return@on true + } + + // stairs to lower level + on(Scenery.STAIRWELL_18597, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, location(1948, 5158, 0)) + sendMessage(player, "You climb down the stairs.") + return@on true + } + + // stairs back up to EW2 + on(Scenery.STAIRS_18599, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, location(1948, 5157, 2)) + sendMessage(player, "You climb up the stairs.") + return@on true + } + + // large cog crate + on(Scenery.CRATE_18616, IntType.SCENERY, "search") { player, _ -> + if (!inInventory(player, Items.LARGE_COG_9724)) { + addItemOrDrop(player, Items.LARGE_COG_9724) + sendMessage(player, "You find a big cog.") + } else { + sendMessage(player, "You search the crate but find nothing.") + } + return@on true + } + + // pipe crate + on(Scenery.CRATE_18619, IntType.SCENERY, "search") { player, _ -> + if (!inInventory(player, Items.PIPE_9723)) { + addItemOrDrop(player, Items.PIPE_9723) + sendMessage(player, "You find a pipe.") + } else { + sendMessage(player, "You search the crate but find nothing.") + } + return@on true + } + + // schematic crate + on(Scenery.SCHEMATIC_CRATE_18711, IntType.SCENERY, "take-from") { player, _ -> + sendDialogueOptions(player, "There are two schematics here...", "Crane schematic", "Lever schematic") + addDialogueAction(player) { _, buttonId -> + when (buttonId) { + 2 -> { + if(!inInventory(player, Items.CRANE_SCHEMATIC_9718)){ + addItemOrDrop(player, Items.CRANE_SCHEMATIC_9718) + sendItemDialogue(player, Items.CRANE_SCHEMATIC_9718, "You take a copy of the schematic drawing.") + } + else sendDialogue(player, "You already have this schematic.") + } + 3 -> { + if(!inInventory(player, Items.LEVER_SCHEMATIC_9719)){ + addItemOrDrop(player, Items.LEVER_SCHEMATIC_9719) + sendItemDialogue(player, Items.LEVER_SCHEMATIC_9719, "You take a copy of the schematic drawing.") + } + else sendDialogue(player, "You already have this schematic.") + } + } + } + return@on true + } + + // crane schematic + on(Items.CRANE_SCHEMATIC_9718, IntType.ITEM, "read") { player, _ -> + sendDialogue(player, "The schematic drawing details the construction and maintenance of a mechanical arm. One of the sections you notice is an explanation of how to make an elemental claw.") + return@on true + } + + // lever schematic + on(Items.LEVER_SCHEMATIC_9719, IntType.ITEM, "read") { player, _ -> + openInterface(player, 466) + return@on true + } + + // various states the crane can be in. they are a pattern, so the logic to flip and lower can be generalized. + val craneStates = intArrayOf( + Scenery.OLD_CRANE_18623, // fixed crane facing north, claw up + Scenery.OLD_CRANE_18624, // fixed crane facing north, claw down + Scenery.OLD_CRANE_18625, // fixed crane facing south, claw up + Scenery.OLD_CRANE_18626, // fixed crane facing south, claw down + Scenery.OLD_CRANE_18627, // fixed crane with ele bar facing north, claw up + Scenery.OLD_CRANE_18628, // fixed crane with ele bar facing north, claw down + Scenery.OLD_CRANE_18629, // fixed crane with ele bar facing south, claw up + Scenery.OLD_CRANE_18630, // fixed crane with ele bar facing south, claw down + Scenery.OLD_CRANE_18631, // fixed crane with mind bar facing north, claw up + Scenery.OLD_CRANE_18632, // fixed crane with mind bar facing north, claw down + Scenery.OLD_CRANE_18633, // fixed crane with mind bar facing south, claw up + Scenery.OLD_CRANE_18634, // fixed crane with mind bar facing south, claw down + Scenery.OLD_CRANE_18635, // broken crane facing north, claw up + Scenery.OLD_CRANE_18636, // broken crane facing north, claw down + Scenery.OLD_CRANE_18637, // broken crane facing south, claw up + Scenery.OLD_CRANE_18638, // broken crane facing south, claw down + ) + + val CraneStates = intArrayOf( + // Varbit 2644 = 0: Broken + Scenery.OLD_CRANE_18638, // broken crane facing south, claw down + Scenery.OLD_CRANE_18637, // broken crane facing south, claw up + Scenery.OLD_CRANE_18636, // broken crane facing north, claw down + Scenery.OLD_CRANE_18635, // broken crane facing north, claw up + + // Varbit 2644 = 1: Fixed/Empty (18623=N-Up, 18624=N-Down, 18625=S-Up, 18626=S-Down) + Scenery.OLD_CRANE_18626, // fixed crane facing south, claw down + Scenery.OLD_CRANE_18625, // fixed crane facing south, claw up + Scenery.OLD_CRANE_18624, // fixed crane facing north, claw down + Scenery.OLD_CRANE_18623, // fixed crane facing north, claw up + + // Varbit 2644 = 2: Elemental Bar + Scenery.OLD_CRANE_18630, // fixed crane with ele bar facing south, claw down + Scenery.OLD_CRANE_18629, // fixed crane with ele bar facing south, claw up + Scenery.OLD_CRANE_18628, // fixed crane with ele bar facing north, claw down + Scenery.OLD_CRANE_18627, // fixed crane with ele bar facing north, claw up + + // Varbit 2644 = 3: Mind Bar + Scenery.OLD_CRANE_18634, // fixed crane with mind bar facing south, claw down + Scenery.OLD_CRANE_18633, // fixed crane with mind bar facing south, claw up + Scenery.OLD_CRANE_18632, // fixed crane with mind bar facing north, claw down + Scenery.OLD_CRANE_18631 // fixed crane with mind bar facing north, claw up + ) + + // function to find my crane because it exists at some corner instead of the center. + fun findCraneInArea(center: Location): core.game.node.scenery.Scenery? { + // Search an area around the center + for (x in -2..2) { + for (y in -2..2) { + val checkLoc = center.transform(x, y, 0) + for (id in craneStates) { + val found = RegionManager.getObject(checkLoc.z, checkLoc.x, checkLoc.y, id) + if (found != null) return found + } + } + } + return null + } + + // position the crane based on varbit states + fun syncCrane(player: Player) { + val mat = getVarbit(player, EW2CraneState) + val pos = getVarbit(player, EW2CranePos) + + val index = (mat * 4) + pos + val newId = CraneStates[index] + + val craneLoc = Location.create(1954, 5145, 2) + val currentCrane = findCraneInArea(craneLoc) + + if (currentCrane != null) { + replaceScenery(currentCrane, newId, -1) + } + } + + // west lever by crane. moves crane up and down. + on(Scenery.AN_OLD_LEVER_18622, IntType.SCENERY, "pull") { player, _ -> + val currentPos = getVarbit(player, EW2CranePos) + val nextPos = currentPos xor 1 + setVarbit(player, EW2CranePos, nextPos, true) + animate(player, Animations.HUMAN_PULL_LEVER_4909) + syncCrane(player) + return@on true + } + + // east lever by crane. rotates crane north and south + on(Scenery.AN_OLD_LEVER_18621, IntType.SCENERY, "pull") { player, _ -> + val currentPos = getVarbit(player,EW2CranePos) + + // crane must be up to rotate + if (currentPos == 0 || currentPos == 2) { + sendMessage(player, "The crane is too low to rotate.") + return@on true + } + + val nextPos = currentPos xor 2 + + setVarbit(player, EW2CranePos, nextPos, true) + animate(player, Animations.HUMAN_PULL_LEVER_4909) + syncCrane(player) + return@on true + } + + // fix crane + onUseWith(IntType.SCENERY, Items.CRANE_CLAW_9720, Scenery.OLD_CRANE_18636) { player, used, with -> + // check if already repaired + if(getVarbit(player, EW2CraneState) != 0) { + sendMessage(player, "The crane is already repaired.") + return@onUseWith true + } + sendItemDialogue(player, used, "You replace the broken claw.") + removeItem(player, used) + + setVarbit(player, EW2CraneState, 1, true) + syncCrane(player) + return@onUseWith true + } + + // unlocked center hatch down to EW2 + on(Scenery.HATCH_18596, IntType.SCENERY, "climb-down") { player, _ -> + sendMessage(player, "You climb down the stairs.") + teleport(player, location(1955, 5155, 2)) + + // set the crane state when you go down based on the varbits + // if you log in and out during a server restart it'll reset the crane, but just reenter the workshop to fix it. + syncCrane(player) + + if(getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) == 4) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 5) + setVarbit(player, EW2Varbit, 5) + } + return@on true + } + } + + // fixes to get right interact locations + override fun defineDestinationOverrides() { + setDest(IntType.SCENERY, intArrayOf(Scenery.OLD_CRANE_18636), "use") { _, _ -> + return@setDest Location.create(1954, 5148, 2) + } + + setDest(IntType.SCENERY, intArrayOf(Scenery.PIPING_18650), "use") { _, _ -> + return@setDest Location.create(1953, 5167, 3) + } } } \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/ElementalWorkshop2.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/ElementalWorkshop2.kt index 5a37ce5b9..670e7da02 100644 --- a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/ElementalWorkshop2.kt +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop2/ElementalWorkshop2.kt @@ -5,50 +5,149 @@ import core.api.* import core.game.node.entity.player.Player import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.skill.Skills -import org.rs09.consts.* +import core.plugin.Initializable +import org.rs09.consts.Items /** * ELEMENTAL WORKSHOP II QUEST * * Requirements: 20 Magic, 30 Smithing, completion of Elemental Workshop I - * Primary Sources: https://www.youtube.com/watch?v=YKSWisRgGZk, https://www.youtube.com/watch?v=xoDkqRhus4Y + * Primary Source: https://www.youtube.com/watch?v=YKSWisRgGZk */ +@Initializable class ElementalWorkshop2 : Quest(Quests.ELEMENTAL_WORKSHOP_II, 53, 52, 1, EW2Varbit, 0, 1, 11) { companion object { - const val EW2Varbit = 2639 + const val ELEMENTALWORKSHOP2VARP = 896 // All of these varbits are packaged into varp 896. + const val EW2Varbit = 2639 // Main quest progress. Incremented with quest stages. + const val EW2MachineryVarbit = 2640 // The machinery you have to search for the key. Set to 1 after you read the scroll. + const val EW2HatchVarbit = 2641 // The hatch down to EW2. Set to 1 after you unlock it with the key. + //const val EW2 = 2642 // north lever + const val EW2JigCart = 2643 + const val EW2CraneState = 2644 // Crane State. 0 = Broken, 1 = Fixed/Empty, 2 = Elemental Bar, 3 = Mind Bar. + const val EW2CranePos = 2645 // Crane Position. 0 = South Down, 1 = South Up, 2 = North Down, 3 = North Up. + //const val EW2 = 2646 // junction box + //const val EW2 = 2647 // junction box + //const val EW2 = 2648 // junction box + //const val EW2 = 2649 // junction box + const val EW2PipeVarbit = 2650 + //const val EW2 = 2651 // water valve west + //const val EW2 = 2652 // cork screw lever and water valve east } /** - * Quest Stages and Varp values: + * Quest Stages and Varbit values: * https://chisel.weirdgloop.org/varbs/display?varbit=2639 * * val stage desc. * 0 0 unstarted - * 1 1 found book - * 2 2 read book - * 3 3 - * 4 4 - * 5 5 - * 6 6 - * 7 7 - * 8 8 - * 9 9 - * 10 10 - * 11 100 quest complete + * 1 1 found the beaten book + * 2 2 read the beaten book + * 3 3 read the beaten book's scroll + * 4 4 found key + * 5 5 went down center hatch + * 6 6 read the crane schematic + * 7 7 read the lever schematic? + * 8 8 went through the mind door + * 9 9 primed a mind bar + * 10 10 primed a mind bar? + * 11 100 smithed a mind helmet, quest complete */ override fun drawJournal(player: Player, stage: Int) { super.drawJournal(player, stage) var line = 12 var stage = getStage(player) - var started = getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) > 0 + // unstarted + if (stage == 0) { + line(player, "I can start this quest by reading a", line++) + line(player, "!!book?? found at the !!Dig Site??.", line++) + line++ + line(player,"To start this quest I will need:", line++) + line(player, "Level 20 Magic", line++, hasLevelStat(player, Skills.MAGIC, 20)) + line(player, "Level 30 Smithing", line++, hasLevelStat(player, Skills.SMITHING, 30)) + line(player,"I must have completed the following quests:", line++) // After - I have completed all of the required quests: + line(player, "Elemental Workshop I", line++, isQuestComplete(player, Quests.ELEMENTAL_WORKSHOP_I)) + } - // journal here + // stage 1, found the beaten book + if (stage >= 1) { + line(player, "I have found a book at the Dig Site.", line++, true) + // in-progress stage text + if(stage == 1) line(player, "I should read the book.", line++) + line++ + } + + // stage 2, read the beaten book + if (stage >= 2) { + line(player, "The book tells of a way to !!make elemental items??", line++, true) + line(player, "even more !!powerful?? than before.", line++, true) + // in-progress stage text + if(stage == 2) line(player, "I should read the scroll.", line++) + line++ + } + + // stage 3, read the scroll from the beaten book + if (stage >= 3) { + line(player, "The note found with the book has a strange code written on it.", line++, stage > 3) + // in-progress stage text + //if(stage == 3) line(player, "", line++) + line++ + } + + // stage 4, finding the key + if (stage >= 4) { + line(player, "By following the code on the !!note?? I was able to !!find a key??.", line++, stage > 4) + line++ + } + + // stage 5, going down the center hatch + if (stage >= 5) { + line(player, "The !!key?? I've found opens the !!large hatch?? in the !!workshop??; there are !!4 machines?? on this level to fix:", line++, stage > 5) + line(player, "The crane - now the claw has been replaced the crane looks like it's in good working order.", line++, stage > 5) + line(player, "The pipes - the pipes have now been fitted and it should work as long as it's powered.", line++, stage > 5) + line(player, "The tank - this should work fine now I have replaced the pipe.", line++, stage > 5) + line(player, "A wind tunnel - I have fitted all the cogs on to the pins. The win tunnel should now work as long as it's powered.", line++, stage > 5) + line(player, "A wind tunnel - I have fitted all the cogs on to the pins. The win tunnel should now work as long as it's powered.", line++, stage > 5) + + line(player, "I have found a track-mounted jig on which I was able to clamp an elemental bar.", line++, stage > 5) + line(player, "I used the press to flatten the hot elemental bar.", line++, stage > 5) + line(player, "The water tank was used to cool the elemental bar down.", line++, stage > 5) + line(player, "The wind tunnel proved a great way to dry off the wet bar.", line++, stage > 5) + line(player, "I have primed a bar of elemental ore.", line++, stage > 5) + line(player, "I placed the primed bar on the device found in the room with the mind symbols on the door.", line++, stage > 5) + line(player, "Operating the device charged the primed bar with some of my own mind power.", line++, stage > 5) + line(player, "I have made an elemental mind bar, now I just have to make one of the helms from it.", line++, stage > 5) + line(player, "Creating the elemental mind helm was easy with the book for instruction.", line++, stage > 5) + line(player, "", line++, stage > 5) + line++ + } + + // stage 6 + if (stage >= 6) { + line(player, "", line++, stage > 6) + line++ + } + + // stage 7 + if (stage >= 7) { + line(player, "", line++, stage > 7) + line++ + } + + // stage 8 + if (stage >= 8) { + line(player, "", line++, stage > 8) + line++ + } } - override fun reset(player: Player?) { + // use ::setqueststage 53 0 to reset quest. + override fun reset(player: Player) { + // this varp wipes all the varbits + setVarp(player, ELEMENTALWORKSHOP2VARP, 0, true) + player.getQuestRepository().syncronizeTab(player) super.reset(player) }