Made random event teleports more robust, fixing edge cases

This commit is contained in:
Player Name 2025-02-16 07:00:13 +00:00 committed by Ryan
parent be47c1d5c9
commit f1131b7d00
18 changed files with 109 additions and 114 deletions

View file

@ -0,0 +1,23 @@
package content.global.ame
import core.ServerConstants
import core.api.*
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager.TeleportType
import core.game.world.map.Location
fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) {
setAttribute(player, "kidnapped-by-random", true)
if (getAttribute(player, "/save:original-loc", null) == null) {
setAttribute(player, "/save:original-loc", player.location)
}
teleport(player, loc, type)
}
fun returnPlayer(player: Player) {
player.locks.unlockTeleport()
val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
teleport(player, destination)
unlock(player)
removeAttributes(player, "/save:original-loc", "kidnapped-by-random")
}

View file

@ -3,7 +3,7 @@ package content.global.ame
import org.rs09.consts.Items
import content.global.ame.events.MysteriousOldManNPC
import content.global.ame.events.certer.CerterNPC
import content.global.ame.events.drilldemon.SeargentDamienNPC
import content.global.ame.events.drilldemon.SergeantDamienNPC
import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC
import content.global.ame.events.evilbob.EvilBobNPC
import content.global.ame.events.evilchicken.EvilChickenNPC
@ -47,7 +47,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1)
)),
MAZE(npc = MazeNPC()),
DRILL_DEMON(npc = SeargentDamienNPC()),
DRILL_DEMON(npc = SergeantDamienNPC()),
EVIL_CHICKEN(npc = EvilChickenNPC()),
STRANGE_PLANT(npc = StrangePlantNPC()),
SWARM(npc = SwarmNPC()),

View file

