diff --git a/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java b/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java index 1d0fa5c07..1eb9d962b 100644 --- a/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java +++ b/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java @@ -105,11 +105,13 @@ public final class FieldPickingPlugin extends OptionHandler { if (!isBloomPlant) { SceneryBuilder.replace(plant == PickingPlant.BANANA_TREE_4 ? full : object, object.transform(banana ? plant.respawn : 0), banana ? 300 : plant.respawn); } - if (!plant.name().startsWith("NETTLES")) { - player.getPacketDispatch().sendMessage("You pick a " + reward.getName().toLowerCase() + "."); - } else { - player.getPacketDispatch().sendMessage("You pick a handful of nettles."); - } + if (plant.name().startsWith("NETTLES")) { + player.getPacketDispatch().sendMessage("You pick a handful of nettles."); + } else if (plant.name().startsWith("GLOWING")) { + player.getPacketDispatch().sendMessage("You pull the fungus from the water, it is very cold to the touch."); + } else { + player.getPacketDispatch().sendMessage("You pick a " + reward.getName().toLowerCase() + "."); + } return true; } }); diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineGhostZone.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineGhostZone.kt new file mode 100644 index 000000000..680cc7539 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineGhostZone.kt @@ -0,0 +1,40 @@ +package content.region.morytania.quest.hauntedmine + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.NPCs + +@Initializable + +class AbandonedMineLiftGhostZone : MapZone("Abandoned Mine Level 4 Lift Ghost Zone", true), Plugin { + + override fun newInstance(arg: Any?): Plugin { + ZoneBuilder.configure(this) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + + // spawn the ghost that tries to turn the lift off if you've turned the lift on. + override fun enter(e: Entity?): Boolean { + if (e!!.isPlayer && getVarbit(e as Player, HauntedMine.liftMachineryVarbit) == 1 && !getAttribute(e, HauntedMine.attributeGhostSpawned, false)){ + LiftGhostNPC(NPCs.MISCHIEVOUS_GHOST_1551, location(2802, 4516,0)).init() + setAttribute(e, HauntedMine.attributeGhostSpawned, true) + } + + return super.enter(e) + } + + override fun configure() { + // just two squares, when the player crosses into it, we spawn the ghost that tries to turn off the lift. + register(ZoneBorders(2802, 4516, 2803, 4516)) + } +} diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineLevelFiveZone.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineLevelFiveZone.kt new file mode 100644 index 000000000..4d022fa9e --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineLevelFiveZone.kt @@ -0,0 +1,58 @@ +package content.region.morytania.quest.hauntedmine + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable + +// If you enter level 5 of the abandoned mine, any tinderboxes with you should become damp tinderboxes. +// Light sources should also be extinguished. This is so that when you try to go to mine level 5 and the +// player says "i need a light source", it'll force you to get a glowing fungus. +class AbandonedMineL5Zone : MapZone("Abandoned Mine Level 5", true), Plugin { + + override fun newInstance(arg: Any?): Plugin { + ZoneBuilder.configure(this) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + + override fun enter(e: Entity?): Boolean { + if (e!!.isPlayer){ + val tindies = amountInInventory(e as Player, Items.TINDERBOX_1553) + if(removeItem(e, Item(Items.TINDERBOX_1553, tindies), Container.INVENTORY)){ + addItemOrDrop(e, Items.DAMP_TINDERBOX_4073, tindies) + } + //todo extinguish light sources. + } + + return super.enter(e) + } + + override fun leave(e: Entity?, logout: Boolean): Boolean { + + if (e!!.isPlayer){ + val tindies = amountInInventory(e as Player, Items.DAMP_TINDERBOX_4073) + if(removeItem(e, Item(Items.DAMP_TINDERBOX_4073, tindies), Container.INVENTORY)){ + addItemOrDrop(e, Items.TINDERBOX_1553, tindies) + } + } + + return super.leave(e, logout) + } + + override fun configure() { + // todo expand the borders to cover level 6, that way the tinderbox stays damp + register(ZoneBorders(2680, 4415, 2755, 4480)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineListeners.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineListeners.kt index 2c5244ea6..03a09a3e5 100644 --- a/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineListeners.kt +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineListeners.kt @@ -1,13 +1,11 @@ package content.region.morytania.quest.hauntedmine -import content.data.tables.BirdNest import core.api.* import core.game.global.action.DoorActionHandler 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.item.Item import core.game.world.map.Location import org.rs09.consts.Items import org.rs09.consts.NPCs @@ -150,16 +148,8 @@ class AbandonedMineListeners : InteractionListener { return@on true } - on(Scenery.LARGE_DOOR_4963, IntType.SCENERY, "Open") { player, node -> - if (player.inventory.contains(Items.CRYSTAL_MINE_KEY_4077, 1)) { - DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) - } else { - sendMessage(player, "This door is locked.") - } - return@on true - } - - on(Scenery.LARGE_DOOR_4964, IntType.SCENERY, "Open") { player, node -> + // These are the doors from the shortcut to level 2, and also the ones on level 6 that go to the crystals. Both require the crystal mine key. + on(intArrayOf(Scenery.LARGE_DOOR_4963, Scenery.LARGE_DOOR_4964), IntType.SCENERY, "Open") { player, node -> if (player.inventory.contains(Items.CRYSTAL_MINE_KEY_4077, 1)) { DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) } else { @@ -251,10 +241,11 @@ class AbandonedMineListeners : InteractionListener { loc.y in 4485..4487 ) { + // randomize the points settings so all players have to pull different levers. setVarp(player, HauntedMine.pointsSettingsVarp, (0..511).random()) - player.debug("points varp is:") - player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString()) + //player.debug("points varp is:") + //player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString()) animate(player, 828) teleport(player, Location.create(2790, 4486, 0)) @@ -274,7 +265,7 @@ class AbandonedMineListeners : InteractionListener { // mine level 4 to 3 on(Scenery.LADDER_4968, IntType.SCENERY, "Climb-up") { player, node -> - // ladder 4968 is reused in two locations, so we have to see which one the player is interacting with + // ladder 4968 is reused in four locations, so we have to see which one the player is interacting with val loc = player.location // north-east ladder @@ -324,6 +315,44 @@ class AbandonedMineListeners : InteractionListener { return@on true } + // stair from mine level 5 to 6 + on(Scenery.STAIRS_4971, IntType.SCENERY, "Walk-down") { player, node -> + // stair 4971 is reused in two locations, so we have to see which one the player is interacting with + val loc = player.location + if(inInventory(player, Items.GLOWING_FUNGUS_4075)) { + + // left stairs to crystals + if (loc.x in 2691..2696) { + teleport(player, Location.create(2758, 4453, 0)) + + // right stairs to dayth + } else if (loc.x in 2745..2750) { + teleport(player, Location.create(2811, 4453, 0)) + + } + } else sendPlayerDialogue(player, "It's kind of dark down here. I should probably find a light source before going further.") + + return@on true + } + + // stair from mine level 6 to 5 + on(Scenery.STAIRS_4973, IntType.SCENERY, "Walk-up") { player, node -> + // stair 4973 is reused in two locations, so we have to see which one the player is interacting with + val loc = player.location + + // left stairs + if (loc.x == 2758) { + teleport(player, Location.create(2691, 4437, 0)) + + // right stairs + } else if (loc.x == 2811) { + teleport(player, Location.create(2750, 4437, 0)) + + } + + return@on true + } + } diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineZone.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineZone.kt index bda02d442..3cbfa4dd3 100644 --- a/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineZone.kt +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/AbandonedMineZone.kt @@ -1,12 +1,6 @@ package content.region.morytania.quest.hauntedmine -import core.api.Container -import core.api.addItem -import core.api.addItemOrDrop -import core.api.amountInInventory -import core.api.inInventory -import core.api.removeItem -import core.api.sendMessage +import core.api.* import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.node.item.Item @@ -33,9 +27,10 @@ class AbandonedMineZone : MapZone("Abandoned Mine", true), Plugin { override fun leave(e: Entity?, logout: Boolean): Boolean { - //todo come back to this and fix it the leave logic. + // Come back to this and fix the leave logic. // Right now if you go from floor 2 to 1 it gets rid of the fungus. - // I could also just leave as-is. It doesn't impact the quest and still accomplishes the correct goal. + // This is a very low priority to fix. It doesn't impact the quest and still accomplishes the correct goal. + if (e!!.isPlayer){ // remove any glowing fungus the player is carrying. val fungi = amountInInventory(e as Player, Items.GLOWING_FUNGUS_4075) @@ -54,47 +49,4 @@ class AbandonedMineZone : MapZone("Abandoned Mine", true), Plugin { // mine floors 2-6 register(ZoneBorders(2680, 4415, 2820, 4609)) } -} - -// If you enter level 5 of the abandoned mine, any tinderboxes with you should become damp tinderboxes. -// Light sources should also be extinguished. This is so that when you try to go to mine level 5 and the -// player says "i need a light source", it'll force you to get a glowing fungus. -class AbandonedMineL5Zone : MapZone("Abandoned Mine Level 5", true), Plugin { - - override fun newInstance(arg: Any?): Plugin { - ZoneBuilder.configure(this) - return this - } - - override fun fireEvent(identifier: String?, vararg args: Any?): Any { - return Unit - } - - override fun enter(e: Entity?): Boolean { - if (e!!.isPlayer){ - val tindies = amountInInventory(e as Player, Items.TINDERBOX_1553) - if(removeItem(e, Item(Items.TINDERBOX_1553, tindies), Container.INVENTORY)){ - addItemOrDrop(e, Items.DAMP_TINDERBOX_4073, tindies) - } - //todo extinguish light sources. - } - - return super.enter(e) - } - - override fun leave(e: Entity?, logout: Boolean): Boolean { - - if (e!!.isPlayer){ - val tindies = amountInInventory(e as Player, Items.DAMP_TINDERBOX_4073) - if(removeItem(e, Item(Items.DAMP_TINDERBOX_4073, tindies), Container.INVENTORY)){ - addItemOrDrop(e, Items.TINDERBOX_1553, tindies) - } - } - - return super.leave(e, logout) - } - - override fun configure() { - register(ZoneBorders(2680, 4415, 2755, 4480)) - } -} +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMine.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMine.kt index 636810629..4c1fcc346 100644 --- a/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMine.kt +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMine.kt @@ -37,7 +37,10 @@ class HauntedMine : Quest(Quests.HAUNTED_MINE,73 ,72 ,2 ,hauntedMineVarp, 0, 1, const val hauntedMineVarp = 382 const val pointsSettingsVarp = 383 const val pointsSettingsInterface = 144 + const val liftMachineryVarbit = 2060 + const val attributeGhostSpawned = "/save:quest:hauntedmine-ghostspawned" // True after the mischievous ghost spawns. + const val attributeValveUnlocked = "/save:quest:hauntedmine-valveunlocked" // True after you use Zealot's Key with the water valve const val attributeFungusPlaced = "/save:quest:hauntedmine-fungusplaced" // True after you put a fungus in the minecart const val attributeCartSent = "/save:quest:hauntedmine-cartsent" // True after you solve the cart puzzle const val attributeKilledTreusDayth = "/save:quest:hauntedmine-killedtreusdayth" // True after you've killed Treus Dayth. @@ -48,6 +51,7 @@ class HauntedMine : Quest(Quests.HAUNTED_MINE,73 ,72 ,2 ,hauntedMineVarp, 0, 1, // Quest Journal ref: https://youtu.be/CD77NeKz1J4?si=AxNEg5YZU5oJ3T11&t=231 // Contains pre-starting journal entry: https://www.youtube.com/watch?v=PMn0LRo4MCo // The video fragment matches the current RS3 journal: https://runescape.wiki/w/Transcript:Haunted_Mine/Journal + // todo go back and add the quest stage progressions. override fun drawJournal(player: Player, stage: Int) { super.drawJournal(player, stage) var line = 12 @@ -106,7 +110,10 @@ class HauntedMine : Quest(Quests.HAUNTED_MINE,73 ,72 ,2 ,hauntedMineVarp, 0, 1, } override fun reset(player: Player) { + //todo come back at the end and make sure all the attributes you thought up get reset. + // for some that might persist after the quest, should they get reset when you leave the mine? removeAttribute(player, attributeKilledTreusDayth) + //removeAttribute(player, attributeValveUnlocked) // DON'T CLEAR THIS ONE, THAT WAY YOU CAN STILL GET BACK TO CRYSTALS setVarbit(player, 382, 0, true) // resets the quest and closes tarn's door. } diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMineListeners.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMineListeners.kt index aad98c546..1ded202d0 100644 --- a/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMineListeners.kt +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/HauntedMineListeners.kt @@ -1,11 +1,13 @@ package content.region.morytania.quest.hauntedmine +import content.data.Quests import core.api.* import core.game.interaction.IntType import core.game.interaction.InteractionListener import core.game.node.item.Item import core.game.system.task.Pulse import core.game.world.GameWorld +import core.game.world.map.Location import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import org.rs09.consts.NPCs @@ -52,12 +54,80 @@ class HauntedMineListeners : InteractionListener { } // mine cart you are supposed to put the fungus into (south) and take the fungus out of (north). - // note that it appears this mine cart exists in both the start and end spots simultaneously. - on(Scenery.MINE_CART_4974, IntType.SCENERY, "Search") { player, node -> + on(Scenery.MINE_CART_4974, IntType.SCENERY, "Search") { player, _ -> + + // the mine cart is the same scenery in both locations, so we have to see which one the player is interacting with + val loc = player.location + + // Check around a 1-tile radius of the north cart + if (loc.z == 0 && + loc.x in 2773..2775 && + loc.y in 4536..4538) { + + // take fungus out if it's in there and you did the cart thing correctly. + if(getAttribute(player, HauntedMine.attributeFungusPlaced,false) && getAttribute(player, HauntedMine.attributeCartSent, false)) { + sendDialogueOptions(player, "There's a glowing fungus I placed in here earlier.", "Take it.", "Leave it.") + addDialogueAction(player) { _, buttonId -> + when (buttonId) { + 2 -> { + if (freeSlots(player) >= 1) { + addItem(player, Items.GLOWING_FUNGUS_4075) + setAttribute(player, HauntedMine.attributeFungusPlaced, false) + setAttribute(player, HauntedMine.attributeCartSent, false) + + } else sendMessage(player,"You need at least one free inventory space to take this.") + } + } + } + } else { + sendMessage(player, "The cart is empty.") + } + + // Check around a 1-tile radius of the south cart + } else if (loc.z == 0 && + loc.x in 2777..2779 && + loc.y in 4505..4507) { + + if(getAttribute(player, HauntedMine.attributeFungusPlaced,false)) { + sendMessage(player, "There's already a load of fungus in this cart.") + } else { + sendMessage(player, "The cart is empty.") + } + } return@on true } + onUseWith(SCENERY, Items.GLOWING_FUNGUS_4075, Scenery.MINE_CART_4974) { player, used, _ -> + + // the mine cart is the same scenery in both locations, so we have to see which one the player is interacting with + val loc = player.location + + // Check around a 1-tile radius of the north cart + if (loc.z == 0 && + loc.x in 2773..2775 && + loc.y in 4536..4538) { + + // don't let the player put the fungus back in the north cart. + sendMessage(player, "I just went to all the effort of getting this over here. I'm not sending it back.") + + // Check around a 1-tile radius of the south cart + } else if (loc.z == 0 && + loc.x in 2777..2779 && + loc.y in 4505..4507) { + + if(getAttribute(player, HauntedMine.attributeFungusPlaced,false)) { + sendMessage(player, "There's already a load of fungus in this cart.") + } else { + removeItem(player, used) + setAttribute(player, HauntedMine.attributeFungusPlaced, true) + sendMessage(player, "You place the glowing fungus in the mine cart.") + } + } + + return@onUseWith true + } + // points settings on(Scenery.POINTS_SETTINGS_4949, IntType.SCENERY, "Check") { player, _ -> openOverlay(player, HauntedMine.pointsSettingsInterface) @@ -77,6 +147,9 @@ class HauntedMineListeners : InteractionListener { // Lever A on(Scenery.LEVER_4951, IntType.SCENERY, "Pull") { player, node -> replaceScenery(node as core.game.node.scenery.Scenery, Scenery.LEVER_4958, 2) + // See PointsSettingsInterface.kt for an explanation on the points settings varp. + // Each lever corresponds to one bit in the varp. This interact XORs a 1 with the varp, with the bit shifted to the position that corresponds to each lever. + // This means that if you pull the lever once, the 0 becomes 1. If you pull it again, the 1 becomes a 0. val varp = getVarp(player, HauntedMine.pointsSettingsVarp) xor 1.shl(2) setVarp(player, HauntedMine.pointsSettingsVarp, varp) sendMessage(player, "You pull the lever. The old points creak into place.") @@ -153,5 +226,74 @@ class HauntedMineListeners : InteractionListener { return@on true } + + // water valve for lift + on(Scenery.WATER_VALVE_4924, IntType.SCENERY, "Turn") {player, _ -> + if(getAttribute(player, HauntedMine.attributeValveUnlocked, false)) { + if(getVarbit(player, HauntedMine.liftMachineryVarbit) == 1) { + sendMessage(player, "The valve is already open.") + } else { + sendMessage(player, "You open the valve. Water begins to flow through the lift mechanism.") + setVarbit(player, HauntedMine.liftMachineryVarbit, 1) + setAttribute(player, HauntedMine.attributeGhostSpawned,false) //resetting this here because it got stuck during test. + } + } else sendMessage(player, "The valve seems to be locked in position. There is a small keyhole in the side.") + return@on true + } + + // unlocking the water valve + onUseWith(SCENERY, Items.ZEALOTS_KEY_4078, Scenery.WATER_VALVE_4924) { player, _, _ -> + sendMessage(player, "The key unlocks the valve.") + setAttribute(player, HauntedMine.attributeValveUnlocked, true) + return@onUseWith true + } + + // lift from level 4 to 5 + on(intArrayOf(Scenery.LIFT_4937, Scenery.LIFT_4938, Scenery.LIFT_4940), IntType.SCENERY, "Go-down") { player, _ -> + // if lift is active, descend. + if (getVarbit(player, HauntedMine.liftMachineryVarbit) == 1) { + sendMessage(player, "You get in the lift. Now powered, the lift descends further into the mines...") + //teleport(player, Location.create(2724, 4456, 0)) + // todo figure out how to swim + teleport(player, Location.create(2724, 4452, 0)) + sendMessage(player, "...plunging you straight into the middle of a chamber flooded with water.") + } else sendMessage(player, "The lift is not active.") + + return@on true + } + + // lift from level 5 to 4 + on(Scenery.LIFT_4942, IntType.SCENERY, "Go-up") { player, _ -> + // todo this is inaccessible until i learn how to swim + teleport(player, Location.create(2807, 4493, 0)) + + return@on true + } + + // todo Make the picks respawn. + on(NPCs.INNOCENT_LOOKING_KEY_1543, IntType.NPC, "Take") { player, _ -> + if(getAttribute(player, HauntedMine.attributeKilledTreusDayth, false)) { + addItemOrDrop(player, Items.CRYSTAL_MINE_KEY_4077, 1) + } else { + // todo add dayth cutscene + // start treus dayth fight + } + + return@on true + } + + // crystals! + on(intArrayOf(Scenery.CRYSTAL_OUTCROP_4926, Scenery.CRYSTAL_OUTCROP_4927, Scenery.CRYSTAL_OUTCROP_4928), IntType.SCENERY, "Cut") { player, _ -> + if (freeSlots(player) >= 1 && (getAttribute(player,HauntedMine.attributeKilledTreusDayth, false) || getQuestStage(player, Quests.HAUNTED_MINE) == 100)) { + addItem(player, Items.SALVE_SHARD_4082) + // complete the quest + if(getQuestStage(player,Quests.HAUNTED_MINE) != 100) { + finishQuest(player, Quests.HAUNTED_MINE) + } + + } else sendMessage(player,"You need at least one free inventory space to take this.") + + return@on true + } } } \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/LiftGhostNPC.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/LiftGhostNPC.kt new file mode 100644 index 000000000..725ccaf93 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/LiftGhostNPC.kt @@ -0,0 +1,59 @@ +package content.region.morytania.quest.hauntedmine + +import core.api.* +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class LiftGhostNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return LiftGhostNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MISCHIEVOUS_GHOST_1551) + } +} + +class LiftGhostNPCBehavior : NPCBehavior(NPCs.MISCHIEVOUS_GHOST_1551) { + + override fun onCreation(self: NPC) { + sendChat(self, "Ooooo Wooooo Woo") + // the ghost is supposed to path through walls directly towards the valve, but this works too i guess. + val movementPath = arrayOf( + Location.create(2802, 4516, 0), + Location.create(2806, 4516, 0), + Location.create(2806, 4510, 0), + Location.create(2807, 4510, 0), + Location.create(2807, 4509, 0), + Location.create(2808, 4509, 0), + Location.create(2808, 4502, 0), + Location.create(2806, 4502, 0), + Location.create(2806, 4497, 0), + Location.create(2807, 4497, 0), + Location.create(2807, 4496, 0) + ) + self.configureMovementPath(*movementPath) + self.isWalks = true + } + + // logic to check if ghost is at end of path. If it is, turn off valve that powers the lift. + override fun tick(self: NPC): Boolean { + + for (p in self.viewport.currentPlane.players) { + if (self.location == location(2807,4496,0) && getVarbit(p, HauntedMine.liftMachineryVarbit) == 1) { + sendMessage(p, "You hear the sound of a valve being turned.") + setVarbit(p, HauntedMine.liftMachineryVarbit, 0) + setAttribute(p, HauntedMine.attributeGhostSpawned, false) + self.clear() + } + } + + + + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/MinecartNPC.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/MinecartNPC.kt index 0c8b25177..09019e1d7 100644 --- a/Server/src/main/content/region/morytania/quest/hauntedmine/MinecartNPC.kt +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/MinecartNPC.kt @@ -60,7 +60,7 @@ class MinecartNPCBehavior : NPCBehavior(NPCs.MINE_CART_1544, NPCs.MINE_CART_1545 // logic to check for, push, and damage players. override fun tick(self: NPC): Boolean { for (p in self.viewport.currentPlane.players) { - // todo come back and refine the pushing, it doesn't work very well. + // todo come back and refine the pushing, it doesn't work very well. can i just override the player's pathing with the minecarts pathing? if (p.location == self.location /*|| p.location == self.location.transform(self.direction,1)*/) { forceMove(p, p.location,self.location.transform(self.direction,1),0,0) impact(p,random(0,2)) diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/PointsSettingsInterface.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/PointsSettingsInterface.kt index d3b39a84a..622b3b3ff 100644 --- a/Server/src/main/content/region/morytania/quest/hauntedmine/PointsSettingsInterface.kt +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/PointsSettingsInterface.kt @@ -1,6 +1,7 @@ package content.region.morytania.quest.hauntedmine import core.api.* +import core.game.dialogue.FacialExpression import core.game.interaction.InterfaceListener import core.game.node.entity.player.Player @@ -33,6 +34,7 @@ import core.game.node.entity.player.Player class PointsSettingsInterface : InterfaceListener { + //todo make this interface close if the player moves override fun defineInterfaceListeners() { on(HauntedMine.pointsSettingsInterface) { player, _, _, buttonID, _, _ -> when (buttonID) { @@ -49,8 +51,8 @@ class PointsSettingsInterface : InterfaceListener { private fun checkCartRoute(player: Player) { - player.debug("points varp is:") - player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString()) + //player.debug("points varp is:") + //player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString()) // 5 of my 7 sources agree this is the correct solution. I have taken that to be the exact one, and the player must match it. if(getVarp(player,HauntedMine.pointsSettingsVarp) == 102 || getVarp(player,HauntedMine.pointsSettingsVarp) == 103) { // 103 could also be an answer because the random function that sets the initial varp stage might make the first bit a 1. afaik that bit does nothing. @@ -59,7 +61,7 @@ class PointsSettingsInterface : InterfaceListener { val varp = getVarp(player, HauntedMine.pointsSettingsVarp) xor 7.shl(12) setVarp(player, HauntedMine.pointsSettingsVarp, varp) setAttribute(player, HauntedMine.attributeCartSent, true) - sendDialogue(player, "I wonder if that cart is anywhere useful now?") + sendPlayerDialogue(player, "I wonder if that cart is anywhere useful now?", FacialExpression.THINKING) } else { // if wrong, clear the fungus out of the cart. setAttribute(player, HauntedMine.attributeFungusPlaced, false) diff --git a/Server/src/main/content/region/morytania/quest/hauntedmine/TreusDaythNPC.kt b/Server/src/main/content/region/morytania/quest/hauntedmine/TreusDaythNPC.kt new file mode 100644 index 000000000..c378f276c --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/hauntedmine/TreusDaythNPC.kt @@ -0,0 +1,2 @@ +package content.region.morytania.quest.hauntedmine +