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) { if (!isBloomPlant) {
SceneryBuilder.replace(plant == PickingPlant.BANANA_TREE_4 ? full : object, object.transform(banana ? plant.respawn : 0), banana ? 300 : plant.respawn); SceneryBuilder.replace(plant == PickingPlant.BANANA_TREE_4 ? full : object, object.transform(banana ? plant.respawn : 0), banana ? 300 : plant.respawn);
} }
if (!plant.name().startsWith("NETTLES")) { if (plant.name().startsWith("NETTLES")) {
player.getPacketDispatch().sendMessage("You pick a " + reward.getName().toLowerCase() + "."); player.getPacketDispatch().sendMessage("You pick a handful of nettles.");
} else { } else if (plant.name().startsWith("GLOWING")) {
player.getPacketDispatch().sendMessage("You pick a handful of nettles."); 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; 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 package content.region.morytania.quest.hauntedmine
import content.data.tables.BirdNest
import core.api.* import core.api.*
import core.game.global.action.DoorActionHandler import core.game.global.action.DoorActionHandler
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
@ -150,16 +148,8 @@ class AbandonedMineListeners : InteractionListener {
return@on true return@on true
} }
on(Scenery.LARGE_DOOR_4963, 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.
if (player.inventory.contains(Items.CRYSTAL_MINE_KEY_4077, 1)) { on(intArrayOf(Scenery.LARGE_DOOR_4963, Scenery.LARGE_DOOR_4964), IntType.SCENERY, "Open") { player, node ->
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 ->
if (player.inventory.contains(Items.CRYSTAL_MINE_KEY_4077, 1)) { if (player.inventory.contains(Items.CRYSTAL_MINE_KEY_4077, 1)) {
DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) DoorActionHandler.handleAutowalkDoor(player, node.asScenery())
} else { } else {
@ -251,10 +241,11 @@ class AbandonedMineListeners : InteractionListener {
loc.y in 4485..4487 loc.y in 4485..4487
) { ) {
// randomize the points settings so all players have to pull different levers.
setVarp(player, HauntedMine.pointsSettingsVarp, (0..511).random()) setVarp(player, HauntedMine.pointsSettingsVarp, (0..511).random())
player.debug("points varp is:") //player.debug("points varp is:")
player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString()) //player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString())
animate(player, 828) animate(player, 828)
teleport(player, Location.create(2790, 4486, 0)) teleport(player, Location.create(2790, 4486, 0))
@ -274,7 +265,7 @@ class AbandonedMineListeners : InteractionListener {
// mine level 4 to 3 // mine level 4 to 3
on(Scenery.LADDER_4968, IntType.SCENERY, "Climb-up") { player, node -> 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 val loc = player.location
// north-east ladder // north-east ladder
@ -324,6 +315,44 @@ class AbandonedMineListeners : InteractionListener {
return@on true 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 package content.region.morytania.quest.hauntedmine
import core.api.Container import core.api.*
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.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.item.Item 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 { 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. // 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){ if (e!!.isPlayer){
// remove any glowing fungus the player is carrying. // remove any glowing fungus the player is carrying.
val fungi = amountInInventory(e as Player, Items.GLOWING_FUNGUS_4075) val fungi = amountInInventory(e as Player, Items.GLOWING_FUNGUS_4075)
@ -54,47 +49,4 @@ class AbandonedMineZone : MapZone("Abandoned Mine", true), Plugin<Any?> {
// mine floors 2-6 // mine floors 2-6
register(ZoneBorders(2680, 4415, 2820, 4609)) 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 hauntedMineVarp = 382
const val pointsSettingsVarp = 383 const val pointsSettingsVarp = 383
const val pointsSettingsInterface = 144 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 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 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. 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 // Quest Journal ref: https://youtu.be/CD77NeKz1J4?si=AxNEg5YZU5oJ3T11&t=231
// Contains pre-starting journal entry: https://www.youtube.com/watch?v=PMn0LRo4MCo // 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 // 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) { override fun drawJournal(player: Player, stage: Int) {
super.drawJournal(player, stage) super.drawJournal(player, stage)
var line = 12 var line = 12
@ -106,7 +110,10 @@ class HauntedMine : Quest(Quests.HAUNTED_MINE,73 ,72 ,2 ,hauntedMineVarp, 0, 1,
} }
override fun reset(player: Player) { 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, 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. 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 package content.region.morytania.quest.hauntedmine
import content.data.Quests
import core.api.* import core.api.*
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.node.item.Item import core.game.node.item.Item
import core.game.system.task.Pulse import core.game.system.task.Pulse
import core.game.world.GameWorld import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs 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). // 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, _ ->
on(Scenery.MINE_CART_4974, IntType.SCENERY, "Search") { player, node ->
// 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 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 // points settings
on(Scenery.POINTS_SETTINGS_4949, IntType.SCENERY, "Check") { player, _ -> on(Scenery.POINTS_SETTINGS_4949, IntType.SCENERY, "Check") { player, _ ->
openOverlay(player, HauntedMine.pointsSettingsInterface) openOverlay(player, HauntedMine.pointsSettingsInterface)
@ -77,6 +147,9 @@ class HauntedMineListeners : InteractionListener {
// Lever A // Lever A
on(Scenery.LEVER_4951, IntType.SCENERY, "Pull") { player, node -> on(Scenery.LEVER_4951, IntType.SCENERY, "Pull") { player, node ->
replaceScenery(node as core.game.node.scenery.Scenery, Scenery.LEVER_4958, 2) 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) val varp = getVarp(player, HauntedMine.pointsSettingsVarp) xor 1.shl(2)
setVarp(player, HauntedMine.pointsSettingsVarp, varp) setVarp(player, HauntedMine.pointsSettingsVarp, varp)
sendMessage(player, "You pull the lever. The old points creak into place.") sendMessage(player, "You pull the lever. The old points creak into place.")
@ -153,5 +226,74 @@ class HauntedMineListeners : InteractionListener {
return@on true 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. // logic to check for, push, and damage players.
override fun tick(self: NPC): Boolean { override fun tick(self: NPC): Boolean {
for (p in self.viewport.currentPlane.players) { 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)*/) { 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) forceMove(p, p.location,self.location.transform(self.direction,1),0,0)
impact(p,random(0,2)) impact(p,random(0,2))

View file

@ -1,6 +1,7 @@
package content.region.morytania.quest.hauntedmine package content.region.morytania.quest.hauntedmine
import core.api.* import core.api.*
import core.game.dialogue.FacialExpression
import core.game.interaction.InterfaceListener import core.game.interaction.InterfaceListener
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
@ -33,6 +34,7 @@ import core.game.node.entity.player.Player
class PointsSettingsInterface : InterfaceListener { class PointsSettingsInterface : InterfaceListener {
//todo make this interface close if the player moves
override fun defineInterfaceListeners() { override fun defineInterfaceListeners() {
on(HauntedMine.pointsSettingsInterface) { player, _, _, buttonID, _, _ -> on(HauntedMine.pointsSettingsInterface) { player, _, _, buttonID, _, _ ->
when (buttonID) { when (buttonID) {
@ -49,8 +51,8 @@ class PointsSettingsInterface : InterfaceListener {
private fun checkCartRoute(player: Player) { private fun checkCartRoute(player: Player) {
player.debug("points varp is:") //player.debug("points varp is:")
player.debug(getVarp(player,HauntedMine.pointsSettingsVarp).toString()) //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. // 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. 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) val varp = getVarp(player, HauntedMine.pointsSettingsVarp) xor 7.shl(12)
setVarp(player, HauntedMine.pointsSettingsVarp, varp) setVarp(player, HauntedMine.pointsSettingsVarp, varp)
setAttribute(player, HauntedMine.attributeCartSent, true) 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 { } else {
// if wrong, clear the fungus out of the cart. // if wrong, clear the fungus out of the cart.
setAttribute(player, HauntedMine.attributeFungusPlaced, false) setAttribute(player, HauntedMine.attributeFungusPlaced, false)

View file

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