@ -1,9 +1,11 @@
package content.global.ame.events.drilldemon
import core.ServerConstants
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.*
import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.context.Animation
@ -12,7 +14,6 @@ import org.rs09.consts.NPCs
object DrillDemonUtils {
val DD_KEY_TASK = "/save:drilldemon:task"
val DD_KEY_RETURN_LOC = "/save:original-loc"
val DD_SIGN_VARP = 531
val DD_SIGN_JOG = 0
val DD_SIGN_SITUP = 1
@ -24,10 +25,7 @@ object DrillDemonUtils {
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
fun teleport(player: Player) {
if (getAttribute(player, DD_KEY_RETURN_LOC, null) == null) {
setAttribute(player, DD_KEY_RETURN_LOC, player.location)
}
teleport(player, Location.create(3163, 4819, 0))
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT)
player.interfaceManager.closeDefaultTabs()
setComponentVisibility(player, 548, 69, true)
setComponentVisibility(player, 746, 12, true)
@ -66,14 +64,8 @@ object DrillDemonUtils {
}
fun cleanup(player: Player) {
player.locks.unlockTeleport()
unlock(player)
val destination = getAttribute(player, DD_KEY_RETURN_LOC, ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
teleport(player, destination)
removeAttribute(player, DD_KEY_RETURN_LOC)
removeAttribute(player, DD_KEY_TASK)
removeAttribute(player, DD_CORRECT_OFFSET)
removeAttribute(player, DD_CORRECT_COUNTER)
returnPlayer(player)
removeAttributes(player, DD_KEY_TASK, DD_CORRECT_OFFSET, DD_CORRECT_COUNTER)
player.interfaceManager.openDefaultTabs()
setComponentVisibility(player, 548, 69, false)
setComponentVisibility(player, 746, 12, false)

View file

@ -10,11 +10,11 @@ import core.game.interaction.QueueStrength
import core.game.system.timer.impl.AntiMacro
import core.tools.secondsToTicks
class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
override fun init() {
super.init()
sendChat(player.username.capitalize() + "! Drop and give me 20!")
sendChat(player.username+ "! Drop and give me 20!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {

View file

@ -1,5 +1,6 @@
package content.global.ame.events.evilbob
import content.global.ame.returnPlayer
import core.ServerConstants
import core.api.*
import core.game.dialogue.FacialExpression
@ -8,8 +9,6 @@ import core.game.interaction.InteractionListener
import core.game.interaction.QueueStrength
import core.game.node.entity.Entity
import core.game.node.entity.player.link.emote.Emotes
import core.game.node.entity.skill.Skills
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
@ -121,8 +120,7 @@ class EvilBobListeners : InteractionListener, MapArea {
}
3 -> {
sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.")
val destination = getAttribute(player, EvilBobUtils.prevLocation, ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
teleport(player, destination)
returnPlayer(player)
EvilBobUtils.reward(player)
EvilBobUtils.cleanup(player)
resetAnimator(player)

View file

@ -1,8 +1,10 @@
package content.global.ame.events.evilbob
import core.ServerConstants
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.*
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.skill.Skills
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
@ -14,7 +16,6 @@ import org.rs09.consts.NPCs
import org.rs09.consts.Scenery
object EvilBobUtils {
const val prevLocation = "/save:original-loc"
const val eventComplete = "/save:evilbob:eventcomplete"
const val assignedFishingZone = "/save:evilbob:fishingzone"
const val attentive = "/save:evilbob:attentive"
@ -53,16 +54,11 @@ object EvilBobUtils {
}
fun teleport(player: Player) {
if (getAttribute(player, prevLocation, null) == null) {
setAttribute(player, prevLocation, player.location)
}
player.properties.teleportLocation = Location.create(3419, 4776, 0)
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player) {
player.locks.unlockTeleport()
player.properties.teleportLocation = getAttribute(player, prevLocation, ServerConstants.HOME_LOCATION)
removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
removeAll(player, Items.FISHLIKE_THING_6202)
removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK)
removeAll(player, Items.FISHLIKE_THING_6206)

View file

@ -1,17 +1,18 @@
package content.global.ame.events.freakyforester
import core.ServerConstants
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.*
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.tools.RandomFunction
object FreakUtils{
const val freakNpc = NPCs.FREAKY_FORESTER_2458
const val freakPreviousLoc = "/save:original-loc"
const val freakTask = "/save:freakyf:task"
const val freakComplete = "/save:freakyf:complete"
const val pheasantKilled = "freakyf:killed"
@ -28,16 +29,12 @@ object FreakUtils{
}
fun teleport(player: Player) {
if (getAttribute(player, freakPreviousLoc,null) == null) {
setAttribute(player, freakPreviousLoc, player.location)
}
teleport(player, Location.create(2599, 4777 ,0))
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player) {
player.locks.unlockTeleport()
player.properties.teleportLocation = getAttribute(player,freakPreviousLoc, ServerConstants.HOME_LOCATION)
removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled)
returnPlayer(player)
removeAttributes(player, freakTask, freakComplete, pheasantKilled)
removeAll(player, Items.RAW_PHEASANT_6178)
removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK)
removeAll(player, Items.RAW_PHEASANT_6179)

View file

@ -1,5 +1,6 @@
package content.global.ame.events.maze
import content.global.ame.returnPlayer
import core.api.*
import core.api.utils.WeightBasedTable
import core.api.utils.WeightedItem
@ -11,7 +12,6 @@ import core.game.interaction.InteractionListener
import core.game.interaction.QueueStrength
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.node.scenery.SceneryBuilder
import core.game.system.task.Pulse
import core.game.world.GameWorld.Pulser
import core.game.world.map.Location
@ -24,7 +24,6 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
companion object {
const val MAZE_TIMER_INTERFACE = Components.MAZETIMER_209
const val MAZE_TIMER_VARP = 531 // Interface 209 child 2 config: [531, 0]
const val MAZE_ATTRIBUTE_RETURN_LOC = "/save:original-loc"
const val MAZE_ATTRIBUTE_TICKS_LEFT = "maze:percent-ticks-left"
const val MAZE_ATTRIBUTE_CHESTS_OPEN = "/save:maze:chests-opened"
@ -217,9 +216,8 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
return@queueScript delayScript(player, 3)
}
2 -> {
teleport(player, getAttribute(player, MAZE_ATTRIBUTE_RETURN_LOC, Location.create(3222, 3218, 0)))
returnPlayer(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
removeAttribute(player, MAZE_ATTRIBUTE_RETURN_LOC)
animate(player,8941)
closeOverlay(player)
return@queueScript delayScript(player, 1)

View file

@ -1,10 +1,12 @@
package content.global.ame.events.maze
import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.TeleportManager
import core.game.system.timer.impl.AntiMacro
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
@ -28,9 +30,6 @@ class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null
return@queueScript delayScript(player, 3)
}
1 -> {
if (getAttribute<Location?>(player, MazeInterface.MAZE_ATTRIBUTE_RETURN_LOC, null) == null) {
setAttribute(player, MazeInterface.MAZE_ATTRIBUTE_RETURN_LOC, player.location)
}
MazeInterface.initMaze(player)
// Note: This event is NOT instanced:
// Sources:
@ -40,7 +39,7 @@ class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null
// https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for."
// https://youtu.be/FMuKZm-Ikgs (2011)
// val region = DynamicRegion.create(11591)
teleport(player, MazeInterface.STARTING_POINTS.random()) // 10 random spots
kidnapPlayer(player, MazeInterface.STARTING_POINTS.random(), TeleportManager.TeleportType.INSTANT) // 10 random spots
AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)

View file

@ -1,6 +1,7 @@
package content.global.ame.events.pillory
import content.global.ame.RandomEvents
import content.global.ame.returnPlayer
import core.api.*
import core.game.dialogue.FacialExpression
import core.game.interaction.IntType
@ -42,11 +43,10 @@ import org.rs09.consts.Sounds
class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
companion object {
const val PILLORY_LOCK_INTERFACE = 189
const val PILLORY_ATRRIBUTE_RETURN_LOC = "/save:original-loc"
const val PILLORY_ATTRIBUTE_EVENT_KEYS = "pillory:event-keys"
const val PILLORY_ATTRIBUTE_EVENT_LOCK = "pillory:event-lock"
const val PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct"
const val PILLORY_ATRRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct"
const val PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct"
const val PILLORY_ATTRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct"
val LOCATIONS = arrayOf(
// Varrock Cages
@ -64,8 +64,8 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
)
fun initPillory(player: Player) {
setAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3)
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3)
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
}
@ -82,8 +82,8 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
player.packetDispatch.sendModelOnInterface(9749 + keys[2], PILLORY_LOCK_INTERFACE, 6, 0)
player.packetDispatch.sendModelOnInterface(9749 + keys[3], PILLORY_LOCK_INTERFACE, 7, 0)
val numberToGetCorrect = getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3)
val correctCount = getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
val numberToGetCorrect = getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3)
val correctCount = getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
for (i in 1.. 6) {
// Set if lock is red or green.
if (i <= correctCount) {
@ -101,12 +101,12 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
val lock = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, -1)
if (keys[buttonID] == lock) {
// CORRECT ANSWER
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0) + 1)
if (getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, -1)) {
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + 1)
if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, -1)) {
player.dialogueInterpreter.sendPlainMessage(true, "", "You've escaped!")
sendMessage(player, "You've escaped!")
removeAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT)
removeAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER)
removeAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT)
removeAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER)
closeInterface(player)
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
when (stage) {
@ -120,10 +120,9 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
1 -> {
val loot = RandomEvents.CERTER.loot!!.roll(player)[0]
addItemOrDrop(player, loot.id, loot.amount)
teleport(player, getAttribute(player, PILLORY_ATRRIBUTE_RETURN_LOC, Location.create(3222, 3218, 0)))
returnPlayer(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
removeAttribute(player, PILLORY_ATRRIBUTE_RETURN_LOC)
closeInterface(player)
return@queueScript stopExecuting(player)
}
@ -137,19 +136,19 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
true,
"",
"Correct!",
"" + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0) + " down, " +
(getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)) + " to go!")
"" + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + " down, " +
(getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)) + " to go!")
// Animation for the star, but it doesn't work.
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 1), false)
sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 1))
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1), false)
sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1))
} else {
// WRONG ANSWER
player.dialogueInterpreter.close()
player.dialogueInterpreter.sendDialogues(NPCs.TRAMP_2794 , FacialExpression.OLD_ANGRY1, "Bah, that's not right.","Use the key that matches the hole", "in the spinning lock.")
if (getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) {
setAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1)
if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) {
setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1)
}
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
closeInterface(player)
}
}

