Improved random event kidnapping logic

Rewrote home teleport
Corrected shades and zombies to only multiply xp by 1/16 if they were random events
Unified non-hostile random event chat mechanics
Fixed random events repeating their opening message and/or saying their timeout message prematurely
Genie will now authentically address female players as 'Mistress'
Fixed hostile randoms wrongly teleporting the player after 3 minutes
Made quizmaster dialogues unclosable and added a hook to restart them if you lose it
Made the pillory dialog unclosable
Implemented rock golem switch between ranged and melee
Replaced sandwich lady chat lines with authentic quotes
Added authentic dialogue for interacting with another player's sandwich lady
Added a teleport block for the surprise exam random event
This commit is contained in:
Player Name 2025-11-27 11:44:43 +00:00 committed by Ryan
parent feb2b10247
commit 3d5cbd90ed
30 changed files with 381 additions and 470 deletions

View file

@ -2,22 +2,57 @@ package content.global.ame
import core.ServerConstants
import core.api.*
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager.TeleportType
import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Sounds
fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) {
setAttribute(player, "kidnapped-by-random", true) //only used in POH code when you leave the hut, so does not need /save. Do not rely on this outside of its intended POH use case.
if (getAttribute(player, "/save:original-loc", null) == null) {
fun kidnapPlayer(npc: NPC, player: Player, dest: Location, playerLine: String? = null, callback: (player: Player, npc: NPC) -> Unit) {
val lockDuration = if (playerLine != null) 4 else 6
lock(player, lockDuration)
queueScript(player, 1, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
if (playerLine != null) {
sendChat(player, playerLine)
return@queueScript delayScript(player, 2)
}
return@queueScript delayScript(player, 0)
}
1 -> {
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
2 -> {
setAttribute(player, "kidnapped-by-random", true)
if (getAttribute<Location?>(player, "/save:original-loc", null) == null) {
setAttribute(player, "/save:original-loc", player.location)
}
teleport(player, loc, type)
teleport(player, dest, TeleportType.INSTANT)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player, 8941)
resetAnimator(player)
callback(player, npc)
return@queueScript delayScript(player, 2)
}
3 -> {
removeAttribute(player, "kidnapped-by-random") //this is not needed at this point anymore and will reenable the original-loc sanity check tick action
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}
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)
val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION)
teleport(player, destination!!)
unlock(player)
removeAttributes(player, "/save:original-loc", "kidnapped-by-random")
}

View file

@ -4,6 +4,7 @@ import content.global.ame.events.surpriseexam.MysteriousOldManNPC
import core.api.playGlobalAudio
import core.api.poofClear
import core.api.sendMessage
import core.api.setAttribute
import core.api.utils.WeightBasedTable
import core.game.interaction.MovementPulse
import core.game.node.entity.Entity
@ -19,8 +20,10 @@ import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Graphics
import core.integrations.discord.Discord
import core.tools.RandomFunction
import core.tools.secondsToTicks
import core.tools.ticksToCycles
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
import kotlin.math.ceil
import kotlin.math.min
@ -43,6 +46,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
event.loot = loot
event.player = player
event.spawnLocation = RegionManager.getSpawnLocation(player, this)
setAttribute(event, "spawned-by-ame", true)
return event
}
@ -101,7 +105,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
}
open fun onTimeUp() {
noteAndTeleport()
terminate()
}
@ -144,4 +147,23 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1
return ids[index]
}
fun sayLine(npc: NPC, phrases: Array<String>, hasOpeningPhrase: Boolean, hasOverTimePhrase: Boolean) {
if (!timerPaused && (ticksLeft % 20 == 0 || ticksLeft <= 2)) { //unless the Certer interface is up, speak every 20 ticks, or in the 2nd-to-last tick before attack/note-&-teleport
var playDwarfWhistle = true
if (ticksLeft == secondsToTicks(180) && hasOpeningPhrase) {
sendChat(phrases[0])
} else if (ticksLeft <= 2 && hasOverTimePhrase) {
sendChat(phrases[phrases.size - 1])
playDwarfWhistle = false
} else {
val start = if (hasOpeningPhrase) 0 else 1
val end = if (hasOverTimePhrase) phrases.size - 2 else phrases.size - 1
sendChat(phrases[RandomFunction.random(start, end + 1)])
}
if (npc.id == NPCs.DRUNKEN_DWARF_956 && playDwarfWhistle) {
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
}
}
}
}

View file

@ -97,5 +97,4 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
}
}
}
}

View file

