From aeb673cc927fa88ca28928e6800d4d92b7aa71e8 Mon Sep 17 00:00:00 2001 From: aidan Date: Wed, 21 Jan 2026 19:35:30 -0600 Subject: [PATCH] some cart logic --- .../quest/elementalworkshop2/EW2Listeners.kt | 333 +++++++++++++----- .../elementalworkshop2/ElementalWorkshop2.kt | 9 +- 2 files changed, 251 insertions(+), 91 deletions(-) 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 732a1a7d2..bb7bfe0d5 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,14 +1,18 @@ package content.region.kandarin.seers.quest.elementalworkshop2 import content.data.Quests +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2CartLever 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.EW2JigCart import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2MachineryVarbit +import content.region.kandarin.seers.quest.elementalworkshop2.ElementalWorkshop2.Companion.EW2PipeVarbit 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.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.scenery.SceneryBuilder @@ -19,6 +23,115 @@ import org.rs09.consts.* class EW2Listeners : InteractionListener { + companion object { + + // various states the crane can be in. they are a pattern, so the logic to flip and lower can be generalized. + 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 + ) + + // cart state is stored in varbit 2643 + val jigCartStates = intArrayOf( + NPCs.JIG_CART_4913, // empty + NPCs.JIG_CART_4914, // ele bar + NPCs.JIG_CART_4915, // mind bar + NPCs.JIG_CART_4916, // smashed mind bar + NPCs.JIG_CART_4917, // smashed ele bar + NPCs.JIG_CART_4918, // smashed white bar + ) + + val jigCartLocations = arrayOf( + Location.create(1954, 5147, 2), // south (start) + Location.create(1946, 5155, 2), // west (hammer) + Location.create(1953, 5162, 2), // north (water) + Location.create(1961, 5155, 2) // east (fans) + ) + + // 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) { + // todo it would be nice to animate this crane + replaceScenery(currentCrane, newId, -1) + } + } + + // update the jig cart based on varbit status + fun syncCart(player: Player) { + val cartState = getVarbit(player, EW2JigCart) + val cartPosIndex = getVarbit(player, EW2CartLever) + + val targetId = jigCartStates[cartState] + val targetLocation = jigCartLocations[cartPosIndex] + + // find existing cart + val trackCenter = Location.create(1953, 5155, 2) + val existingCart = RegionManager.getLocalNpcs(trackCenter, 15).find { + it.id in jigCartStates + } + + if (existingCart != null) { + // update appearance + if (existingCart.id != targetId) { + existingCart.transform(targetId) + } + // update location + if (existingCart.location != targetLocation) { + existingCart.teleport(targetLocation) + } + } else { + // Spawn if missing + val newCart = NPC(targetId, targetLocation) + newCart.init() + } + } + } + override fun defineListeners() { // Bookcase at digsite where you start quest. @@ -85,6 +198,23 @@ class EW2Listeners : InteractionListener { 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 and cart 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) + syncCart(player) + + if(getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II) == 4) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_II, 5) + setVarbit(player, EW2Varbit, 5) + } + return@on true + } + // stairs back up to EW1 on(Scenery.STAIRS_18598, IntType.SCENERY, "climb-up") { player, _ -> teleport(player, location(2720, 9892, 0)) @@ -106,6 +236,10 @@ class EW2Listeners : InteractionListener { return@on true } + // todo small cog crate + + // todo medium cog crate + // large cog crate on(Scenery.CRATE_18616, IntType.SCENERY, "search") { player, _ -> if (!inInventory(player, Items.LARGE_COG_9724)) { @@ -164,87 +298,40 @@ class EW2Listeners : InteractionListener { 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 + val craneMat = getVarbit(player, EW2CraneState) + val cartState = getVarbit(player, EW2JigCart) + + // facing north: pick up and drop off bar + if (currentPos == 3 && nextPos == 2) { // Moving from North-Up to North-Down + if (craneMat == 1 && (cartState == 1 || cartState == 2)) { + // pick up + setVarbit(player, EW2CraneState, cartState + 1) + setVarbit(player, EW2JigCart, 0) + sendMessage(player, "The crane claw picks up the bar from the cart.") + syncCart(player) + } else if ((craneMat == 2 || craneMat == 3) && cartState == 0) { + // drop off + setVarbit(player, EW2JigCart, craneMat - 1) + setVarbit(player, EW2CraneState, 1) + sendMessage(player, "You lower the bar onto the jig cart.") + syncCart(player) + } + } + + // facing south: process bar + if (currentPos == 1 && nextPos == 0) { + if (craneMat == 2) { + // if holding elemental bar, transform into mind bar + setVarbit(player, EW2CraneState, 3) + sendMessage(player, "As you lower the bar into the machinery, it glows with a strange mind-energy.") + playAudio(player, Sounds.EW2_CRANE_LOWER_3169) + } + } + setVarbit(player, EW2CranePos, nextPos, true) animate(player, Animations.HUMAN_PULL_LEVER_4909) syncCrane(player) @@ -257,7 +344,7 @@ class EW2Listeners : InteractionListener { // crane must be up to rotate if (currentPos == 0 || currentPos == 2) { - sendMessage(player, "The crane is too low to rotate.") + sendMessage(player, "The arm cannot be rotated while the claw is down.") return@on true } @@ -284,19 +371,79 @@ class EW2Listeners : InteractionListener { 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)) + // opens the junction box + on(Scenery.JUNCTION_BOX_18641, IntType.SCENERY, "open") { player, _ -> + openInterface(player, Components.JUNCTION_BOX_262) + return@on true + } - // 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) + // take item from the jig cart + on(jigCartStates, IntType.NPC, "take-from") { player, node -> + when(node.id) { + 4914 -> { + addItemOrDrop(player, Items.ELEMENTAL_METAL_2893) + sendItemDialogue(player, Items.ELEMENTAL_METAL_2893, "You take the elemental metal.") + } + 4915 -> { + //addItemOrDrop(player, Items.ELEMENTAL_MIND_BAR_9728) + //sendItemDialogue(player, Items.ELEMENTAL_MIND_BAR_9728, "You take the elemental mind bar.") + sendMessage(player, "The bar is too hot to touch.") + } + 4918 -> { + addItemOrDrop(player, Items.PRIMED_BAR_9727) + sendItemDialogue(player, Items.PRIMED_BAR_9727, "You take the primed bar.") + } } + animate(player, 537) + setVarbit(player, EW2JigCart, 0, true) + syncCart(player) + return@on true + } + + // fix the pipe + onUseWith(IntType.SCENERY, Items.PIPE_9723, Scenery.PIPING_18650) { player, item, _ -> + animate(player, 537) + sendItemDialogue(player, item, "You replace the section of broken pipe.") + playAudio(player, Sounds.EW2_PLACE_PIPE_3179) + setVarbit(player, EW2PipeVarbit, 1, true) + removeItem(player, item) + return@onUseWith true + } + + // put regular bar on the jig cart + onUseWith(IntType.NPC, intArrayOf(Items.ELEMENTAL_METAL_2893), NPCs.JIG_CART_4913) { player, used, _ -> + val cranePos = getVarbit(player, EW2CranePos) + + // if crane is south down, it's blocking the cart. + if (cranePos == 2) { + sendMessage(player, "You cannot place that while the claw is down.") + return@onUseWith true + } + + setVarbit(player, EW2JigCart, 1, true) + animate(player, 537) + syncCart(player) + removeItem(player, used) + return@onUseWith true + } + + on(Scenery.LEVER_18620, IntType.SCENERY, "pull") { player, _ -> + val currentPos = getVarbit(player, EW2CartLever) + val cranePos = getVarbit(player, EW2CranePos) + + // crane must be up + if (currentPos == 0 && cranePos == 2) { + sendMessage(player, "You cannot do that while the claw is down.") + return@on true + } + + // positions cycles 0 -> 1 -> 2 -> 3 -> 0 etc. + val nextPos = (currentPos + 1) % 4 + + animate(player, Animations.HUMAN_PULL_LEVER_4909) + setVarbit(player, EW2CartLever, nextPos, true) + syncCart(player) + return@on true } } @@ -307,6 +454,14 @@ class EW2Listeners : InteractionListener { return@setDest Location.create(1954, 5148, 2) } + setDest(IntType.NPC, intArrayOf(NPCs.JIG_CART_4913), "use") { _, _ -> + return@setDest Location.create(1954, 5148, 2) + } + + setDest(IntType.NPC, intArrayOf(NPCs.JIG_CART_4914, NPCs.JIG_CART_4915), "take-from") { _, _ -> + return@setDest Location.create(1954, 5148, 2) + } + setDest(IntType.SCENERY, intArrayOf(Scenery.PIPING_18650), "use") { _, _ -> return@setDest Location.create(1953, 5167, 3) } 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 670e7da02..3fbb32315 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 @@ -1,12 +1,17 @@ package content.region.kandarin.seers.quest.elementalworkshop2 import content.data.Quests +import content.region.kandarin.seers.quest.elementalworkshop2.EW2Listeners.Companion.syncCart +import content.region.kandarin.seers.quest.elementalworkshop2.EW2Listeners.Companion.syncCrane import core.api.* +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.entity.skill.Skills +import core.game.world.map.Location import core.plugin.Initializable import org.rs09.consts.Items +import org.rs09.consts.NPCs /** * ELEMENTAL WORKSHOP II QUEST @@ -23,8 +28,8 @@ class ElementalWorkshop2 : Quest(Quests.ELEMENTAL_WORKSHOP_II, 53, 52, 1, EW2Var 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 EW2CartLever = 2642 // cart moving lever. 0 = start (south), 1 = west, 2 = north, 3 = east + const val EW2JigCart = 2643 // Jig Cart state. 0 = Empty, 1 = ele bar, 2 = mind bar, 3 = smashed mind, 4 = smashed ele, 5 = primed 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