I've got most of the stuff up till the dayth fight now.

This commit is contained in:
aidan 2025-12-07 15:11:09 -06:00
parent 9f75ba700d
commit 62eb248109
11 changed files with 372 additions and 79 deletions

View file

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

View file

@ -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<Any?> {
override fun newInstance(arg: Any?): Plugin<Any?> {
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))
}
}

View file

@ -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<Any?> {
override fun newInstance(arg: Any?): Plugin<Any?> {
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))
}
}

View file

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

View file

@ -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<Any?> {
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)
@ -55,46 +50,3 @@ class AbandonedMineZone : MapZone("Abandoned Mine", true), Plugin<Any?> {
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<Any?> {
override fun newInstance(arg: Any?): Plugin<Any?> {
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))
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,2 @@
package content.region.morytania.quest.hauntedmine