@ -1,5 +1,6 @@
package content.global.ame.events
import core.api.getAttribute
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
@ -8,12 +9,12 @@ import org.rs09.consts.NPCs
class HostileRandomEventBehavior : NPCBehavior(
NPCs.EVIL_CHICKEN_2463, NPCs.EVIL_CHICKEN_2464, NPCs.EVIL_CHICKEN_2465, NPCs.EVIL_CHICKEN_2466, NPCs.EVIL_CHICKEN_2467, NPCs.EVIL_CHICKEN_2468,
NPCs.RIVER_TROLL_391, NPCs.RIVER_TROLL_392, NPCs.RIVER_TROLL_393, NPCs.RIVER_TROLL_394, NPCs.RIVER_TROLL_395, NPCs.RIVER_TROLL_396,
NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418,
NPCs.SHADE_425, NPCs.SHADE_426, NPCs.SHADE_427, NPCs.SHADE_428, NPCs.SHADE_429, NPCs.SHADE_430, NPCs.SHADE_431,
NPCs.TREE_SPIRIT_438, NPCs.TREE_SPIRIT_439, NPCs.TREE_SPIRIT_440, NPCs.TREE_SPIRIT_441, NPCs.TREE_SPIRIT_442, NPCs.TREE_SPIRIT_443,
NPCs.ZOMBIE_419, NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424
) {
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
return super.getXpMultiplier(self, attacker) / 16.0
val xprate = super.getXpMultiplier(self, attacker)
return if (getAttribute(self, "spawned-by-ame", false)) xprate / 16.0 else xprate
}
}

View file

@ -4,42 +4,19 @@ 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.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
/** "::revent -p player_name -e candlelight" **/
class PiousPeteNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PRIEST_3206) {
override fun init() {
super.init()
// Supposed to be "I'm sorry to drag you away from your tasks, but I need a little help with something." but it's too goddamn long.
sendChat("${player.username.capitalize()}! I need a little help with something.")
sendChat("${player.username}! I need a little help with something.")
face(player)
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
kidnapPlayer(this, player, Location(1972, 5002, 0)) { player, _ ->
CandlelightInterface.initCandlelight(player)
kidnapPlayer(player, Location(1972, 5002, 0), TeleportManager.TeleportType.INSTANT)
// AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
openDialogue(player, PiousPeteStartingDialogueFile(), NPC(NPCs.PIOUS_PETE_3207))
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}

View file

@ -2,29 +2,19 @@ package content.global.ame.events.certer
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.emote.Emotes
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC
import core.api.animate
import core.api.lock
import core.api.utils.WeightBasedTable
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
lateinit var pName: String
lateinit var phrases: Array<String>
override fun tick() {
// Don't speak if we have the interface opened
if (!timerPaused) {
// Over allotted time phrase
if (ticksLeft <= 2) {
player.lock(2)
sendChat(phrases[4])
// Say a phrase every 20 ticks starting at 280 ticks
// as to not interfere with the init chat phrase
} else if (ticksLeft <= 280 && ticksLeft % 20 == 0) {
sendChat(phrases[RandomFunction.random(1, 3)])
}
sayLine(this, phrases, true, true)
if (ticksLeft == 2) {
lock(player, 2)
}
super.tick()
}
@ -36,15 +26,20 @@ class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NP
override fun init() {
super.init()
pName = player.username.capitalize()
phrases = arrayOf("Greetings $pName, I need your help.",
"ehem... Hello $pName, please talk to me!",
"Hello, are you there $pName?",
"It's really rude to ignore someone, $pName!",
"No-one ignores me!")
phrases = arrayOf(
"Greetings ${player.username}, I need your help.",
"ehem... Hello ${player.username}, please talk to me!",
"Hello, are you there ${player.username}?",
"It's really rude to ignore someone, ${player.username}!",
"No-one ignores me!"
)
player.setAttribute("random:pause", false)
player.setAttribute("certer:reward", false)
sendChat(phrases[0])
animate(this, Emotes.BOW.animation, true)
}
override fun onTimeUp() {
noteAndTeleport()
terminate()
}
}

View file

@ -1,12 +1,9 @@
package content.global.ame.events.drilldemon
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
import org.rs09.consts.Items
@ -24,13 +21,6 @@ object DrillDemonUtils {
val DD_AREA = ZoneBorders(3158, 4817, 3168, 4823)
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT)
player.interfaceManager.closeDefaultTabs()
setComponentVisibility(player, 548, 69, true)
setComponentVisibility(player, 746, 12, true)
}
fun changeSignsAndAssignTask(player: Player) {
setVarp(player, DD_SIGN_VARP, 0)
val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList()
@ -94,6 +84,5 @@ object DrillDemonUtils {
}
return@queueScript stopExecuting(player)
}
}
}

