mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-01 14:39:13 -06:00
various suggested fixes 2
This commit is contained in:
parent
d8c7b681bb
commit
b22525e204
7 changed files with 140 additions and 65 deletions
|
|
@ -4736,8 +4736,6 @@
|
|||
"name": "Ghost's skull",
|
||||
"examine": "Ooooh spooky!",
|
||||
"archery_ticket_price": "0",
|
||||
"destroy": "true",
|
||||
"destroy_message": "If you get rid of the skull you'll have to search for it again.",
|
||||
"durability": null,
|
||||
"tradeable": "false"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,15 +30,13 @@ class OldCroneDialogueFile : DialogueLabeller() {
|
|||
|
||||
override fun addConversation() {
|
||||
|
||||
label("anma_entry") {
|
||||
exec { player, npc ->
|
||||
when (getQuestStage(player, Quests.ANIMAL_MAGNETISM)) {
|
||||
16, 17, 18 -> {
|
||||
loadLabel(player, "about_the_farmers")
|
||||
}
|
||||
else -> {
|
||||
loadLabel(player, "hello_old")
|
||||
}
|
||||
exec { player, npc ->
|
||||
when (getQuestStage(player, Quests.ANIMAL_MAGNETISM)) {
|
||||
16, 17, 18 -> {
|
||||
loadLabel(player, "about_the_farmers")
|
||||
}
|
||||
else -> {
|
||||
loadLabel(player, "hello_old")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,22 +32,21 @@ class FatherAereckDefaultDialogue : InteractionListener {
|
|||
class FatherAereckDefaultDialogueFile : DialogueLabeller() {
|
||||
override fun addConversation() {
|
||||
|
||||
label("entry_logic")
|
||||
//allows skipping the main dialogue while Restless Ghost quest is started
|
||||
exec { player, npc ->
|
||||
when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) {
|
||||
0 -> {
|
||||
loadLabel(player, "main_entry_transcript")
|
||||
}
|
||||
10, 20, 30, 40 -> {
|
||||
//passthrough for mid-quest dialogue skip
|
||||
open(player, FatherAereckQuestDialogueFile(), npc)
|
||||
}
|
||||
else -> {
|
||||
loadLabel(player, "main_entry_transcript")
|
||||
}
|
||||
//allows skipping the main dialogue while Restless Ghost quest is started
|
||||
exec { player, npc ->
|
||||
when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) {
|
||||
0 -> {
|
||||
loadLabel(player, "main_entry_transcript")
|
||||
}
|
||||
10, 20, 30, 40 -> {
|
||||
//passthrough for mid-quest dialogue skip
|
||||
open(player, FatherAereckQuestDialogueFile(), npc)
|
||||
}
|
||||
else -> {
|
||||
loadLabel(player, "main_entry_transcript")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label("main_entry_transcript") {
|
||||
npc("Welcome to the church of holy Saradomin.")
|
||||
|
|
|
|||
|
|
@ -33,18 +33,16 @@ class FatherUrhneyDefaultDialogueFile: DialogueLabeller() {
|
|||
|
||||
npc(FacialExpression.ANGRY, "Go away! I'm meditating!");
|
||||
|
||||
label("main_opts") {
|
||||
exec {player, npc ->
|
||||
when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) {
|
||||
0 -> {
|
||||
loadLabel(player, "pre_quest_opts")
|
||||
}
|
||||
10 -> {
|
||||
loadLabel(player, "mid_quest_opts")
|
||||
}
|
||||
else -> {
|
||||
loadLabel(player, "post_quest_opts")
|
||||
}
|
||||
exec { player, npc ->
|
||||
when (getQuestStage(player, Quests.THE_RESTLESS_GHOST)) {
|
||||
0 -> {
|
||||
loadLabel(player, "pre_quest_opts")
|
||||
}
|
||||
10 -> {
|
||||
loadLabel(player, "mid_quest_opts")
|
||||
}
|
||||
else -> {
|
||||
loadLabel(player, "post_quest_opts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package content.region.misthalin.lumbridge.quest.therestlessghost;
|
|||
import content.data.Quests
|
||||
import core.api.getQuestStage
|
||||
import core.api.setQuestStage
|
||||
import core.api.setVarbit
|
||||
import core.game.dialogue.DialogueLabeller
|
||||
import core.game.dialogue.DialogueOption
|
||||
import core.game.dialogue.FacialExpression
|
||||
|
|
@ -63,6 +64,9 @@ class FatherAereckQuestDialogueFile : DialogueLabeller() {
|
|||
label("let_me_help") {
|
||||
exec { player, npc ->
|
||||
setQuestStage(player, Quests.THE_RESTLESS_GHOST, 10)
|
||||
//ensures the varbits is set to default state
|
||||
setVarbit(player, 2128, 0, true)
|
||||
setVarbit(player, 2130, 0, true)
|
||||
}
|
||||
|
||||
npc("Thank you. The problem is, there is a ghost in the", "church graveyard. I would like you to get rid of it.")
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ class RestlessGhost : Quest(Quests.THE_RESTLESS_GHOST, 25, 24, 1, 107, 0, 4, 5)
|
|||
player.interfaceManager.closeChatbox()
|
||||
|
||||
player.packetDispatch.sendString("You have completed The Restless Ghost Quest!", 277, 2 + 2)
|
||||
setVarp(player, 728, 31, true)
|
||||
|
||||
//post quest skeleton scenery and altar visually correct
|
||||
setVarbit(player, 2128, 1, true)
|
||||
setVarbit(player, 2130, 1, true)
|
||||
|
||||
//setVarp(player, 728, 31, true)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package content.region.misthalin.lumbridge.quest.therestlessghost;
|
|||
|
||||
import content.data.Quests
|
||||
import core.api.*
|
||||
import core.game.global.action.DropListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.Entity
|
||||
|
|
@ -9,6 +10,7 @@ import core.game.node.entity.combat.CombatStyle
|
|||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.scenery.SceneryBuilder
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
|
|
@ -22,17 +24,20 @@ import org.rs09.consts.Sounds
|
|||
/**
|
||||
* Authenticity source Aug 18 2009
|
||||
* https://www.youtube.com/watch?v=ikbX12Xywxs
|
||||
* https://www.youtube.com/watch?v=gC3qR9tKJMI
|
||||
* * Author Beck, Vexia
|
||||
**/
|
||||
class RestlessGhostListeners : InteractionListener {
|
||||
|
||||
companion object {
|
||||
//This is not in the Animations consts
|
||||
//This is not in the Animations consts, added in Constlib MR !22
|
||||
private const val Animations_HUMAN_CLOSE_CHEST_535 = 535
|
||||
|
||||
private const val CLOSED_COFFIN = Scenery.COFFIN_2145
|
||||
private const val INCOMPLETE_COFFIN_OPEN = Scenery.COFFIN_15052
|
||||
private const val COMPLETE_COFFIN_OPEN = Scenery.COFFIN_15053
|
||||
private const val ALTAR_WITH_SKULL = Scenery.ALTAR_15050
|
||||
private const val ALTAR_NO_SKULL = Scenery.ALTAR_15051
|
||||
|
||||
private fun createRestlessGhostNPC() : NPC {
|
||||
val restlessGhostNPC = NPC(NPCs.RESTLESS_GHOST_457, Location(3250, 3195, 0))
|
||||
|
|
@ -45,14 +50,26 @@ class RestlessGhostListeners : InteractionListener {
|
|||
return restlessGhostNPC
|
||||
}
|
||||
|
||||
//removes the skeleton on ground, resets in ~2mins
|
||||
private fun animSkeleAlive(player: Player, skeleScenery: core.game.node.scenery.Scenery) {
|
||||
|
||||
// TODO: find animation and maybe sfx of the skeleton coming alive, from a still scenery of a skeleton slumped on the ground against the wall and then rises to life
|
||||
|
||||
queueScript(player, 4) {_ ->
|
||||
SceneryBuilder.remove(skeleScenery, 200)
|
||||
return@queueScript stopExecuting(player)
|
||||
//Scenery 15057 changes to 15060 hidden and plays animation, resets in ~2mins if player still doing quest, otherwise it stays at 15060 forever
|
||||
private fun animSkeleAlive(player: Player) {
|
||||
|
||||
//set scenery to 15060 which hides the ground skeleton
|
||||
setVarbit(player, 2128, 1, true)
|
||||
|
||||
// TODO: Scenery skeleton id 15057 turns into a hidden 15060 then with an animation, uses varbit 2128, client side only
|
||||
// TODO: find animation and maybe sfx of the skeleton coming alive, from a still scenery 15057 (15060 is the post animation?) of a skeleton slumped on the ground against the wall and then rises to life
|
||||
// TODO: convert to queuescript on Scenery objects when engine is capable to be attached to them.
|
||||
// https://www.youtube.com/watch?v=gC3qR9tKJMI
|
||||
|
||||
// Use world pulse in the mean time, in the edge case where a player logs off in middle of the script
|
||||
if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) in 30..40) {
|
||||
submitWorldPulse(object : Pulse(200) {
|
||||
override fun pulse(): Boolean {
|
||||
//resets the skeleton on the ground
|
||||
setVarbit(player, 2128, 0, true)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,8 +123,8 @@ class RestlessGhostListeners : InteractionListener {
|
|||
toggleCoffinSceneryObj(player, node as core.game.node.scenery.Scenery)
|
||||
|
||||
if (!isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) {
|
||||
//is this from the center of the scenery/node object?
|
||||
val ghostExists = RegionManager.getLocalNPCs(node.centerLocation).find { it.id == NPCs.RESTLESS_GHOST_457 }
|
||||
//val ghostExists = RegionManager.getLocalNpcs(node.centerLocation).find { it.id == NPCs.RESTLESS_GHOST_457 }
|
||||
|
||||
//not within rendering distance or doesn't exist at all
|
||||
if (ghostExists == null) {
|
||||
|
|
@ -115,11 +132,21 @@ class RestlessGhostListeners : InteractionListener {
|
|||
val ghost = createRestlessGhostNPC()
|
||||
|
||||
//despawn ghost after awhile and shut the coffin
|
||||
queueScript(player, 200) { _ ->
|
||||
// TODO: convert to queuescript on Scenery objects when engine is capable to be attached to them.
|
||||
// Use world pulse in the mean time, in the edge case where a player logs off in middle of the script
|
||||
/* queueScript(player, 200) { _ ->
|
||||
ghost.clear()
|
||||
toggleCoffinSceneryObj(player, node)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
} */
|
||||
|
||||
submitWorldPulse(object : Pulse(200) {
|
||||
override fun pulse(): Boolean {
|
||||
ghost.clear()
|
||||
toggleCoffinSceneryObj(player, node)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,42 +193,88 @@ class RestlessGhostListeners : InteractionListener {
|
|||
|
||||
with as core.game.node.scenery.Scenery
|
||||
SceneryBuilder.replace(with, with.transform(COMPLETE_COFFIN_OPEN))
|
||||
|
||||
}
|
||||
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
on(Scenery.ALTAR_15050, IntType.SCENERY, "search") { player, node ->
|
||||
on(ALTAR_WITH_SKULL, IntType.SCENERY, "search") { player, node ->
|
||||
|
||||
if (!inInventory(player, Items.GHOSTS_SKULL_553)) {
|
||||
if (!inInventory(player, Items.GHOSTS_SKULL_553) && !inBank(player, Items.GHOSTS_SKULL_553)) {
|
||||
if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) !in 30..40) {
|
||||
sendMessage(player, "You search the altar and find nothing.")
|
||||
} else {
|
||||
if (freeSlots(player) >= 1) {
|
||||
if (addItem(player, Items.GHOSTS_SKULL_553)) {
|
||||
setQuestStage(player, Quests.THE_RESTLESS_GHOST, 40)
|
||||
sendMessage(player, "The skeleton in the corner suddenly comes to life!")
|
||||
|
||||
//skele comes to live from scenery 15057 with an animation,
|
||||
//but idk how to select it to at least remove/hide it from the world briefly
|
||||
//animSkeleAlive(player, node as core.game.node.scenery.Scenery)
|
||||
|
||||
//spawn in skeleton
|
||||
val s = createLevel13SkeletonNPC(player)
|
||||
//update altar to without the skull, altar is now scenery 15051
|
||||
setVarbit(player, 2130, 1, true)
|
||||
|
||||
//if skeleton scenery is visible such first time coming alive
|
||||
//so that it can only be killed/spawned to attack once to prevent some sort of griefing exploit
|
||||
if (getVarbit(player, 2128) == 0) {
|
||||
sendMessage(player, "The skeleton in the corner suddenly comes to life!")
|
||||
|
||||
// despawn after awhile if it never dies
|
||||
// so there isnt a group of them for next visitor lol
|
||||
queueScript(player, 200) { _ ->
|
||||
s.clear()
|
||||
return@queueScript stopExecuting(player)
|
||||
animSkeleAlive(player)
|
||||
|
||||
//spawn in skeleton
|
||||
val s = createLevel13SkeletonNPC(player)
|
||||
|
||||
// despawn after awhile if it never dies so there isnt a group of them for next visitor lol
|
||||
|
||||
// TODO: convert to queuescript on Scenery objects when engine is capable to be attached to them.
|
||||
// Use world pulse in the mean time, in the edge case where a player logs off in middle of the script
|
||||
|
||||
/* queueScript(player, 200) { _ ->
|
||||
s.clear()
|
||||
return@queueScript stopExecuting(player)
|
||||
} */
|
||||
|
||||
submitWorldPulse(object : Pulse(200) {
|
||||
override fun pulse(): Boolean {
|
||||
s.clear()
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sendMessage(player, "You don't have enough inventory space.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(ALTAR_NO_SKULL, IntType.SCENERY, "search") { player, node ->
|
||||
//Mainly for a weird edge case if some how the varbit wasn't set correctly
|
||||
if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) !in 30..40) {
|
||||
sendMessage(player, "You search the altar and find nothing.")
|
||||
} else {
|
||||
if (!inInventory(player, Items.GHOSTS_SKULL_553) && !inBank(player, Items.GHOSTS_SKULL_553)) {
|
||||
//guard clause if for when player does the drop trick, etc
|
||||
if (!addItem(player, Items.GHOSTS_SKULL_553)) {
|
||||
sendMessage(player, "You don't have enough inventory space.")
|
||||
}
|
||||
} else {
|
||||
// TODO: Authenticity check needed for exact message
|
||||
sendMessage(player, "You already have the Ghost's Skull!")
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Items.GHOSTS_SKULL_553, IntType.ITEM, "drop") { player, node ->
|
||||
DropListener.drop(player, node.asItem())
|
||||
|
||||
if (getQuestStage(player, Quests.THE_RESTLESS_GHOST) in 30..40) {
|
||||
//update altar to one with the skull, altar is now scenery 15060
|
||||
setVarbit(player, 2130, 0, true)
|
||||
}
|
||||
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue