Merge branch 'prison-pete-random' into 'master'

Prison Pete Random

See merge request 2009scape/2009scape!1948
This commit is contained in:
Oven Bread 2025-11-30 07:52:37 +00:00
commit c9ce505c25
9 changed files with 473 additions and 6 deletions

View file

@ -4,6 +4,16 @@
<ObjectAction mode="add" id="2646" x="2447" y="3414" z="0" direction="e"/> <ObjectAction mode="add" id="2646" x="2447" y="3414" z="0" direction="e"/>
<ObjectAction mode="add" id="2646" x="2447" y="3421" z="0" direction="nw"/> <ObjectAction mode="add" id="2646" x="2447" y="3421" z="0" direction="nw"/>
<!-- Prison Pete Random -->
<ObjectAction mode="add" id="36788" x="2094" y="4465" z="0" type="10" direction="e" /> <!-- Bank Deposit -->
<ObjectAction mode="remove" id="11371" x="2085" y="4457" z="0"/> <!-- Green Portal -->
<ObjectAction mode="remove" id="10817" x="2083" y="4460" z="0"/> <!-- Lever -->
<ObjectAction mode="add" id="26191" x="2083" y="4460" z="0" type="10" direction="e" /> <!-- Lever -->
<ObjectAction mode="add" id="26184" x="2084" y="4459" z="0" type="0" direction="n"/> <!-- Window -->
<ObjectAction mode="add" id="26186" x="2085" y="4459" z="0" type="0" direction="n"/> <!-- Door -->
<ObjectAction mode="add" id="26188" x="2086" y="4459" z="0" type="0" direction="n"/> <!-- Door -->
<ObjectAction mode="add" id="26184" x="2087" y="4459" z="0" type="0" direction="n"/> <!-- Window -->
<ObjectAction mode="remove" id="37670" x="3292" y="3299" z="0"/> <ObjectAction mode="remove" id="37670" x="3292" y="3299" z="0"/>
<ObjectAction mode="add" id="37304" x="3292" y="3299" z="0"/> <ObjectAction mode="add" id="37304" x="3292" y="3299" z="0"/>

View file