View file

@ -3,32 +3,22 @@ package content.global.ame.events.drilldemon
import core.game.node.entity.npc.NPC
import org.rs09.consts.NPCs
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.system.timer.impl.AntiMacro
import core.tools.secondsToTicks
import core.game.world.map.Location
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
override fun init() {
super.init()
sendChat(player.username+ "! Drop and give me 20!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, secondsToTicks(30))
DrillDemonUtils.teleport(player)
AntiMacro.terminateEventNpc(player)
return@queueScript delayScript(player, 2)
}
1 -> {
sendChat("${player.username}! Drop and give me 20!")
face(player)
kidnapPlayer(this, player, Location(3163, 4819, 0)) { player, _ ->
player.interfaceManager.closeDefaultTabs()
setComponentVisibility(player, 548, 69, true)
setComponentVisibility(player, 746, 12, true)
openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}

View file

@ -9,36 +9,28 @@ import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.DRUNKEN_DWARF_956) {
private val phrases = arrayOf("Oi, are you der @name!","Dunt ignore your matey!","Aww comeon, talk to ikle me @name!")
private var attackPhrase = false
lateinit var phrases: Array<String>
private var attackDelay = 0
private var lastPhraseTime = 0
private fun sendPhrases() {
if (getWorldTicks() > lastPhraseTime + 5) {
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
sendChat(this, phrases.random().replace("@name",player.username.capitalize()))
this.face(player)
lastPhraseTime = getWorldTicks()
}
}
override fun init() {
super.init()
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
sendChat(this, "'Ello der ${player.username.capitalize()}! *hic*")
phrases = arrayOf(
"'Ello der ${player.username}! *hic*",
"Oi, are you der ${player.username}!",
"Dunt ignore your matey!",
"Aww comeon, talk to ikle me ${player.username}!",
"I hates you, ${player.username}!"
)
}
override fun tick() {
if (RandomFunction.roll(20) && !attackPhrase)
sendPhrases()
sayLine(this, phrases, true, true)
if (ticksLeft <= 10) {
ticksLeft = 10
if (!attackPhrase)
sendChat("I hates you, ${player.username.capitalize()}!").also { attackPhrase = true }
if (attackDelay <= getWorldTicks())
if (attackDelay <= getWorldTicks()) {
this.attack(player)
}
}
super.tick()
}
@ -47,4 +39,10 @@ class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEvent
this.pulseManager.clear()
openDialogue(player, DrunkenDwarfDialogue(), this.asNpc())
}
override fun onTimeUp() {
if (attackDelay <= getWorldTicks()) {
this.attack(player)
}
}
}

View file

