Implemented Clock Tower quest

This commit is contained in:
Oven Bread
2023-08-12 08:39:53 +00:00
committed by Ryan
parent 6112abf673
commit bb21ad533b
6 changed files with 506 additions and 16 deletions
@@ -0,0 +1,29 @@
package content.region.kandarin.ardougne.dialogue
import content.region.kandarin.ardougne.quest.clocktower.BrotherKojoDialogueFile
import core.api.*
import core.game.dialogue.DialoguePlugin
import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.NPCs
/**
* Brother Kojo main dialogue.
* @author ovenbread
*/
@Initializable
class BrotherKojoDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
// Fallback to default. Always the start of Clocktower quest
openDialogue(player!!, BrotherKojoDialogueFile(), npc)
return true
}
override fun newInstance(player: Player?): DialoguePlugin {
return BrotherKojoDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.BROTHER_KOJO_223)
}
}
@@ -0,0 +1,108 @@
package content.region.kandarin.ardougne.quest.clocktower
import core.api.*
import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.game.dialogue.Topic
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
class BrotherKojoDialogueFile : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
if (getAttribute(player!!, ClockTower.attributeAskKojoAboutRats, false) && !getAttribute(player!!, ClockTower.attributeRatsPoisoned, false)) {
when (stage) {
START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I've found the white cog! But it's locked behind a gate. There's rats everywhere!").also { stage++ }
1 -> npcl(FacialExpression.FRIENDLY, "Rats again?! Kill them! Kill them all!").also { stage++ }
2 -> playerl(FacialExpression.FRIENDLY, "But how do I open the gate? Do you have a key?").also { stage++ }
3 -> npcl(FacialExpression.FRIENDLY, "Get rid of the rats! I'm sure I left some rat poison down there!").also { stage++ }
4 -> playerl(FacialExpression.FRIENDLY, "I guess I better go and deal with the rat problem...").also {
stage = END_DIALOGUE
}
}
return
}
when (getQuestStage(player!!, ClockTower.questName)) {
0 -> {
when (stage) {
START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello monk.").also { stage++ }
1 -> npcl(FacialExpression.FRIENDLY, "Hello adventurer. My name is Brother Kojo. Do you happen to know the time?").also { stage++ }
2 -> player(FacialExpression.SAD, "No, sorry, I don't.").also { stage++ }
3 -> npcl(FacialExpression.NEUTRAL, "Exactly! This clock tower has recently broken down, and without it nobody can tell the correct time. I must fix it before the town people become too angry!").also { stage++ }
4 -> npcl(FacialExpression.ASKING, "I don't suppose you could assist me in the repairs? I'll pay you for your help.").also { stage++ }
5 -> showTopics(
Topic(FacialExpression.FRIENDLY, "Ok old monk, what can I do?", 30),
Topic(FacialExpression.ASKING, "So... how much reward are we talking then?", 10),
Topic(FacialExpression.FRIENDLY, "Not now old monk.", 20),
)
10 -> npcl(FacialExpression.STRUGGLE, "Well, I'm only a monk so I'm not exactly rich, but I assure you I will give you a fair reward for the time spent assisting me in repairing the clock.").also { stage = 4 }
20 -> npcl(FacialExpression.FRIENDLY, "OK then. Come back and let me know if you change your mind.").also { stage = END_DIALOGUE }
30 -> npc(FacialExpression.HAPPY, "Oh, thank you kind ${if (player!!.isMale) "sir" else "madam"}!",
"In the cellar below, you'll find four cogs.",
"They're too heavy for me, but you should be able to",
"carry them one at a time.").also { stage++ }
31 -> npcl(FacialExpression.THINKING, "I know one goes on each floor... but I can't exactly remember which goes where specifically. Oh well, I'm sure you can figure it out fairly easily.").also { stage++ }
32 -> player(FacialExpression.FRIENDLY, "Well, I'll do my best.").also { stage++ }
33 -> npcl(FacialExpression.HAPPY, "Thank you again! And remember to be careful, the cellar is full of strange beasts!").also {
stage = END_DIALOGUE
setQuestStage(player!!, ClockTower.questName, 1)
}
}
}
1 -> {
when (stage) {
START_DIALOGUE -> npcl(FacialExpression.ASKING, "Oh hello, are you having trouble? The cogs are in four rooms below us. Place one cog on a pole on each of the four tower levels.").also { stage++ }
1 -> showTopics(
Topic(FacialExpression.FRIENDLY, "Can I have a hint?", 2),
Topic(FacialExpression.ASKING, "I'll carry on looking.", END_DIALOGUE),
)
2 -> showTopics(
Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the red cog?", 3),
Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the blue cog?", 3),
Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the black cog?", 3),
Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the white cog?", 3),
)
3 -> npcl(FacialExpression.FRIENDLY, "If I knew, I wouldn't ask you to find it. It's in the basement somewhere.").also { stage = 1 }
}
}
2 -> {
when (stage) {
START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I've placed a cog!").also { stage++ }
1 -> npcl(FacialExpression.FRIENDLY, "That's great. Come see me when you've done the other three.").also { stage = END_DIALOGUE }
}
}
3 -> {
when (stage) {
START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Two down!").also { stage++ }
1 -> npcl(FacialExpression.FRIENDLY, "Two to go.").also { stage = END_DIALOGUE }
}
}
4 -> {
when (stage) {
START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "One left.").also { stage = END_DIALOGUE }
}
}
in 5 .. 10 -> {
when (stage) {
START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I have replaced all the cogs!").also { stage++ }
1 -> npcl(FacialExpression.FRIENDLY, "Really..? Wait, listen! Well done, well done! Yes yes yes, you've done it! You ARE clever!").also { stage++ }
2 -> npcl(FacialExpression.FRIENDLY, "The townsfolk will all be able to know the correct time now! Thank you so much for all of your help! And as promised, here is your reward!").also { stage++ }
3 -> {
end()
finishQuest(player!!, ClockTower.questName)
}
}
}
100 -> {
when (stage) {
START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Oh hello there traveller. You've done a grand job with the clock. It's just like new.").also { stage = END_DIALOGUE }
}
}
}
}
}
@@ -0,0 +1,74 @@
package content.region.kandarin.ardougne.quest.clocktower
import core.api.addItemOrDrop
import core.api.getAttribute
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.quest.Quest
import core.plugin.Initializable
import org.rs09.consts.Items
/**
* https://www.youtube.com/watch?v=Cl68Z0bsRq4
*/
@Initializable
class ClockTower : Quest("Clock Tower",38, 37, 1, 10, 0, 1, 8) {
companion object {
const val questName = "Clock Tower"
const val attributeBlueCog = "/save:quest:clocktower-bluecogplaced"
const val attributeBlackCog = "/save:quest:clocktower-blackcogplaced"
const val attributeWhiteCog = "/save:quest:clocktower-whitecogplaced"
const val attributeRedCog = "/save:quest:clocktower-redcogplaced"
const val attributeBlackCogCooled = "/save:quest:clocktower-blackcogcooled"
const val attributeRatsPoisoned = "/save:quest:clocktower-poisonplaced"
const val attributeAskKojoAboutRats = "quest:clocktower-askkojoaboutrats"
}
override fun drawJournal(player: Player?, stage: Int) {
super.drawJournal(player, stage)
var line = 12
var stage = getStage(player)
when (stage) {
0 -> {
line(player, "I can start this quest by speaking to !!Brother Kojo?? at the", line++)
line(player, "!!Clock Tower?? which is located !!South?? of !!Ardougne??", line++)
}
in 1 .. 10 -> {
line(player, "I spoke to Brother Kojo at the Clock Tower South of", line++, true)
line(player, "Ardougne and agreed to help him repair the clock.", line++, true)
line(player,"To repair the clock I need to find the four coloured cogs", line++, false)
line(player,"and place them on the four correctly coloured spindles.", line++, false)
line(player, if (getAttribute(player!!, attributeBlueCog, false)) "I placed the !!Blue Cog?? on it's !!spindle??." else "I haven't placed the !!Blue Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeBlueCog, false))
line(player, if (getAttribute(player!!, attributeBlackCog, false)) "I placed the !!Black Cog?? on it's !!spindle??." else "I haven't placed the !!Black Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeBlackCog, false))
line(player, if (getAttribute(player!!, attributeWhiteCog, false)) "I placed the !!White Cog?? on it's !!spindle??." else "I haven't placed the !!White Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeWhiteCog, false))
line(player, if (getAttribute(player!!, attributeRedCog, false)) "I placed the !!Red Cog?? on it's !!spindle??." else "I haven't placed the !!Red Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeRedCog, false))
}
100 -> {
line(player, "I spoke to Brother Kojo at the Clock Tower South of", line++, true)
line(player, "I have placed all four cogs successfully on the spindles.", line++, true)
line(player,"Brother Kojo was grateful for all my help and rewarded me.", line++, true)
line++
line(player,"<col=FF0000>QUEST COMPLETE!</col>", line)
}
}
}
override fun finish(player: Player) {
var ln = 10
super.finish(player)
player.packetDispatch.sendString("You have completed the Clock Tower Quest!", 277, 4)
player.packetDispatch.sendItemZoomOnInterface(Items.COINS_995, 240, 277, 5)
drawReward(player,"1 Quest Point", ln++)
drawReward(player,"500 coins", ln++)
addItemOrDrop(player, Items.COINS_995, 500)
}
override fun newInstance(`object`: Any?): Quest {
return this
}
}
@@ -0,0 +1,277 @@
package content.region.kandarin.ardougne.quest.clocktower
import core.api.*
import core.game.global.action.DoorActionHandler
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.item.GroundItem
import core.game.node.item.Item
import core.game.world.map.Direction
import core.game.world.map.Location
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import org.rs09.consts.Scenery
class ClockTowerListener : InteractionListener {
companion object {
val DOWN_ANIMATION = Animation(2140)
val UP_ANIMATION = Animation(2139)
}
override fun defineListeners() {
onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_25) { player, _, _ ->
sendMessage(player, "The cog doesn't seem to fit.")
return@onUseWith true
}
onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_26) { player, _, _ ->
sendMessage(player, "The cog doesn't seem to fit.")
return@onUseWith true
}
onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_27) { player, _, _ ->
sendMessage(player, "The cog doesn't seem to fit.")
return@onUseWith true
}
onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_28) { player, _, _ ->
sendMessage(player, "The cog doesn't seem to fit.")
return@onUseWith true
}
onUseWith(IntType.SCENERY, Items.WHITE_COG_20, Scenery.CLOCK_SPINDLE_31) { player, _, _ ->
if (!getAttribute(player, ClockTower.attributeWhiteCog, false)) {
if (removeItem(player, Items.WHITE_COG_20)) {
sendMessage(player, "The cog fits perfectly.")
setAttribute(player, ClockTower.attributeWhiteCog, true)
if (!isQuestComplete(player, ClockTower.questName)) {
setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1)
}
}
} else {
sendMessage(player, "The cog has already been placed.")
}
return@onUseWith true
}
onUseWith(IntType.SCENERY, Items.BLACK_COG_21, Scenery.CLOCK_SPINDLE_30) { player, _, _ ->
if (!getAttribute(player, ClockTower.attributeBlackCog, false)) {
if (removeItem(player, Items.BLACK_COG_21)) {
sendMessage(player, "The cog fits perfectly.")
setAttribute(player, ClockTower.attributeBlackCog, true)
if (!isQuestComplete(player, ClockTower.questName)) {
setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1)
}
}
} else {
sendMessage(player, "The cog has already been placed.")
}
return@onUseWith true
}
onUseWith(IntType.SCENERY, Items.BLUE_COG_22, Scenery.CLOCK_SPINDLE_32) { player, _, _ ->
if (!getAttribute(player, ClockTower.attributeBlueCog, false)) {
if (removeItem(player, Items.BLUE_COG_22)) {
sendMessage(player, "The cog fits perfectly.")
setAttribute(player, ClockTower.attributeBlueCog, true)
if (!isQuestComplete(player, ClockTower.questName)) {
setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1)
}
}
} else {
sendMessage(player, "The cog has already been placed.")
}
return@onUseWith true
}
onUseWith(IntType.SCENERY, Items.RED_COG_23, Scenery.CLOCK_SPINDLE_29) { player, _, _ ->
if (!getAttribute(player, ClockTower.attributeRedCog, false)) {
if (removeItem(player, Items.RED_COG_23)) {
sendMessage(player, "The cog fits perfectly.")
setAttribute(player, ClockTower.attributeRedCog, true)
if (!isQuestComplete(player, ClockTower.questName)) {
setQuestStage(player, ClockTower.questName, getQuestStage(player, ClockTower.questName) + 1)
}
}
} else {
sendMessage(player, "The cog has already been placed.")
}
return@onUseWith true
}
// The lever to the rats
val levers = intArrayOf(Scenery.LEVER_33, Scenery.LEVER_34)
on(levers, IntType.SCENERY, "pull") { player, node ->
val leverScenery = node.asScenery()
// This one opens the first and only gate
if (leverScenery.location.equals(2591, 9661, 0)) {
if (leverScenery.id == Scenery.LEVER_33) {
val metalGate = getScenery(2595, 9657, 0)!!
val location = metalGate.location.transform(1, 0, 0)
face(player, Location.create(2591, 9660, 0))
animate(player, UP_ANIMATION)
replaceScenery(metalGate, Scenery.GATE_37, -1, Direction.WEST, location)
replaceScenery(leverScenery, Scenery.LEVER_34, -1)
} else if (leverScenery.id == Scenery.LEVER_34) {
val metalGateOpen = getScenery(2596, 9657, 0)!!
val location = metalGateOpen.location.transform(-1, 0, 0)
face(player, Location.create(2591, 9660, 0))
animate(player, DOWN_ANIMATION)
replaceScenery(metalGateOpen, Scenery.GATE_37, -1, Direction.SOUTH, location)
replaceScenery(leverScenery, Scenery.LEVER_33, -1)
}
}
if (leverScenery.location.equals(2593, 9661, 0)) {
// This one doesn't do anything https://www.youtube.com/watch?v=2FXiYftAX9A
// The second gate is fixed and is not a Scenery
if (leverScenery.id == Scenery.LEVER_34) {
face(player, Location.create(2593, 9660, 0))
animate(player, DOWN_ANIMATION)
replaceScenery(leverScenery, Scenery.LEVER_33, -1)
} else if (leverScenery.id == Scenery.LEVER_33) {
face(player, Location.create(2593, 9660, 0))
animate(player, UP_ANIMATION)
replaceScenery(leverScenery, Scenery.LEVER_34, -1)
}
}
return@on true
}
// The gate to the rats
on(Scenery.GATE_37, IntType.SCENERY, "open") { player, _ ->
sendMessage(player, "The door doesn't seem to open from here...")
return@on true
}
// Poison the rats
onUseWith(IntType.SCENERY, Items.RAT_POISON_24, Scenery.FOOD_TROUGH_40) { player, _, _ ->
if (getAttribute(player, ClockTower.attributeRatsPoisoned, false)) {
sendDialogue(player, "The gate has already been damaged, you see no reason to cause more suffering.")
return@onUseWith true
}
if (removeItem(player, Items.RAT_POISON_24)) {
val loc = location(2579, 9656, 0) // Location of the gate
sendMessage(player, "The rats swarm towards the poisoned food...")
sendMessage(player, "... and devour it hungrily.")
sendMessage(player, "You see them smashing against the gates in a panic.")
sendMessage(player, "They seem to be dying.")
setAttribute(player, ClockTower.attributeRatsPoisoned, true)
runTask(player, 1) {
val rats = findLocalNPCs(player, intArrayOf(NPCs.DUNGEON_RAT_224))
rats.forEach { rat ->
if (rat.location.withinDistance(loc, 20)) {
var xDeath = 0
var yDeath = -1
for (rat in rats) {
Pathfinder.find(rat.location, location(loc.x + xDeath, loc.y + yDeath, loc.z), true, Pathfinder.SMART).walk(rat)
xDeath++
if (xDeath == 4) {
xDeath = 0
yDeath++
}
}
runTask(rat, 15) {
rat.startDeath(null)
}
}
}
}
}
return@onUseWith true
}
// Gate to White Cog (after rats die)
on(Scenery.GATE_39, IntType.SCENERY, "go-through") { player, node ->
if (getAttribute(player, ClockTower.attributeRatsPoisoned, false)) {
sendDialogueLines(player, "The death throws of the rats seem to have shaken the door loose of", "its hinges. You pick it up and go through.")
DoorActionHandler.handleAutowalkDoor(player, node.asScenery())
} else {
sendPlayerDialogue(player, "It won't open. Maybe the monk knows how to open this door?")
setAttribute(player, ClockTower.attributeAskKojoAboutRats, true)
}
return@on true
}
// Wall to Blue Cog
on(Scenery.WALL_1586, IntType.SCENERY, "push") { player, node ->
DoorActionHandler.handleAutowalkDoor(player, node.asScenery())
return@on true
}
on(Items.WHITE_COG_20, IntType.GROUNDITEM, "take") { player, groundItem ->
if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) {
sendDialogue(player, "The cogs are too heavy to carry more than one at a time.")
} else if (hasSpaceFor(player, Item(Items.WHITE_COG_20))) {
addItem(player, Items.WHITE_COG_20)
removeGroundItem(groundItem as GroundItem)
}
return@on true
}
onUseWith(IntType.GROUNDITEM, Items.BUCKET_OF_WATER_1929, Items.BLACK_COG_21) { player, _, _ ->
if (removeItem(player, Items.BUCKET_OF_WATER_1929)) {
addItem(player, Items.BUCKET_1925)
sendDialogue(player, "You pour water over the cog. It quickly cools down enough to take.")
setAttribute(player, ClockTower.attributeBlackCogCooled, true)
}
return@onUseWith true
}
on(Items.BLACK_COG_21, IntType.GROUNDITEM, "take") { player, groundItem ->
if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) {
sendDialogue(player, "The cogs are too heavy to carry more than one at a time.")
return@on true
}
if (hasSpaceFor(player, Item(Items.BLACK_COG_21)) && getAttribute(player, ClockTower.attributeBlackCogCooled, false)) {
addItem(player, Items.BLACK_COG_21)
removeGroundItem(groundItem as GroundItem)
return@on true
}
if (!inInventory(player, Items.BUCKET_OF_WATER_1929, 1) && !inEquipment(player, Items.ICE_GLOVES_1580)) {
sendDialogue(player, "The cog is red hot from the flames. You cannot pick it up.")
return@on true
}
if (hasSpaceFor(player, Item(Items.BLACK_COG_21)) && (inInventory(player, Items.BUCKET_OF_WATER_1929, 1) || inEquipment(player, Items.ICE_GLOVES_1580)) && !getAttribute(player, ClockTower.attributeBlackCogCooled, false)) {
// Picking up the Black Cog requires dousing it in water or using ice gloves
if (!inEquipment(player, Items.ICE_GLOVES_1580) && removeItem(player, Items.BUCKET_OF_WATER_1929)) {
sendDialogue(player, "You pour water over the cog. It quickly cools down enough to take.")
addItem(player, Items.BUCKET_1925)
addItem(player, Items.BLACK_COG_21)
setAttribute(player, ClockTower.attributeBlackCogCooled, true)
removeGroundItem(groundItem as GroundItem)
} else if (inEquipment(player, Items.ICE_GLOVES_1580) && !inInventory(player, Items.BUCKET_OF_WATER_1929)) {
sendDialogue(player, "You grab the cog with your ice gloves. It quickly cools down enough to take.")
setAttribute(player, ClockTower.attributeBlackCogCooled, true)
removeGroundItem(groundItem as GroundItem)
addItem(player, Items.BLACK_COG_21)
}
}
return@on true
}
on(Items.BLUE_COG_22, IntType.GROUNDITEM, "take") { player, groundItem ->
if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) {
sendDialogue(player, "The cogs are too heavy to carry more than one at a time.")
} else if (hasSpaceFor(player, Item(Items.BLUE_COG_22))) {
addItem(player, Items.BLUE_COG_22)
removeGroundItem(groundItem as GroundItem)
}
return@on true
}
on(Items.RED_COG_23, IntType.GROUNDITEM, "take") { player, groundItem ->
if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) {
sendDialogue(player, "The cogs are too heavy to carry more than one at a time.")
} else if (hasSpaceFor(player, Item(Items.RED_COG_23))) {
addItem(player, Items.RED_COG_23)
removeGroundItem(groundItem as GroundItem)
}
return@on true
}
}
}
@@ -31,6 +31,8 @@ public enum SpecialLadders implements LadderAchievementCheck {
ALKHARID_SOCRCERESS_UP(Location.create(3325,3142,0),Location.create(3325,3139,1)),
ALKHARID_SOCRCERESS_DOWN(Location.create(3325,3139,1),Location.create(3325,3143,0)),
CLOCKTOWER_HIDDEN_LADDER(Location.create(2572,9631,0),Location.create(2572,3230,0)),
DRAYNOR_SEWER_SOUTHEAST_DOWN(new Location(3118, 3244, 0), new Location(3118, 9643, 0)),
DRAYNOR_SEWER_SOUTHEAST_UP(new Location(3118, 9643, 0), new Location(3118, 3243, 0)),
DRAYNOR_SEWER_NORTHWEST_DOWN(new Location(3084, 3272, 0), new Location(3085, 9672, 0)),