@ -63812,6 +63812,15 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "6965" "id": "6965"
}, },
{
"examine": "A key to the prison.",
"grand_exchange_price": "0",
"durability": null,
"name": "Prison key",
"tradeable": "false",
"archery_ticket_price": "0",
"id": "6966"
},
{ {
"lendable": "true", "lendable": "true",
"examine": "Makes the wearer pretty intimidating.", "examine": "Makes the wearer pretty intimidating.",

View file

@ -30123,7 +30123,55 @@
"attack_level": "1" "attack_level": "1"
}, },
{ {
"examine": "Looks after farming tools.", "examine": "He wants to escape!",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Prison Pete",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "3118",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "It looks like an animal.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Balloon Animal",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "3119",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "It looks like an animal.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Balloon Animal",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "3120",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "It looks like an animal.",
"melee_animation": "0", "melee_animation": "0",
"range_animation": "0", "range_animation": "0",
"defence_animation": "0", "defence_animation": "0",
@ -30139,7 +30187,7 @@
"attack_level": "1" "attack_level": "1"
}, },
{ {
"examine": "I saw the witchdoctor", "examine": "It looks like an animal.",
"melee_animation": "0", "melee_animation": "0",
"range_animation": "0", "range_animation": "0",
"defence_animation": "0", "defence_animation": "0",

View file

@ -6675,6 +6675,26 @@
"npc_id": "3115", "npc_id": "3115",
"loc_data": "{2439,4444,0,1,3}-" "loc_data": "{2439,4444,0,1,3}-"
}, },
{
"npc_id": "3118",
"loc_data": "{2084,4460,0,0,1}-"
},
{
"npc_id": "3119",
"loc_data": "{2078,4462,0,1,0}-{2082,4466,0,1,0}-{2087,4470,0,1,0}-{2090,4464,0,1,0}-{2091,4461,0,1,0}-"
},
{
"npc_id": "3120",
"loc_data": "{2080,4464,0,1,0}-{2082,4472,0,1,0}-{2083,4462,0,1,0}-{2083,4463,0,1,0}-{2084,4468,0,1,0}-{2088,4464,0,1,0}-"
},
{
"npc_id": "3121",
"loc_data": "{2078,4466,0,1,0}-{2080,4470,0,1,0}-{2085,4463,0,1,0}-{2086,4467,0,1,0}-{2091,4470,0,1,0}-"
},
{
"npc_id": "3122",
"loc_data": "{2080,4467,0,1,0}-{2084,4465,0,1,0}-{2084,4470,0,1,0}-{2087,4462,0,1,0}-{2089,4466,0,1,0}-"
},
{ {
"npc_id": "3123", "npc_id": "3123",
"loc_data": "{3344,2827,0,1,5}-" "loc_data": "{3344,2827,0,1,5}-"

View file

@ -348,10 +348,6 @@
"regionId": "8260", "regionId": "8260",
"keys": "-357122149,-546918388,1659548066,2023267334" "keys": "-357122149,-546918388,1659548066,2023267334"
}, },
{
"regionId": "8261",
"keys": "14881828,-6662814,58238456,146761213"
},
{ {
"regionId": "8262", "regionId": "8262",
"keys": "937196178,1968517712,1697292009,-2036678778" "keys": "937196178,1968517712,1697292009,-2036678778"

View file

@ -12,6 +12,7 @@ import content.global.ame.events.maze.MazeNPC
import content.global.ame.events.genie.GenieNPC import content.global.ame.events.genie.GenieNPC
import content.global.ame.events.candlelight.PiousPeteNPC import content.global.ame.events.candlelight.PiousPeteNPC
import content.global.ame.events.pillory.PilloryNPC import content.global.ame.events.pillory.PilloryNPC
import content.global.ame.events.prisonpete.PrisonPeteNPC
import content.global.ame.events.rickturpentine.RickTurpentineNPC import content.global.ame.events.rickturpentine.RickTurpentineNPC
import content.global.ame.events.rivertroll.RiverTrollRENPC import content.global.ame.events.rivertroll.RiverTrollRENPC
import content.global.ame.events.rockgolem.RockGolemRENPC import content.global.ame.events.rockgolem.RockGolemRENPC
@ -55,6 +56,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
STRANGE_PLANT(npc = StrangePlantNPC()), STRANGE_PLANT(npc = StrangePlantNPC()),
SWARM(npc = SwarmNPC()), SWARM(npc = SwarmNPC()),
EVIL_BOB(npc = EvilBobNPC(), skillIds = intArrayOf(Skills.FISHING, Skills.MAGIC)), EVIL_BOB(npc = EvilBobNPC(), skillIds = intArrayOf(Skills.FISHING, Skills.MAGIC)),
PRISON_PETE(npc= PrisonPeteNPC()),
DRUNKEN_DWARF(npc = DrunkenDwarfNPC()), DRUNKEN_DWARF(npc = DrunkenDwarfNPC()),
RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot), RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot),
SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"), SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"),

View file