View file

@ -1,10 +1,12 @@
package content.global.ame.events.pillory
import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.TeleportManager
import core.game.system.timer.impl.AntiMacro
import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
@ -29,11 +31,9 @@ class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(N
return@queueScript delayScript(player, 3)
}
1 -> {
if (getAttribute<Location?>(player, PilloryInterface.PILLORY_ATRRIBUTE_RETURN_LOC, null) == null) {
setAttribute(player, PilloryInterface.PILLORY_ATRRIBUTE_RETURN_LOC, player.location)
}
PilloryInterface.initPillory(player)
teleport(player, PilloryInterface.LOCATIONS.random()) // 9 random spots!
val dest = PilloryInterface.LOCATIONS.random() //9 random spots!
kidnapPlayer(player, dest, TeleportManager.TeleportType.INSTANT)
AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)

View file

@ -1,5 +1,6 @@
package content.global.ame.events.quizmaster
import content.global.ame.returnPlayer
import core.ServerConstants
import core.api.*
import core.api.utils.WeightBasedTable
@ -8,7 +9,6 @@ import core.game.dialogue.DialogueFile
import core.game.dialogue.FacialExpression
import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.tools.END_DIALOGUE
import org.rs09.consts.Components
import org.rs09.consts.Items
@ -16,7 +16,6 @@ import org.rs09.consts.Items
class QuizMasterDialogueFile : DialogueFile() {
companion object {
const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191
const val QUIZMASTER_ATTRIBUTE_RETURN_LOC = "/save:original-loc"
const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct"
const val QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER = "quizmaster:random-answer"
@ -106,7 +105,7 @@ class QuizMasterDialogueFile : DialogueFile() {
5 -> options("1000 Coins", "Random Item").also { stage++ }
6 -> {
resetAnimator(player!!)
teleport(player!!, getAttribute(player!!, QUIZMASTER_ATTRIBUTE_RETURN_LOC, Location.create(3222, 3218, 0)))
returnPlayer(player!!)
when (buttonID) {
1 -> {
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
@ -121,9 +120,7 @@ class QuizMasterDialogueFile : DialogueFile() {
}
}
}
removeAttribute(player!!, QUIZMASTER_ATTRIBUTE_RETURN_LOC)
removeAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT)
removeAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
removeAttributes(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
stage = END_DIALOGUE
end()
}

View file

@ -1,10 +1,12 @@
package content.global.ame.events.quizmaster
import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.TeleportManager
import core.game.system.timer.impl.AntiMacro
import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
@ -35,12 +37,8 @@ class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable?
return@queueScript delayScript(player, 3)
}
1 -> {
if (getAttribute<Location?>(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_RETURN_LOC, null) == null) {
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_RETURN_LOC, player.location)
}
kidnapPlayer(player, Location(1952, 4764, 1), TeleportManager.TeleportType.INSTANT)
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
//MazeInterface.initMaze(player)
teleport(player, Location(1952, 4764, 1))
AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)

View file

@ -10,6 +10,7 @@ import core.game.interaction.InteractionListener
import core.game.interaction.IntType
import content.global.handlers.iface.ExperienceInterface
import core.api.MapArea
import core.api.removeItem
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
@ -23,7 +24,7 @@ class SupriseExamListeners : InteractionListener, MapArea {
return@on true
}
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open"){ player, node ->
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open") { player, node ->
val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1)
if(correctDoor == -1){
@ -42,7 +43,7 @@ class SupriseExamListeners : InteractionListener, MapArea {
on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ ->
player.setAttribute("caller") { skill: Int, p: Player ->
if (p.inventory.remove(Item(Items.BOOK_OF_KNOWLEDGE_11640))) {
if (removeItem(p, Items.BOOK_OF_KNOWLEDGE_11640)) {
val level = p.skills.getStaticLevel(skill)
val experience = level * 15.0
p.skills.addExperience(skill, experience)

View file

@ -1,22 +1,18 @@
package content.global.ame.events.surpriseexam
import core.Server
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.*
import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.map.Location
import org.rs09.consts.Components
import org.rs09.consts.Items
import core.ServerConstants
import core.game.node.entity.player.link.TeleportManager
object SurpriseExamUtils {
val SE_KEY_LOC = "/save:original-loc"
val SE_KEY_INDEX = "supexam:index"
val SE_LOGOUT_KEY = "suprise_exam"
val SE_DOOR_KEY = "supexam:door"
val INTER_PATTERN_CHILDS = intArrayOf(6,7,8)
val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13)
@ -30,20 +26,13 @@ object SurpriseExamUtils {
intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311)
)
fun teleport(player: Player){
if (getAttribute(player, SE_KEY_LOC, null) == null) {
player.setAttribute(SE_KEY_LOC, player.location)
}
registerLogoutListener(player, SE_LOGOUT_KEY){p ->
p.location = getAttribute(p, SE_KEY_LOC, ServerConstants.HOME_LOCATION)
}
player.properties.teleportLocation = Location.create(1886, 5025, 0)
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(1886, 5025, 0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player){
player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC, ServerConstants.HOME_LOCATION)
clearLogoutListener(player, SE_LOGOUT_KEY)
removeAttributes(player, SE_KEY_LOC, SE_KEY_INDEX, SE_KEY_CORRECT)
returnPlayer(player)
removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT)
player.pulseManager.run(object : Pulse(2){
override fun pulse(): Boolean {
addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640)

View file

@ -204,7 +204,7 @@ public final class HouseManager {
}
/**
* Leaves this house.
* Leaves this house through the portal.
* @param player The player leaving.
*/
public static void leave(Player player) {
@ -215,7 +215,6 @@ public final class HouseManager {
if (house.isInHouse(player)) {
player.animate(Animation.RESET);
player.getProperties().setTeleportLocation(house.location.getExitLocation());
removeAttribute(player, "original-loc");
}
}

View file

@ -3,11 +3,12 @@ package content.global.skill.construction;
import core.game.node.entity.Entity;
import core.game.node.entity.player.Player;
import core.game.world.map.build.DynamicRegion;
import core.game.world.map.zone.MapZone;
import core.game.world.map.zone.ZoneRestriction;
import core.game.world.map.RegionManager;
import core.game.world.map.Region;
import core.game.system.task.Pulse;
import core.game.world.map.zone.ZoneRestriction;
import static core.api.ContentAPIKt.*;
@ -90,6 +91,7 @@ public final class HouseZone extends MapZone {
public boolean leave(Entity e, boolean logout) {
if (e instanceof Player) {
Player p = (Player) e;
// The below tears down the house if the owner was the one who left
if (house == p.getHouseManager()) {
house.expelGuests(p);
int toRemove = previousRegion;
@ -110,7 +112,11 @@ public final class HouseZone extends MapZone {
}
});
}
// Clear logout listener and original-loc (if appropriate)
clearLogoutListener(p, "houselogout");
if (!getAttribute(p, "kidnapped-by-random", false)) {
removeAttribute(p, "/save:original-loc");
}
return true;
}
return true;

View file

@ -465,17 +465,20 @@ public class Player extends Entity {
// Update wealth tracking
checkForWealthUpdate(false);
// Check if the player is on the map
// This is only a sanity check to detect improper usage of the 'original-loc' attribute, hence only do this work if the attribute is set
// Check if the player is on the map, runs only every 6 seconds for performance reasons.
// This is only a sanity check to detect improper usage of the 'original-loc' attribute, hence only do this work if the attribute is set.
// Only runs when the player is not movement/interaction-locked, so that original-loc does not get wiped e.g. in the middle of the player teleporting to their POH.
if (GameWorld.getTicks() % 10 == 0 && !getLocks().isMovementLocked() && !getLocks().isInteractionLocked()) {
if (ContentAPIKt.getAttribute(this, "/save:original-loc", null) != null) {
int rid = location.getRegionId();
Region r = RegionManager.forId(rid);
if (!(r instanceof DynamicRegion) && !getZoneMonitor().isRestricted(ZoneRestriction.OFF_MAP)) {
log(this.getClass(), Log.ERR, "Player " + getUsername() + " has the original-loc attribute set but isn't actually off-map! This indicates a bug in the code that set that attribute. The original-loc is: " + getAttribute("/save:original-loc") + ", good luck debugging!");
log(this.getClass(), Log.ERR, "Player " + getUsername() + " has the original-loc attribute set but isn't actually off-map! This indicates a bug in the code that set that attribute. The original-loc is " + getAttribute("/save:original-loc") + ", the current region is " + rid + ". Good luck debugging!");
ContentAPIKt.removeAttribute(this, "original-loc");
}
}
}
}
private void checkForWealthUpdate(boolean force) {
if (isArtificial()) return;