lever logic

This commit is contained in:
aidan 2026-01-21 15:00:50 -06:00
parent 7860d8a27f
commit 118f995bef
4 changed files with 752 additions and 56 deletions

View file

@ -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
}

View file

@ -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
}
}
}

View file

@ -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)
}
}
}

View file

@ -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)
}