@ -0,0 +1,130 @@
package content.global.ame.events.prisonpete
import core.ServerConstants
import core.api.*
import core.game.dialogue.DialogueBuilder
import core.game.dialogue.DialogueBuilderFile
import core.game.dialogue.DialoguePlugin
import core.game.dialogue.FacialExpression
import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.Items
import org.rs09.consts.NPCs
@Initializable
class PrisonPeteDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, PrisonPeteDialogueFile(), npc)
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return PrisonPeteDialogue(player)
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.PRISON_PETE_3118)
}
}
class PrisonPeteDialogueFile : DialogueBuilderFile() {
override fun create(b: DialogueBuilder) {
b.onPredicate { _ -> true }
.branch {
player -> if (removeItem(player, Items.PRISON_KEY_6966)) { 1 } else { 0 } }
.let{ branch ->
branch.onValue(1)
.branch { player ->
if (getAttribute(player, PrisonPeteListeners.attributeTimesUnlocked, 0) >= 3) {
return@branch 1
}
return@branch 0
}
.let { branch2 ->
branch.onValue(1)
return@let branch2.onValue(0)
}
.npc(FacialExpression.FRIENDLY, "Ooh, thanks! I'll see if it's the right one...")
.branch { player ->
val poppedBalloon = getAttribute(player, PrisonPeteListeners.attributePoppedBalloonIndex, 0)
val correctBalloon = getAttribute(player, PrisonPeteListeners.attributeCurrentBalloonIndex, 0)
if (poppedBalloon != 0 && poppedBalloon == correctBalloon) {
setAttribute(player, PrisonPeteListeners.attributeTimesUnlocked, getAttribute(player, PrisonPeteListeners.attributeTimesUnlocked, 0) + 1)
if (getAttribute(player, PrisonPeteListeners.attributeTimesUnlocked, 0) >= 3) {
return@branch 2
}
setAttribute(player, PrisonPeteListeners.attributeCurrentBalloonIndex, 0)
return@branch 1
} else {
return@branch 0
}
}
.let { branch2 ->
branch2.onValue(2)
.npc(FacialExpression.FRIENDLY, "You did it, you got all the keys right!", "Thank you! You're my friend FOREVER!")
.playerl(FacialExpression.FRIENDLY, "Let's get out of here before the cat notices.")
.end()
branch2.onValue(1)
.npc(FacialExpression.FRIENDLY, "Hooray, you got the right one! Now pull the lever again", "and let's get the next lock unlocked.")
.end()
branch2.onValue(0)
.npc(FacialExpression.SAD, "Aww, that was the wrong key! You must have popped", "the wrong sort of animal. Try the big lever again; it'll", "tell you which animal to pop.")
.end()
}
branch.onValue(0)
.options("What would you like to say?").let { optionBuilder ->
optionBuilder.option("What is this place?")
.playerl(FacialExpression.THINKING,"What is this place?")
.npc(FacialExpression.SAD, "Don't you remember? This is ScapeRune's prison.", "Evil Bob caught you and brought you here.")
.player(FacialExpression.ANGRY, "What gives him the right to lock me up?", "I demand to see a lawyer! I know my rights!")
.npc(FacialExpression.SAD, "Evil Bob doesn't care about people's rights.", "He's cruel and utterly merciless. He's a cat.")
.player(FacialExpression.ANGRY, "How do I get out of here?", "I can't be held captive by a cat!")
.npc(FacialExpression.SAD, "Some of these balloon animals have keys in them, and if", "you pull the big lever it tells you which shape animal", "contains the correct key, but I can never find it.")
.npc(FacialExpression.SAD, "You need to pull the lever to find out which shape", "animal contains the key, then pop that sort of animal to", "get the key.")
.npc(FacialExpression.SAD, "Bring me any keys you get and", "I'll try them on the doors.")
// This is a future thing. Since this random event is in transition, I would follow other random events of this era and not have the 15 min countdown.
// .playerl(FacialExpression.THINKING,"What happens if I get it wrong?")
// .npc(FacialExpression.SAD, "You haven't get a life sentence, so they'll let you out in", "[15] minutes, but you should be able to escape much", "faster if you go pull that lever and pop the right balloon", "animals.")
// Note the [15] minutes part counts down, Prison pete would say "you have 9 minutes left" and yada
.end()
optionBuilder.option("How do I get out of here?")
.player(FacialExpression.ANGRY, "How do I get out of here?", "I can't be held captive by a cat!")
.npc(FacialExpression.SAD, "Some of these balloon animals have keys in them, and if", "you pull the big lever it tells you which shape animal", "contains the correct key, but I can never find it.")
.npc(FacialExpression.SAD, "You need to pull the lever to find out which shape", "animal contains the key, then pop that sort of animal to", "get the key.")
.npc(FacialExpression.SAD, "Bring me any keys you get and", "I'll try them on the doors.")
// This is a future thing. Since this random event is in transition, I would follow other random events of this era and not have the 15 min countdown.
// .playerl(FacialExpression.THINKING,"What happens if I get it wrong?")
// .npc(FacialExpression.SAD, "You haven't get a life sentence, so they'll let you out in", "[15] minutes, but you should be able to escape much", "faster if you go pull that lever and pop the right balloon", "animals.")
// Note the [15] minutes part counts down, Prison pete would say "you have 9 minutes left" and yada
.end()
}
}
}
}
class PrisonPeteIntroDialogueFile : DialogueBuilderFile() {
override fun create(b: DialogueBuilder) {
b.onPredicate { _ -> true }
.playerl(FacialExpression.AMAZED, "What on ${ServerConstants.SERVER_NAME} just happened?")
.npc(FacialExpression.SAD, "This isn't ${ServerConstants.SERVER_NAME} anymore, this is Scape2009.", "So you've been captured, too?")
.playerl(FacialExpression.THINKING, "Captured?")
.npcl(FacialExpression.SAD, "Yes, Evil Bob captured me and stuck me in this prison.")
.player(FacialExpression.ANGRY, "How do I get out of here?", "I can't be held captive by a cat!")
.npcl(FacialExpression.SAD, "Some of these balloon animals have keys in them, and if you pull the big lever it tells you which shape animal contains the correct key, but I can never find it.")
.npcl(FacialExpression.SAD, "You need to pull the lever to find out which shape animal contains the key, then pop that sort of animal to get the key.")
.npc(FacialExpression.SAD, "Bring me any keys you get and", "I'll try them on the doors.")
.playerl(FacialExpression.THINKING,"What happens if I get it wrong?")
.npc(FacialExpression.SAD, "You haven't get a life sentence, so they'll let you out in", "[15] minutes, but you should be able to escape much", "faster if you go pull that lever and pop the right balloon", "animals.")
.end()
}
}

