From f1131b7d00c35273ba74ba75e02587ac908e9769 Mon Sep 17 00:00:00 2001 From: Player Name Date: Sun, 16 Feb 2025 07:00:13 +0000 Subject: [PATCH] Made random event teleports more robust, fixing edge cases --- .../main/content/global/ame/KidnapHelper.kt | 23 +++++++++++ .../main/content/global/ame/RandomEvents.kt | 4 +- .../ame/events/drilldemon/DrillDemonUtils.kt | 20 +++------- ...rgentDamienNPC.kt => SergeantDamienNPC.kt} | 4 +- .../ame/events/evilbob/EvilBobListeners.kt | 6 +-- .../global/ame/events/evilbob/EvilBobUtils.kt | 14 +++---- .../ame/events/freakyforester/FreakUtils.kt | 15 +++---- .../global/ame/events/maze/MazeInterface.kt | 6 +-- .../content/global/ame/events/maze/MazeNPC.kt | 7 ++-- .../ame/events/pillory/PilloryInterface.kt | 39 +++++++++---------- .../global/ame/events/pillory/PilloryNPC.kt | 8 ++-- .../quizmaster/QuizMasterDialogueFile.kt | 9 ++--- .../ame/events/quizmaster/QuizMasterNPC.kt | 8 ++-- .../surpriseexam/SupriseExamListeners.kt | 5 ++- .../events/surpriseexam/SurpriseExamUtils.kt | 25 ++++-------- .../skill/construction/HouseManager.java | 3 +- .../global/skill/construction/HouseZone.java | 8 +++- .../core/game/node/entity/player/Player.java | 19 +++++---- 18 files changed, 109 insertions(+), 114 deletions(-) create mode 100644 Server/src/main/content/global/ame/KidnapHelper.kt rename Server/src/main/content/global/ame/events/drilldemon/{SeargentDamienNPC.kt => SergeantDamienNPC.kt} (89%) diff --git a/Server/src/main/content/global/ame/KidnapHelper.kt b/Server/src/main/content/global/ame/KidnapHelper.kt new file mode 100644 index 000000000..2efc90f2d --- /dev/null +++ b/Server/src/main/content/global/ame/KidnapHelper.kt @@ -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") +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/RandomEvents.kt b/Server/src/main/content/global/ame/RandomEvents.kt index 9addefbe4..49bac5151 100644 --- a/Server/src/main/content/global/ame/RandomEvents.kt +++ b/Server/src/main/content/global/ame/RandomEvents.kt @@ -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()), diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt index 84cba68d6..a6638fecb 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt @@ -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) diff --git a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt similarity index 89% rename from Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt rename to Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt index f767b0554..af4e8fe3c 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt @@ -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 -> { diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt index b40c42bf6..f2a3e9134 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt @@ -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) diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt index 55ef8c2db..d70eab940 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt @@ -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) diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt index e777e3c05..e247bfeb1 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt @@ -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) diff --git a/Server/src/main/content/global/ame/events/maze/MazeInterface.kt b/Server/src/main/content/global/ame/events/maze/MazeInterface.kt index 8a317e57a..108d456ca 100644 --- a/Server/src/main/content/global/ame/events/maze/MazeInterface.kt +++ b/Server/src/main/content/global/ame/events/maze/MazeInterface.kt @@ -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, 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, 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) diff --git a/Server/src/main/content/global/ame/events/maze/MazeNPC.kt b/Server/src/main/content/global/ame/events/maze/MazeNPC.kt index 973f8423d..e4befe00e 100644 --- a/Server/src/main/content/global/ame/events/maze/MazeNPC.kt +++ b/Server/src/main/content/global/ame/events/maze/MazeNPC.kt @@ -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(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) diff --git a/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt b/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt index 22ff21957..f48fc76f4 100644 --- a/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt +++ b/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt @@ -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) } } diff --git a/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt b/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt index 055c684dd..f833d9ce2 100644 --- a/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt +++ b/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt @@ -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(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) diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt index aba73764c..3796fac17 100644 --- a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt @@ -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() } diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt index d1c6f12e9..26407a1dc 100644 --- a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt @@ -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(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) diff --git a/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt b/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt index 3fbe1cdc7..6d8ad6b4f 100644 --- a/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt @@ -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) diff --git a/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt b/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt index 1c729efc0..01a722343 100644 --- a/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt +++ b/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt @@ -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) diff --git a/Server/src/main/content/global/skill/construction/HouseManager.java b/Server/src/main/content/global/skill/construction/HouseManager.java index 372b976d2..01a37f377 100644 --- a/Server/src/main/content/global/skill/construction/HouseManager.java +++ b/Server/src/main/content/global/skill/construction/HouseManager.java @@ -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"); } } diff --git a/Server/src/main/content/global/skill/construction/HouseZone.java b/Server/src/main/content/global/skill/construction/HouseZone.java index 860b38e03..ccd426c19 100644 --- a/Server/src/main/content/global/skill/construction/HouseZone.java +++ b/Server/src/main/content/global/skill/construction/HouseZone.java @@ -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; diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index 70f944c39..dfced34d2 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -465,14 +465,17 @@ 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 - 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!"); - ContentAPIKt.removeAttribute(this, "original-loc"); + // 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") + ", the current region is " + rid + ". Good luck debugging!"); + ContentAPIKt.removeAttribute(this, "original-loc"); + } } } }