@ -1,40 +1,22 @@
package content.global.ame.events.evilbob
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.system.timer.impl.AntiMacro
import core.game.world.map.Location
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.EVIL_BOB_2478) {
override fun init() {
super.init()
sendChat("meow")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendChat(player, "No... what? Nooooooooooooo!")
animate(player, EvilBobUtils.teleAnim)
player.graphics(EvilBobUtils.telegfx)
playAudio(player, Sounds.TELEPORT_ALL_200)
face(player)
kidnapPlayer(this, player, Location(3419, 4776, 0), "No... what? Nooooooooooooo!") { player, _ ->
EvilBobUtils.giveEventFishingSpot(player)
return@queueScript delayScript(player, 3)
}
1 -> {
sendMessage(player, "Welcome to Scape2009.")
EvilBobUtils.teleport(player)
resetAnimator(player)
openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479)
AntiMacro.terminateEventNpc(player)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}

View file

@ -1,12 +1,8 @@
package content.global.ame.events.evilbob
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
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
@ -53,10 +49,6 @@ object EvilBobUtils {
}
}
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player) {
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
removeAll(player, Items.FISHLIKE_THING_6202)

View file

@ -1,13 +1,10 @@
package content.global.ame.events.freakyforester
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
@ -28,10 +25,6 @@ object FreakUtils{
player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc)
}
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player) {
returnPlayer(player)
removeAttributes(player, freakTask, freakComplete, pheasantKilled)

View file

@ -1,39 +1,21 @@
package content.global.ame.events.freakyforester
import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.*
import org.rs09.consts.NPCs
import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.system.timer.impl.AntiMacro
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Sounds
import core.game.world.map.Location
class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) {
override fun init() {
super.init()
sendChat("Ah, ${player.username}, just the person I need!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(308, 100, 50), player.location)
animate(player,714)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
FreakUtils.teleport(player)
face(player)
kidnapPlayer(this, player, Location(2599, 4777, 0)) { player, _ ->
FreakUtils.giveFreakTask(player)
AntiMacro.terminateEventNpc(player)
openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc)
resetAnimator(player)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}

View file

@ -4,27 +4,40 @@ import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC
import core.api.lock
import core.api.playAudio
import core.api.utils.WeightBasedTable
import org.rs09.consts.Sounds
class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) {
val phrases = arrayOf("Greetings, @name!","Ehem... Master @name?","Are you there, Master @name?","No one ignores me!")
lateinit var phrases: Array<String>
override fun tick() {
if(RandomFunction.random(1,15) == 5){
sendChat(phrases.random().replace("@name",player.username.capitalize()))
sayLine(this, phrases, true, true)
if (ticksLeft == 2) {
lock(player, 2)
}
super.tick()
}
override fun init() {
super.init()
val honorific = if (player.isMale) "Master" else "Mistress"
phrases = arrayOf(
"Greetings, ${player.username}!",
"Ehem... $honorific ${player.username}?",
"Are you there, $honorific ${player.username}?",
"No one ignores me!"
)
playAudio(player, Sounds.GENIE_APPEAR_2301)
sendChat(phrases.random().replace("@name",player.username.capitalize()))
}
override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(GenieDialogue(),npc)
}
override fun onTimeUp() {
noteAndTeleport()
terminate()
}
}

View file

@ -4,33 +4,14 @@ 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
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
override fun init() {
super.init()
sendChat("Aha, you'll do ${player.username}!")
face(player)
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
MazeInterface.initMaze(player)
// Note: This event is NOT instanced:
// Sources:
// https://youtu.be/2gpzn9oNdy0 (2007)
@ -39,19 +20,13 @@ 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)
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)
kidnapPlayer(this, player, MazeInterface.STARTING_POINTS.random()) { player, _ ->
MazeInterface.initMaze(player)
removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}
override fun talkTo(npc: NPC) {
// Do nothing.
sendMessage(player, "He isn't interested in talking to you.")
}
}

View file

@ -4,47 +4,22 @@ 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.component.Component.setUnclosable
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
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
// "::revent [-p] <lt>player name<gt> [-e <lt>event name<gt>]"
class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PILLORY_GUARD_2791) {
override fun init() {
super.init()
sendChat("${player.username}, you're under arrest!")
face(player)
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
kidnapPlayer(this, player, PilloryInterface.LOCATIONS.random()) { player, _ ->
PilloryInterface.initPillory(player)
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)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
setUnclosable(player, player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from."))
}
}
override fun talkTo(npc: NPC) {
//player.dialogueInterpreter.open(FreakyForesterDialogue(),npc)
sendMessage(player, "He isn't interested in talking to you.")
}
}

View file