View file

@ -0,0 +1,206 @@
package content.global.ame.events.prisonpete
import content.global.ame.RandomEvents
import content.global.ame.returnPlayer
import core.api.*
import core.game.dialogue.FacialExpression
import core.game.interaction.InteractionListener
import core.game.interaction.InterfaceListener
import core.game.interaction.QueueStrength
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.*
// Model 6474 is interesting
// http://youtu.be/a1R5vdqiBCQ
// http://youtu.be/6PKLqIjoR4c
// http://youtu.be/7eHhptb80WU
// http://youtu.be/28Ah8i6PUK0
/**
* Prison Pete Random / Evil Bob 2
* Do note that this is the most patchwork random ever, due to the map being in transition to a newer one.
* The old one (seen in osrs too) has a corridor on the east with 3 barriers.
* The new one (seen in rs3) came in around Jan 2009 and includes a locked door to the south.
* Due to the shit map and half fucked version of objects, we are following the locked door variation.
* Note that there are a lot of moving parts due to Jigglyflex trying stupid shit.
* There used to be a 15 mins timer, but I think it's later, so I'm here to make you suffer this random event.
*
* Note: On server load, some sceneries are patched into Prison Pete in ObjectParser.xml file.
*/
class PrisonPeteListeners : InteractionListener, InterfaceListener, MapArea {
companion object {
val balloons = intArrayOf(0, NPCs.BALLOON_ANIMAL_3119,NPCs.BALLOON_ANIMAL_3120,NPCs.BALLOON_ANIMAL_3121,NPCs.BALLOON_ANIMAL_3122)
val models = intArrayOf(0, 10734, 10735, 10736, 10737)
const val attributeReturnLoc = "/save:original-loc"
const val attributeTimesUnlocked = "/save:prisonpete:timesUnlocked"
const val attributeCurrentBalloonIndex = "prisonpete:currentballoon"
const val attributePoppedBalloonIndex = "prisonpete:poppedballoon"
fun randomizeBalloon(player: Player) {
setAttribute(player, attributeCurrentBalloonIndex, (1..4).random())
}
}
var count = 1
override fun defineListeners() {
/**
* Alright, this is the most infuriating component.
* I cannot for the life of me get this goddamn thing to animate.
* So here's some details
*
* Clicking on the lever should open Components.PRISONPETE_273
* child 1 is the text below
* child 2 is the button overlaying the balloon
* child 3 is the balloon image
* child 4-6 is unknown
*
* There are 2 sets of balloon animal MODELS.
* 10734, 10735, 10736, 10737 - Models used for NPCs 3119, 3120, 3121, 3122
* 10749, 10750, 10751, 10752 - Models used for the component(PRISONPETE_273) because 10753 is the grill for it.
*
* Animation 3047 is the "old" rotating animation, ([3048, 3049, 3050, 3052] are walking animations for balloons)
* but the first set animates it waaay too tiny,
* and the second set doesn't animate at all.
*
* I've tried a lot of animations, but I can't find it, so the replacment here is to use:
* the first set, with animation 7163 as a workaround
*
* Update: I've determined from a1R5vdqiBCQ that this is a challenging one.
* You can click on the interface, which changes the way the thing spins.
* I'm assuming one of the other childs (4,5,6) are axis controls, that I don't know how to control.
* maybe all that 562_interface_configs.txt and stuff
* player.packetDispatch.sendIfaceSettings(281, 5, Components.PRISONPETE_273, 23, 23)
*
*/
on(Scenery.LEVER_26191, SCENERY, "pull") { player, node ->
openInterface(player, Components.PRISONPETE_273)
randomizeBalloon(player)
player.packetDispatch.sendModelOnInterface(models[getAttribute(player, attributeCurrentBalloonIndex, 0)], Components.PRISONPETE_273, 3, 0)
sendAnimationOnInterface(player,7163, Components.PRISONPETE_273, 3)
return@on true
}
// Burst a balloon.
on(intArrayOf(NPCs.BALLOON_ANIMAL_3119,NPCs.BALLOON_ANIMAL_3120,NPCs.BALLOON_ANIMAL_3121,NPCs.BALLOON_ANIMAL_3122), NPC, "pop") { player, node ->
if (inInventory(player, Items.PRISON_KEY_6966)){
sendNPCDialogueLines(player, NPCs.PRISON_PETE_3118, FacialExpression.ANGRY, false,"Hey, bring me that key you've got!", "I wanna get out of here!") // B6FwlfnRtAo
} else if (getAttribute(player, attributeCurrentBalloonIndex, 0) == 0) {
sendNPCDialogueLines(player, NPCs.PRISON_PETE_3118, FacialExpression.ANGRY, false,"You're meant to pull the lever to find out", "which sort of animal to pop!") // a1R5vdqiBCQ
} else {
animate(player, 10017)
sendGraphics(524, node.location)
(node as NPC).finalizeDeath(player)
queueScript(player, 1, QueueStrength.SOFT) {
animate(player, 7270)
if(player.inventory.isFull) {
sendDialogue(player, "You don't have room to pick up any keys.") // qqncnqOc_MA
addItemOrDrop(player, Items.PRISON_KEY_6966)
return@queueScript stopExecuting(player)
}
addItemOrDrop(player, Items.PRISON_KEY_6966)
sendNPCDialogueLines(player, NPCs.PRISON_PETE_3118, FacialExpression.FRIENDLY, false,"Great, now you've got a key!", "Bring it to me so I can try it on the door")
setAttribute(player, attributePoppedBalloonIndex, balloons.indexOf(node.id))
// Technically, the person autowalks to prison pete, but screw that lmao.
return@queueScript stopExecuting(player)
}
}
return@on true
}
on(Items.PRISON_KEY_6966, ITEM, "drop") { player, node ->
// http://youtu.be/c3DJGIVG3MM
sendMessage(player,"The key disappears as it hits the ground.")
return@on true
}
on(Scenery.LOCKED_DOOR_26188, SCENERY, "open") { player, node ->
if (getAttribute(player, attributeTimesUnlocked, 0) >= 3) {
sendMessage(player, "You quickly escape the prison with Pete.")
removeAttribute(player, attributeTimesUnlocked)
closeInterface(player)
queueScript(player, 0, 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 -> {
val loot = RandomEvents.CERTER.loot!!.roll(player)[0]
addItemOrDrop(player, loot.id, loot.amount)
returnPlayer(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
closeInterface(player)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
} else {
sendMessage(player, "You need 3 more keys to unlock this gate.") // Inauthentic
if (inInventory(player, Items.PRISON_KEY_6966)){
sendNPCDialogueLines(player, NPCs.PRISON_PETE_3118, FacialExpression.ANGRY, false,"Hey, bring me that key you've got!", "I wanna get out of here!") // B6FwlfnRtAo
} else if (getAttribute(player, attributeCurrentBalloonIndex, 0) == 0) {
sendNPCDialogueLines(player, NPCs.PRISON_PETE_3118, FacialExpression.ANGRY, false,"You're meant to pull the lever to find out", "which sort of animal to pop!") // a1R5vdqiBCQ
}
}
return@on true
}
// End of 15 mins:
// SFiAALVHrR8
// npc(FacialExpression.SAD, "You've served your sentence, so you can walk out now.", "Lucky you!")
// player(FacialExpression.THINKING, "Aren't you coming?")
// npc(FacialExpression.SAD, "No, I've got a life sentence. Maybe if you'd been able", "to get the door open for yourself I could have escaped", "with you.")
// player(FacialExpression.SAD, "I'm sorry.")
// npc(FacialExpression.SAD, "Oh, don't worry. Someone always rescues me", "eventually. Then Evil Bob drags me back again. It's", "been going on for ages. Now, you'd better get out", "before you're arrested for loitering.")
// You can now at any point, click the gate and walk out as per normal.
}
override fun defineInterfaceListeners() {
on(Components.PRISONPETE_273) { player, _, _, buttonID, _, _ ->
if (buttonID == 2) {
// So this is the new thing that happens.
// On click, this will cause the object to spin in a different direction.
// Unfortunately I don't know how to do this.
}
return@on true
}
}
override fun defineAreaBorders(): Array<ZoneBorders> {
return arrayOf(getRegionBorders(8261))
}
override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
}
override fun areaEnter(entity: Entity) {
if (entity is Player) {
// sendMessage(entity, "Head for the center of the maze.")
}
}
override fun areaLeave(entity: Entity, logout: Boolean) {
if (entity is Player) {
//entity.unhook(this)
}
}
override fun entityStep(entity: Entity, location: Location, lastLocation: Location) {
if (entity is Player) {
//entity.hook(Event.Tick, this)
}
}
}

View file

@ -0,0 +1,46 @@
package content.global.ame.events.prisonpete
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
/** Technically its EvilBobNpc, but there's already another random with him. */
class PrisonPeteNPC(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!")
visualize(player, 714, Graphics(308, 100, 50))
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
kidnapPlayer(player, Location(2083, 4461 ,0), TeleportManager.TeleportType.INSTANT)
sendMessage(player, "Welcome to Scape2009.")
openDialogue(player, PrisonPeteDialogue(), NPCs.PRISON_PETE_3118)
AntiMacro.terminateEventNpc(player)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}
override fun talkTo(npc: NPC) {
// The cat doesn't talk.
}
}