Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import world.gregs.voidps.engine.Script
import world.gregs.voidps.engine.client.instruction.handle.interactPlayer
import world.gregs.voidps.engine.client.message
import world.gregs.voidps.engine.entity.character.npc.NPCs
import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.inv.add
import world.gregs.voidps.engine.inv.inventory
import world.gregs.voidps.engine.queue.queue
Expand All @@ -20,47 +21,21 @@ class LumbridgeSwamp : Script {

init {
objectOperate("Search", "rocks_skull_restless_ghost_quest") {
if (quest("the_restless_ghost") != "mining_spot" && quest("the_restless_ghost") != "found_skull") {
message("There's nothing there of any use to you.")
return@objectOperate
}
if (inventory.isFull()) {
message("You can see the skull under the rocks, but you don't have enough space to carry it.")
return@objectOperate
}
statement("You take the skull from the pile of rocks.")
inventory.add("muddy_skull")
set("rocks_restless_ghost", "no_skull")
set("the_restless_ghost", "found_skull")
val index: Int? = remove("restless_ghost_warlock")
if (index != null) {
val skeleton = NPCs.indexed(index)
if (skeleton != null) {
NPCs.remove(skeleton)
}
}
message("A skeleton warlock has appeared.")
val warlock = NPCs.add("skeleton_warlock", Tile(3236, 3149), Direction.SOUTH, ticks = TimeUnit.SECONDS.toTicks(60), owner = this)
set("restless_ghost_warlock", warlock.index)
warlock.anim("restless_ghost_warlock_spawn")
val player = this
warlock.queue("delayed_attack", 4) {
warlock.interactPlayer(player, "Attack")
}
takeSkull()
}

objectOperate("Search", "rocks_no_skull_restless_ghost_quest") {
if (quest("the_restless_ghost") == "completed") {
message("There's nothing of any interest.")
} else {
message("You already have the ghost's skull.")
return@objectOperate
}
}

playerDeath {
if (!ownsItem("muddy_skull")) {
set("rocks_restless_ghost", "skull")
if (ownsItem("muddy_skull")) {
message("You already have the ghost's skull.")
return@objectOperate
}
// The skull is no longer held (died with it, dropped it, or let the gravestone
// expire) so it's back under the rocks rather than being lost for good.
takeSkull()
}

destroyed("muddy_skull") {
Expand Down Expand Up @@ -89,4 +64,34 @@ class LumbridgeSwamp : Script {
)
}
}

suspend fun Player.takeSkull() {
if (quest("the_restless_ghost") != "mining_spot" && quest("the_restless_ghost") != "found_skull") {
message("There's nothing there of any use to you.")
return
}
if (inventory.isFull()) {
message("You can see the skull under the rocks, but you don't have enough space to carry it.")
return
}
statement("You take the skull from the pile of rocks.")
inventory.add("muddy_skull")
set("rocks_restless_ghost", "no_skull")
set("the_restless_ghost", "found_skull")
val index: Int? = remove("restless_ghost_warlock")
if (index != null) {
val skeleton = NPCs.indexed(index)
if (skeleton != null) {
NPCs.remove(skeleton)
}
}
message("A skeleton warlock has appeared.")
val warlock = NPCs.add("skeleton_warlock", Tile(3236, 3149), Direction.SOUTH, ticks = TimeUnit.SECONDS.toTicks(60), owner = this)
set("restless_ghost_warlock", warlock.index)
warlock.anim("restless_ghost_warlock_spawn")
val player = this
warlock.queue("delayed_attack", 4) {
warlock.interactPlayer(player, "Attack")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,55 @@ class RestlessGhostQuest : WorldTest() {
assertEquals("completed", player.quest("the_restless_ghost"))
assertEquals(1125.0, player.experience.get(Skill.Prayer))
}

@Test
fun `Search the rocks again after losing the skull on death`() {
val player = createPlayer(Tile(3234, 3147))
player["the_restless_ghost"] = "mining_spot"

val rock = GameObjects.find(Tile(3234, 3145), "rocks_skull_restless_ghost_quest_base")
player.interactObject(rock, "Search")
tick()
player.continueDialogue()

assertEquals(1, player.inventory.count("muddy_skull"))
assertEquals("no_skull", player["rocks_restless_ghost", ""])

// Die in the wilderness so the skull is dropped rather than kept, and never reclaimed.
player.tele(3100, 3550)
tick(2)
player.levels.set(Skill.Constitution, 0)
tick(10)
assertEquals(0, player.inventory.count("muddy_skull"))

// The rocks now show as emptied but must hand the skull back rather than dead-end the quest.
player.tele(3234, 3147)
tick()
val emptyRock = GameObjects.find(Tile(3234, 3145), "rocks_skull_restless_ghost_quest_base")
player.interactObject(emptyRock, "Search")
tick()
player.continueDialogue()

assertEquals(1, player.inventory.count("muddy_skull"))
assertEquals("found_skull", player.quest("the_restless_ghost"))
}

@Test
fun `Rocks stay empty while still carrying the skull`() {
val player = createPlayer(Tile(3234, 3147))
player["the_restless_ghost"] = "mining_spot"

val rock = GameObjects.find(Tile(3234, 3145), "rocks_skull_restless_ghost_quest_base")
player.interactObject(rock, "Search")
tick()
player.continueDialogue()
assertEquals(1, player.inventory.count("muddy_skull"))

player.interactObject(GameObjects.find(Tile(3234, 3145), "rocks_skull_restless_ghost_quest_base"), "Search")
tick()

// No "You take the skull" statement, no second skull.
assertNull(player.dialogue)
assertEquals(1, player.inventory.count("muddy_skull"))
}
}
Loading