@ -5,15 +5,17 @@ import core.ServerConstants
import core.api.*
import core.api.utils.WeightBasedTable
import core.api.utils.WeightedItem
import core.game.dialogue.DialogueFile
import core.game.component.Component
import core.game.dialogue.DialogueLabeller
import core.game.dialogue.DialogueOption
import core.game.dialogue.FacialExpression
import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player
import core.tools.END_DIALOGUE
import org.rs09.consts.Components
import org.rs09.consts.Items
import org.rs09.consts.NPCs
class QuizMasterDialogueFile : DialogueFile() {
class QuizMasterDialogueFile : DialogueLabeller() {
companion object {
const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191
const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct"
@ -74,56 +76,77 @@ class QuizMasterDialogueFile : DialogueFile() {
}
override fun handle(componentID: Int, buttonID: Int) {
when (stage) {
0 -> npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>").also { stage++ }
1 -> player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...").also { stage++ }
2 -> npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!").also { stage++ }
3 -> {
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player!!))
player!!.interfaceManager.openChatbox(QUIZMASTER_INTERFACE)
stage++
override fun addConversation() {
assignToIds(NPCs.QUIZ_MASTER_2477)
afterClose { player ->
loadLabel(player, "question")
}
4-> {
if (buttonID == getAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) {
npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>", unclosable = true)
player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...", unclosable = true)
npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!", unclosable = true)
goto("question")
label("question")
manual(unclosable = true) { player, _ ->
setAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player))
val comp = Component(QUIZMASTER_INTERFACE)
player.interfaceManager.openChatbox(comp)
return@manual comp
}
exec { player, _ ->
if (buttonID == getAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) {
// Correct Answer
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1)
if (getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) {
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!")
stage = 5
setAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1)
if (getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) {
goto("winner")
} else {
npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!")
stage = 3
goto("right")
}
} else {
// Wrong Answer
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!")
stage = 3
goto("wrong")
}
}
// Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas.
5 -> options("1000 Coins", "Random Item").also { stage++ }
6 -> {
resetAnimator(player!!)
returnPlayer(player!!)
when (buttonID) {
1 -> {
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
addItemOrDrop(player!!, Items.COINS_995, 1000)
return@queueScript stopExecuting(player!!)
label("right")
npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!", unclosable = true)
goto("question")
label("wrong")
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!", unclosable = true)
goto("question")
label("winner")
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!", unclosable = true)
options(
DialogueOption("money", "1000 Coins", skipPlayer = true),
DialogueOption("item", "Random Item", skipPlayer = true)
)
label("money")
exec { player, _ ->
queueScript(player, 0, QueueStrength.SOFT) { _ ->
addItemOrDrop(player, Items.COINS_995, 1000)
return@queueScript stopExecuting(player)
}
}
2 -> {
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
addItemOrDrop(player!!, tableRoll.roll()[0].id)
return@queueScript stopExecuting(player!!)
goto("cleanup")
label("item")
exec { player, _ ->
queueScript(player, 0, QueueStrength.SOFT) { _ ->
addItemOrDrop(player, tableRoll.roll()[0].id)
return@queueScript stopExecuting(player)
}
}
goto("cleanup")
label("cleanup")
exec { player, _ ->
resetAnimator(player)
returnPlayer(player)
removeAttributes(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
}
removeAttributes(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
stage = END_DIALOGUE
end()
}
}
goto("nowhere")
}
}

View file

@ -4,14 +4,9 @@ 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
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
/**
* Quiz Master NPC:
@ -27,35 +22,14 @@ class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable?
override fun init() {
super.init()
sendChat("Hey ${player.username}! It's your lucky day!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
kidnapPlayer(player, Location(1952, 4764, 1), TeleportManager.TeleportType.INSTANT)
face(player)
kidnapPlayer(this, player, Location(1952, 4764, 0)) { player, _ ->
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
return@queueScript delayScript(player, 6)
}
2 -> {
face(player, Location(1952, 4768, 1))
animate(player,2378)
// This is not needed as when you enter the QuizMasterBorders, it should fire off the dialogue
// openDialogue(player, QuizMasterDialogueFile(), this.asNpc())
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
// Quiz dialogue gets opened automatically on zone entry.
}
}

View file

@ -0,0 +1,25 @@
package content.global.ame.events.rockgolem
import core.game.node.entity.Entity
import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.combat.CombatSwingHandler
import core.game.node.entity.combat.MultiSwingHandler
import core.game.node.entity.combat.equipment.SwitchAttack
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
import org.rs09.consts.NPCs
class RockGolemBehavior() : NPCBehavior(
NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418
) {
val rangeHandler = SwitchAttack(CombatStyle.RANGE)
val meleeHandler = SwitchAttack(CombatStyle.MELEE)
val combatHandler = MultiSwingHandler(rangeHandler, meleeHandler)
override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler {
return combatHandler
}
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
return super.getXpMultiplier(self, attacker) / 16.0
}
}

View file

@ -5,24 +5,41 @@ import core.tools.RandomFunction
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC
import core.api.lock
import core.api.utils.WeightBasedTable
class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) {
val phrases = arrayOf("Hello, @name, can you hear me?","Sandwiches, @name!","Are you ignoring me, @name??","Yoohoo! Sandwiches, @name!","Hello, @name?", "Come get your sandwiches, @name!", "How could you ignore me like this, @name?!", "Do you even want your sandwiches, @name?")
lateinit var phrases: Array<String>
var assigned_item = 0
val items = arrayOf(Items.BAGUETTE_6961, Items.TRIANGLE_SANDWICH_6962, Items.SQUARE_SANDWICH_6965, Items.ROLL_6963, Items.MEAT_PIE_2327, Items.KEBAB_1971, Items.CHOCOLATE_BAR_1973)
override fun tick() {
if(RandomFunction.random(1,15) == 5){
sendChat(phrases.random().replace("@name",player.username.capitalize()))
sayLine(this, phrases, true, true)
if (ticksLeft == 2) {
lock(player, 2)
}
super.tick()
}
override fun init() {
super.init()
phrases = arrayOf(
// https://www.youtube.com/watch?v=ek8r3ZS929E
// She always starts with "Sandwiches, ${player.username}!" but she ALSO picks that at random, hence duplicate it with hasOpeningPhrase = true
"Sandwiches, ${player.username}!",
"Sandwiches, ${player.username}!",
"Come on ${player.username}, I made these specially!!",
"All types of sandwiches, ${player.username}.",
"Did you hear me ${player.username}?",
"You think I made these just for fun?!!?",
"How could you ignore me like this, ${player.username}?!" //unknown if authentic but it was already here
)
assignItem()
sendChat(phrases.random().replace("@name",player.username.capitalize()))
}
override fun onTimeUp() {
noteAndTeleport()
terminate()
}
fun assignItem(){

View file

@ -5,32 +5,16 @@ import content.global.ame.kidnapPlayer
import core.api.*
import org.rs09.consts.NPCs
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.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Sounds
class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
override fun init() {
super.init()
sendChat("Surprise exam, ${player.username}!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
kidnapPlayer(player, Location(1886, 5025, 0), TeleportManager.TeleportType.INSTANT)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
face(player)
kidnapPlayer(this, player, Location(1886, 5025, 0)) { _, _ ->
/* nothing needed */
}
}

View file

@ -2,7 +2,6 @@ package content.global.ame.events.surpriseexam
import core.game.component.Component
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.map.Location
import org.rs09.consts.Items
import org.rs09.consts.NPCs
@ -66,6 +65,6 @@ class SupriseExamListeners : InteractionListener, MapArea {
}
override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
}
}

View file

@ -1,15 +1,12 @@
package content.global.ame.events.surpriseexam
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.system.task.Pulse
import core.game.world.map.Location
import org.rs09.consts.Components
import org.rs09.consts.Items
import core.game.node.entity.player.link.TeleportManager
object SurpriseExamUtils {
val SE_KEY_INDEX = "supexam:index"

View file

@ -12,6 +12,7 @@ import core.game.system.timer.impl.AntiMacro
import core.game.worldevents.holiday.HolidayRandomEventNPC
import core.game.worldevents.holiday.HolidayRandomEvents
import core.game.worldevents.holiday.HolidayRandoms
import org.rs09.consts.NPCs
/**
* Handles the NPC talk-to option.
@ -37,11 +38,18 @@ class NPCTalkListener : InteractionListener {
val npc = node.asNpc()
if(RandomEvents.randomIDs.contains(node.id)){
if(AntiMacro.getEventNpc(player) == null || AntiMacro.getEventNpc(player) != node.asNpc() || AntiMacro.getEventNpc(player)?.finalized == true) {
player.sendMessage("They aren't interested in talking to you.")
// Why the fuck is this here of all places? Now look at what you've made me do:
if (npc.id == NPCs.SANDWICH_LADY_3117) {
// https://www.youtube.com/watch?v=ek8r3ZS929E
player.dialogueInterpreter.sendDialogue("The sandwich lady doesn't seem interested in selling you any", "refreshments.")
} else {
sendMessage(player, "They aren't interested in talking to you.")
}
} else {
AntiMacro.getEventNpc(player)?.talkTo(node.asNpc())
}
return@on true
//TODO bring sanity here
}
if (HolidayRandomEvents.holidayRandomIDs.contains(node.id) && node is HolidayRandomEventNPC) {
if(HolidayRandoms.getEventNpc(player) == null || HolidayRandoms.getEventNpc(player) != node.asNpc() || HolidayRandoms.getEventNpc(player)?.finalized == true) {

View file

@ -0,0 +1,46 @@
package content.global.skill.magic
import core.api.delayScript
import core.api.playGlobalAudio
import core.api.queueScript
import core.api.sendMessage
import core.api.stopExecuting
import core.game.event.TeleportEvent
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.ZoneRestriction
val HOME_ANIMATIONS = arrayOf(1722, 1723, 1724, 1725, 2798, 2799, 2800, 3195, 4643, 4645, 4646, 4847, 4848, 4849, 4850, 4851, 4852, 65535)
val HOME_GRAPHICS = arrayOf(775, 800, 801, 802, 803, 804, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 65535)
fun getAudio(count: Int): Int {
return when (count) {
0 -> 193
4 -> 194
11 -> 195
else -> -1
}
}
fun homeTeleport(player: Player, dest: Location) {
if (player.timers.getTimer("teleblock") != null) {
sendMessage(player, "A magical force prevents you from teleporting.")
return
}
if (player.locks.isTeleportLocked || player.zoneMonitor.isRestricted(ZoneRestriction.TELEPORT)) {
sendMessage(player, "A magical force has stopped you from teleporting.")
return
}
queueScript(player, 0, QueueStrength.WEAK) { stage ->
if (stage == 18) {
player.properties.teleportLocation = dest
player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.SPELL, -1, dest))
return@queueScript stopExecuting(player)
}
playGlobalAudio(player.location, getAudio(stage))
player.packetDispatch.sendGraphic(HOME_GRAPHICS[stage])
player.packetDispatch.sendAnimation(HOME_ANIMATIONS[stage])
return@queueScript delayScript(player, 1)
}
}

View file

@ -1,5 +1,6 @@
package content.global.skill.magic.ancient;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
@ -13,8 +14,12 @@ import core.game.world.GameWorld;
import core.game.world.map.Location;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.Log;
import core.tools.RandomFunction;
import static content.global.skill.magic.HomeTeleportHelperKt.homeTeleport;
import static core.api.ContentAPIKt.log;
/**
* Represents the plugin used to handle all ancient teleporting plugins.
* @author 'Vexia
@ -55,7 +60,14 @@ public final class AncientTeleportPlugin extends MagicSpell {
entity.asPlayer().sendMessage("A magical force has stopped you from teleporting.");
return false;
}
if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), getSpellId() == 28 ? TeleportType.HOME : TeleportType.ANCIENT)) {
boolean isHomeTeleport = getSpellId() == 28;
if (isHomeTeleport) {
if (!entity.isPlayer()) {
log(this.getClass(), Log.ERR, "Why the fuck is a non-player entity trying to cast ancient-magick home teleport?!");
return false;
}
homeTeleport((Player) entity, Location.create(3087, 3495, 0));
} else if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), TeleportType.ANCIENT)) {
if (!super.meetsRequirements(entity, true, true)) {
entity.getTeleporter().getCurrentTeleport().stop();
return false;

View file

@ -5,6 +5,7 @@ import content.global.skill.farming.CompostBins
import content.global.skill.farming.CompostType
import content.global.skill.farming.FarmingPatch
import content.global.skill.magic.SpellListener
import content.global.skill.magic.homeTeleport
import content.global.skill.magic.spellconsts.Lunar
import core.api.*
import core.game.component.CloseEvent
@ -36,7 +37,7 @@ class LunarListeners : SpellListener("lunar"), Commands {
// Level 0
onCast(Lunar.HOME_TELEPORT, NONE) { player, _ ->
requires(player)
player.teleporter.send(Location.create(2100, 3914, 0),TeleportManager.TeleportType.HOME)
homeTeleport(player, Location.create(2100, 3914, 0))
setDelay(player,true)
}

View file

@ -4,10 +4,12 @@ import content.data.Quests
import content.global.skill.magic.SpellListener
import content.global.skill.magic.SpellUtils.hasRune
import content.global.skill.magic.TeleportMethod
import content.global.skill.magic.homeTeleport
import content.global.skill.magic.spellconsts.Modern
import content.global.skill.prayer.Bones
import content.global.skill.smithing.smelting.Bar
import content.global.skill.smithing.smelting.SmeltingPulse
import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners
import core.ServerConstants
import core.api.*
import core.game.event.ItemAlchemizationEvent
@ -23,7 +25,6 @@ import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.skill.Skills
import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
@ -39,7 +40,7 @@ class ModernListeners : SpellListener("modern"){
return@onCast
}
requires(player)
player.teleporter.send(ServerConstants.HOME_LOCATION,TeleportManager.TeleportType.HOME)
homeTeleport(player, ServerConstants.HOME_LOCATION ?: Location(3222, 3218, 0))
setDelay(player,true)
}

View file

@ -468,9 +468,8 @@ public class Player extends Entity {
// 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) {
// Does not run if the player is currently in the middle of a kidnap sequence (to avoid false positives while the teleport is taking place).
if (GameWorld.getTicks() % 10 == 0 && ContentAPIKt.getAttribute(this, "/save:original-loc", null) != null && !ContentAPIKt.getAttribute(this, "kidnapped-by-random", false)) {
int rid = location.getRegionId();
Region r = RegionManager.forId(rid);
if (!(r instanceof DynamicRegion) && !getZoneMonitor().isRestricted(ZoneRestriction.OFF_MAP)) {
@ -479,7 +478,6 @@ public class Player extends Entity {
}
}
}
}
private void checkForWealthUpdate(boolean force) {
if (isArtificial()) return;

View file

@ -26,16 +26,6 @@ public class TeleportManager {
*/
public static final int WILDY_TELEPORT = 1 << 16 | 8;
/**
* The animations used in the home teleport.
*/
private final static int[] HOME_ANIMATIONS = {1722, 1723, 1724, 1725, 2798, 2799, 2800, 3195, 4643, 4645, 4646, 4847, 4848, 4849, 4850, 4851, 4852, 65535};
/**
* The graphics used in the home teleport.
*/
private final static int[] HOME_GRAPHICS = {775, 800, 801, 802, 803, 804, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 65535};
/**
* The entity being handled.
*/
@ -62,7 +52,6 @@ public class TeleportManager {
*/
public TeleportManager(Entity entity) {
this.entity = entity;
lastTeleport = TeleportType.HOME.getPulse(entity, ServerConstants.HOME_LOCATION);
}
/**
@ -116,16 +105,11 @@ public class TeleportManager {
}
this.teleportType = teleportType;
entity.getWalkingQueue().reset();
lastTeleport = currentTeleport;
currentTeleport = type.getPulse(entity, location);
entity.getPulseManager().clear();
if (type == TeleportType.HOME) {
entity.getPulseManager().run(type.getPulse(entity, location));
} else {
entity.lock(12);
entity.getImpactHandler().setDisabledTicks(teleportType == -1 ? 5 : 12);
GameWorld.getPulser().submit(currentTeleport);
}
if (entity instanceof Player) {
((Player) entity).getInterfaceManager().close();
}
@ -143,22 +127,6 @@ public class TeleportManager {
}
}
/**
* Get the home teleport audio based on tick count.
* @param count
*/
private static int getAudio(int count){
switch(count){
case 0:
return 193;
case 4:
return 194;
case 11:
return 195;
}
return -1;
}
/**
* Gets the entity.
* @return the Entity
@ -167,14 +135,6 @@ public class TeleportManager {
return entity;
}
/**
* Gets the last teleport pulse.
* @return the Pulse
*/
public final Pulse getLastTeleport() {
return lastTeleport;
}
/**
* Gets the current teleport pulse.
* @return the Pulse
@ -183,7 +143,6 @@ public class TeleportManager {
return currentTeleport;
}
/**
* Represents a NodeType for Teleporter
* @author SonicForce41
@ -330,57 +289,6 @@ public class TeleportManager {
};
}
},
HOME(new TeleportSettings(4847, 4857, 800, 804)) {
@Override
public Pulse getPulse(final Entity entity, final Location location) {
return new TeleportPulse(entity) {
int count;
Player player;
@Override
public boolean pulse() {
switch (count) {
case 18:
player.getProperties().setTeleportLocation(location);
return true;
default:
playGlobalAudio(entity.getLocation(), getAudio(count));
player.getPacketDispatch().sendGraphic(HOME_GRAPHICS[count]);
player.getPacketDispatch().sendAnimation(HOME_ANIMATIONS[count]);
break;
}
count++;
return false;
}
@Override
public void start() {
player = ((Player) entity);
/*if (player.getSavedData().getGlobalData().getHomeTeleportDelay() > System.currentTimeMillis() && !player.isDonator()) {
long milliseconds = player.getSavedData().getGlobalData().getHomeTeleportDelay() - System.currentTimeMillis();
int minutes = (int) Math.round(milliseconds / 120000);
if (minutes > 15) {
player.getSavedData().getGlobalData().setHomeTeleportDelay(System.currentTimeMillis() + 1200000);
milliseconds = player.getSavedData().getGlobalData().getHomeTeleportDelay() - System.currentTimeMillis();
minutes = (int) Math.round(milliseconds / 120000);
}
if (minutes != 0) {
player.getPacketDispatch().sendMessage("You need to wait another " + minutes + " " + (minutes == 1 ? "minute" : "minutes") + " to cast this spell.");
stop();
return;
}
}*/
super.start();
}
@Override
public void stop() {
super.stop();
entity.getAnimator().forceAnimation(new Animation(-1));
player.graphics(new Graphics(-1));
}
};
}
},
OBELISK(new TeleportSettings(8939, 8941, 661, -1)) {
@Override
public Pulse getPulse(final Entity entity, final Location location) {