From 604925f513f7747c999f90b60c5197d16ecbd615 Mon Sep 17 00:00:00 2001 From: Zerken Date: Sun, 6 Aug 2023 13:03:45 +0000 Subject: [PATCH] Implemented Evil Bob's Island random event Added admin command ::bob to start random event --- Server/data/configs/ground_spawns.json | 2 +- Server/data/configs/music_configs.json | 2 +- Server/data/configs/npc_configs.json | 2 +- Server/data/configs/npc_spawns.json | 8 + .../main/content/global/ame/RandomEvents.kt | 2 + .../ame/events/evilbob/EvilBobDialogue.kt | 109 +++++++++++++ .../ame/events/evilbob/EvilBobListeners.kt | 146 +++++++++++++++++ .../global/ame/events/evilbob/EvilBobNPC.kt | 35 ++++ .../global/ame/events/evilbob/EvilBobUtils.kt | 92 +++++++++++ .../ame/events/evilbob/ServantCutscene.kt | 150 ++++++++++++++++++ .../ame/events/evilbob/ServantDialogue.kt | 57 +++++++ .../src/main/core/game/activity/Cutscene.kt | 12 +- .../system/command/sets/MiscCommandSet.kt | 5 + 13 files changed, 613 insertions(+), 9 deletions(-) create mode 100644 Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt create mode 100644 Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt create mode 100644 Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt create mode 100644 Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt create mode 100644 Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt create mode 100644 Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt diff --git a/Server/data/configs/ground_spawns.json b/Server/data/configs/ground_spawns.json index 989bbc066..adfa66cf9 100644 --- a/Server/data/configs/ground_spawns.json +++ b/Server/data/configs/ground_spawns.json @@ -85,7 +85,7 @@ }, { "item_id": "303", - "loc_data": "{1,3245,3155,0,10485900}-{1,3244,3159,0,10485900}" + "loc_data": "{1,3245,3155,0,10485900}-{1,3244,3159,0,10485900}-{1,3429,4784,0,75}-{1,3432,4783,0,75}-{1,3414,4768,0,75}-{1,3429,4769,0,75}-{1,3431,4772,0,75}-{1,3415,4786,0,75}-{1,3412,4784,0,75}" }, { "item_id": "305", diff --git a/Server/data/configs/music_configs.json b/Server/data/configs/music_configs.json index 336820da0..96fb00052 100644 --- a/Server/data/configs/music_configs.json +++ b/Server/data/configs/music_configs.json @@ -1239,7 +1239,7 @@ }, { "id": "411", - "borders": "{2496,4736,2559,4799}" + "borders": "{3403,4761,3442,4792}" }, { "id": "412", diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json index 2cb342a0d..a7167d741 100644 --- a/Server/data/configs/npc_configs.json +++ b/Server/data/configs/npc_configs.json @@ -24390,7 +24390,7 @@ "attack_level": "1" }, { - "examine": "Hey", + "examine": "Hey, it's Bob the cat! Or... is it?", "melee_animation": "0", "range_animation": "0", "defence_animation": "0", diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json index 50909ccac..75ab6fcdf 100644 --- a/Server/data/configs/npc_spawns.json +++ b/Server/data/configs/npc_spawns.json @@ -4787,6 +4787,14 @@ "npc_id": "2462", "loc_data": "{2596,4773,0,1,2}-{2602,4771,0,1,6}-{2596,4780,0,1,4}" }, + { + "npc_id": "2479", + "loc_data": "{3420,4777,0,0,0}" + }, + { + "npc_id": "2481", + "loc_data": "{3423,4777,0,0,5}" + }, { "npc_id": "2482", "loc_data": "{3057,3902,0,1,3}" diff --git a/Server/src/main/content/global/ame/RandomEvents.kt b/Server/src/main/content/global/ame/RandomEvents.kt index 19d49ce62..32212d157 100644 --- a/Server/src/main/content/global/ame/RandomEvents.kt +++ b/Server/src/main/content/global/ame/RandomEvents.kt @@ -4,6 +4,7 @@ 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.evilbob.EvilBobNPC import content.global.ame.events.evilchicken.EvilChickenNPC import content.global.ame.events.freakyforester.FreakyForesterNPC import content.global.ame.events.genie.GenieNPC @@ -40,6 +41,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n )), DRILL_DEMON(npc = SeargentDamienNPC()), EVIL_CHICKEN(npc = EvilChickenNPC()), + EVIL_BOB(npc = EvilBobNPC(), skillId = Skills.FISHING), SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"), FREAKY_FORESTER(npc = FreakyForesterNPC(), skillId = Skills.WOODCUTTING), TREE_SPIRIT(npc = TreeSpiritRENPC(), skillId = Skills.WOODCUTTING), diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt new file mode 100644 index 000000000..6f39535ae --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt @@ -0,0 +1,109 @@ +package content.global.ame.events.evilbob + +import content.global.ame.events.evilbob.EvilBobUtils.giveEventFishingSpot +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class EvilBobDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.EVIL_BOB_2479) + if (getAttribute(player!!, EvilBobUtils.assignedFishingZone, "none") == "none") giveEventFishingSpot(player!!) + when (stage) { + 0 -> { + if (getAttribute(player!!, EvilBobUtils.eventComplete, false)) { + sendDialogue(player!!, "Evil Bob appears to be sleeping, best not to wake him up.").also { stage = END_DIALOGUE } + } else if (removeItem(player!!, Items.RAW_FISHLIKE_THING_6200)) { + setAttribute(player!!, EvilBobUtils.fishCaught, false) + playerl(FacialExpression.NEUTRAL, "Here, I've brought you some fish.").also { stage = 500 } + } else if (removeItem(player!!, Items.RAW_FISHLIKE_THING_6204)) { + setAttribute(player!!, EvilBobUtils.fishCaught, false) + setAttribute(player!!, EvilBobUtils.attentive, true) + setAttribute(player!!, EvilBobUtils.attentiveNewSpot, true) + playerl(FacialExpression.NEUTRAL, "Here, I've brought you some fish.").also { stage = 600 } + } else if (inInventory(player!!, Items.FISHLIKE_THING_6202) || inInventory(player!!, Items.FISHLIKE_THING_6206)) { + npcl(FacialExpression.CHILD_NORMAL, "What, are you giving me cooked fish? What am I going to do with that? Uncook it first!").also { stage = 700 } + } else if (!getAttribute(player!!, EvilBobUtils.startingDialogueSeen, false)) { + playerl(FacialExpression.ASKING, "Huh?").also { stage = 800 } + setAttribute(player!!, EvilBobUtils.startingDialogueSeen, true) + } else playerl(FacialExpression.ANNOYED, "Let me out of here!").also { stage++ } + } + 1 -> npcl(FacialExpression.CHILD_NORMAL, "I will never let you go, ${player!!.username}!").also { stage++ } + 2 -> options("Why not?", "What's it all about?", "How is it possible that you're talking?", "What did you do to Bob?").also { stage++ } + 3 -> when (buttonID) { + 1 -> playerl(FacialExpression.ASKING, "Why not?").also { stage = 100 } + 2 -> playerl(FacialExpression.ASKING, "What's it all about?").also { stage = 200 } + 3 -> playerl(FacialExpression.ASKING, "How is it possible that you're talking?").also { stage = 300 } + 4 -> playerl(FacialExpression.ASKING, "What did you do to Bob?").also { stage = 400 } + } + + 100 -> npcl(FacialExpression.CHILD_NORMAL, "Uhm...").also { stage++ } + 101 -> npcl(FacialExpression.CHILD_NORMAL, "Because I say so! And because I can never have enough servants!").also { stage++ } + 102 -> npcl(FacialExpression.CHILD_NORMAL, "Now catch me some fish, I'm hungry.").also { stage++ } + 103 -> playerl(FacialExpression.ASKING, "What fish, where?").also { stage++ } + 104 -> npcl(FacialExpression.CHILD_NORMAL, "Talk to my other servants, and hurry it up!").also { stage = END_DIALOGUE } + + 200 -> npcl(FacialExpression.CHILD_NORMAL, "Sit down and I'll tell you. It's a question of servant shortage.").also { stage++ } + 201 -> playerl(FacialExpression.NEUTRAL, "Go on.").also { stage++ } + 202 -> npcl(FacialExpression.CHILD_NORMAL, "You are a skilled worker. A human like you is worth a great deal as a slave.").also { stage++ } + 203 -> playerl(FacialExpression.ANGRY, "A slave?? I will have nothing to do with you. Is that clear? Absolutely nothing.").also { stage++ } + 204 -> npcl(FacialExpression.CHILD_NORMAL, "Now be reasonable little human. It's just a matter of time before you will do everything I ask you to. Play along and this can be a very nice place.").also { stage++ } + 205 -> playerl(FacialExpression.ANGRY, "I will not make any deals with you. I'm a human. I will not be pushed, numbered, meowed at, teleported or enslaved. My life is my own.").also { stage++ } + 206 -> npcl(FacialExpression.CHILD_NORMAL, "Is it?").also { stage++ } + 207 -> playerl(FacialExpression.ANNOYED, "Yes. You won't hold me.").also { stage++ } + 208 -> npcl(FacialExpression.CHILD_NORMAL, "Won't I?").also { stage++ } + 209 -> npcl(FacialExpression.CHILD_NORMAL, "Let me assure you there's no way out.").also { stage++ } + 210 -> npcl(FacialExpression.CHILD_NORMAL, "Just ask my servants!").also { stage = END_DIALOGUE } + + 300 -> npcl(FacialExpression.CHILD_NORMAL, "How is it possible that you're not meowing?").also { stage++ } + 301 -> playerl(FacialExpression.HALF_ASKING, "Meowing?? Why would I be meowing?").also { stage++ } + 302 -> npcl(FacialExpression.CHILD_NORMAL, "Most humans do, that's why I'm wearing this amulet of Man speak... but I do try to train my staff in civilised speech.").also { stage++ } + 303 -> npcl(FacialExpression.CHILD_NORMAL, "Ah, but I suppose things are slightly different in your world... what a dreadful place that must be.").also { stage++ } + 304 -> playerl(FacialExpression.NEUTRAL, "I think I'm getting a headache...").also { stage = END_DIALOGUE } + + 400 -> npcl(FacialExpression.CHILD_NORMAL, "Bob? I am Bob!").also { stage++ } + 401 -> npcl(FacialExpression.CHILD_NORMAL, "Oh, you mean the Bob in your world? Nothing. I am an incarnation of Bob here on Scape2009.").also { stage++ } + 402 -> playerl(FacialExpression.NEUTRAL, "What, you mean this is... like some kind of mirror land?").also { stage++ } + 403 -> npcl(FacialExpression.CHILD_NORMAL, " Something like that... somewhere in Scape2009 there must be a human servant called ${player!!.username}.").also { stage++ } + 404 -> npcl(FacialExpression.CHILD_NORMAL, "But you work just as well for me! Now get to work, human! Fish for me!").also { stage = END_DIALOGUE } + + 500 ->{ + if (getAttribute(player!!, EvilBobUtils.attentive , false)) stage = 505 else stage++ + npcl(FacialExpression.CHILD_NORMAL, "Mmm, mmm...that's delicious.") + } + 501 -> npcl(FacialExpression.CHILD_NORMAL, "Now, let me take...a little...catnap.").also { stage++ } + 502 -> { + end() + setAttribute(player!!, EvilBobUtils.eventComplete, true) + findNPC(NPCs.EVIL_BOB_2479)!!.sendChat("ZZZzzz") + } + 505 -> { + setAttribute(player!!, EvilBobUtils.attentive , false) + setAttribute(player!!, EvilBobUtils.attentiveNewSpot , true) + giveEventFishingSpot(player!!) + npcl(FacialExpression.CHILD_NORMAL, "Now get me another, you no-good human.").also { stage++ } + } + 506 -> sendDialogue(player!!, "Evil Bob seems slightly less attentive of you.").also { stage = END_DIALOGUE } + + 600 -> npcl(FacialExpression.CHILD_NORMAL, "What was this? That was absolutely disgusting!").also { stage++ } + 601 -> npcl(FacialExpression.CHILD_NORMAL, "Don't you know what kind of fish I like? Talk to my other servants for some advice.").also { stage++ } + 602 -> sendDialogue(player!!, "Evil Bob seems more attentive of you.").also { stage = END_DIALOGUE } + + 700 -> playerl(FacialExpression.HALF_ASKING, "Errr... Uncook it?").also { stage++ } + 701 -> npcl(FacialExpression.CHILD_NORMAL,"You heard me! There's the cold fire, by the trees, now get uncooking!").also { stage = END_DIALOGUE } + + 800 -> playerl(FacialExpression.ANGRY, "Where am I?").also { stage++ } + 801 -> npcl(FacialExpression.CHILD_NORMAL, "On my island.").also { stage++ } + 802 -> playerl(FacialExpression.ANGRY, "Who brought me here?").also { stage++ } + 803 -> npcl(FacialExpression.CHILD_NORMAL, "That would be telling.").also { stage++ } + 804 -> playerl(FacialExpression.ANGRY, "Take me to your leader!").also { stage++ } + 805 -> npcl(FacialExpression.CHILD_NORMAL,"I am your leader, you are but a slave.").also { stage++ } + 806 -> playerl(FacialExpression.ANGRY, "I am not a slave, I am a free man!").also { stage++ } + 807 -> npcl(FacialExpression.CHILD_NORMAL, "Ah-ha-ha-ha-ha-ha!").also { stage = END_DIALOGUE } + } + } +} diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt new file mode 100644 index 000000000..150be8a96 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt @@ -0,0 +1,146 @@ +package content.global.ame.events.evilbob + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.player.link.emote.Emotes +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 +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class EvilBobListeners : InteractionListener, MapArea { + + override fun defineListeners() { + on(EvilBobUtils.evilBob, IntType.NPC, "talk-to") { player, node -> + openDialogue(player, EvilBobDialogue(), node.asNpc()) + return@on true + } + + on(EvilBobUtils.servant, IntType.NPC, "talk-to") { player, node -> + openDialogue(player, ServantDialogue(), node.asNpc()) + return@on true + } + + on(EvilBobUtils.fishingSpot, IntType.SCENERY, "net") { player, _ -> + if (getAttribute(player!!, EvilBobUtils.attentiveNewSpot, false) || getAttribute(player!!, EvilBobUtils.eventComplete, false)) { + sendDialogue(player, "You don't know if this is a good place to go fishing. Perhaps you should ask someone, like one of the human servants.") + } else if (!inInventory(player, Items.SMALL_FISHING_NET_303)) { + sendNPCDialogue(player, NPCs.SERVANT_2481, "You'll need a fishing net. There are plenty scattered around the beach.", FacialExpression.SAD); + } else if (freeSlots(player) == 0) { + sendDialogue(player, "You don't have enough space in your inventory.") + } else if (getAttribute(player, EvilBobUtils.fishCaught, false)) { + sendNPCDialogue(player, NPCs.SERVANT_2481, "You've already got a fish. Come over here to uncook it, then serve it to Evil Bob.", FacialExpression.SAD) + } else { + lock(player, 6) + animate(player, EvilBobUtils.fishAnim) + sendMessage(player, "You cast out your net...") + runTask(player, 6) { + when (getAttribute(player, EvilBobUtils.assignedFishingZone, EvilBobUtils.northFishingZone.toString())) { + EvilBobUtils.northFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.northFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + EvilBobUtils.southFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.southFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + EvilBobUtils.eastFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.eastFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + EvilBobUtils.westFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.westFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + } + sendItemDialogue(player, Items.FISHLIKE_THING_6202, "You catch a... what is this?? Is this a fish?? And it's cooked already??") + resetAnimator(player) + setAttribute(player, EvilBobUtils.fishCaught, true) + } + } + return@on true + } + + onUseWith(IntType.SCENERY, EvilBobUtils.fishlikeThings, EvilBobUtils.uncookingPot) { player, _, _ -> + lock(player, 2) + animate(player, EvilBobUtils.cookAnim) + playAudio(player, Sounds.UNCOOKING_2322) + if (removeItem(player, Items.FISHLIKE_THING_6202)) addItem(player, Items.RAW_FISHLIKE_THING_6200) + if (removeItem(player, Items.FISHLIKE_THING_6206)) addItem(player, Items.RAW_FISHLIKE_THING_6204) + return@onUseWith true + } + + onUseWith(IntType.NPC, EvilBobUtils.fishlikeThings, EvilBobUtils.evilBob) { player, _, _ -> + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) + return@onUseWith true + } + + onUseWith(IntType.NPC, EvilBobUtils.rawFishlikeThings, EvilBobUtils.evilBob) { player, _, _ -> + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) + return@onUseWith true + } + + on(EvilBobUtils.fishlikeThings, IntType.ITEM, "Eat") { player, _ -> + sendMessage(player, "It looks vile and smells even worse. You're not eating that!") + return@on true + } + + on(EvilBobUtils.exitPortal, IntType.SCENERY, "enter") { player, portal -> + if (getAttribute(player, EvilBobUtils.eventComplete, false)) { + lock(player, 12) + submitWorldPulse(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> forceMove(player, player.location, portal.location, 0, 50, null, 819) + 4 -> { + player.faceLocation(Location.create(3421, 4777, 0)) + emote(player, Emotes.RASPBERRY) + sendChat(player, "Be seeing you!") + + } + 7 -> { + player.animate(EvilBobUtils.teleAnim) + player.graphics(EvilBobUtils.telegfx) + playAudio(player, Sounds.TELEPORT_ALL_200) + + } + 10 -> { + sendMessage(player, "Welcome back to 2009Scape.") + teleport(player, getAttribute(player, EvilBobUtils.prevLocation, Location.create(3222, 3219, 0))) + EvilBobUtils.reward(player) + EvilBobUtils.cleanup(player) + sendPlayerDialogue(player, "That was the strangest dream I've ever had! Assuming it was a dream...", FacialExpression.HALF_ASKING) + resetAnimator(player) + } + } + return false + } + }) + } else sendNPCDialogue(player, NPCs.EVIL_BOB_2479, "You're going nowhere, human!", FacialExpression.CHILD_NEUTRAL) + return@on true + } + } + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(3400, 4762, 3443, 4793)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + } + + override fun areaEnter(entity: Entity) { + entity.locks.lockTeleport(1000000) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt new file mode 100644 index 000000000..3f6d8cca3 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt @@ -0,0 +1,35 @@ +package content.global.ame.events.evilbob + +import content.global.ame.RandomEventNPC +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.node.entity.npc.NPC +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") + lock(player, 10) + runTask(player, 6) { + sendChat(player, "No... what? Nooooooooooooo!") + player.animate(EvilBobUtils.teleAnim) + player.graphics(EvilBobUtils.telegfx) + playAudio(player, Sounds.TELEPORT_ALL_200) + EvilBobUtils.giveEventFishingSpot(player) + runTask(player, 3) { + sendMessage(player, "Welcome to Scape2009.") + EvilBobUtils.teleport(player) + resetAnimator(player) + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) + content.global.ame.RandomEventManager.getInstance(player)?.event?.terminate() + } + } + } + + override fun talkTo(npc: NPC) { + player.dialogueInterpreter.open(EvilBobDialogue(), this.asNpc()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt new file mode 100644 index 000000000..40f0027b9 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt @@ -0,0 +1,92 @@ +package content.global.ame.events.evilbob + +import core.api.* +import core.game.node.entity.player.Player +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 +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +object EvilBobUtils { + const val prevLocation = "/save:evilbob:prevlocation" + const val eventComplete = "/save:evilbob:eventcomplete" + const val assignedFishingZone = "/save:evilbob:fishingzone" + const val fishCaught = "evilbob:fishcaught" + const val attentive = "/save:evilbob:attentive" + const val servantHelpDialogueSeen = "/save:evilbob:servantdialogeseen" + const val attentiveNewSpot = "/save:evilbob:attentivenewspot" + const val startingDialogueSeen = "/save:evilbob:startingdialogueseen" + + const val evilBob = NPCs.EVIL_BOB_2479 + const val servant = NPCs.SERVANT_2481 + const val exitPortal = Scenery.PORTAL_8987 + + const val uncookingPot = Scenery.UNCOOKING_POT_8985 + const val fishingSpot = 8986 + + val fishlikeThings = intArrayOf(Items.FISHLIKE_THING_6202, Items.FISHLIKE_THING_6206) + val rawFishlikeThings = intArrayOf(Items.RAW_FISHLIKE_THING_6200, Items.RAW_FISHLIKE_THING_6204) + + val cookAnim = Animation(897) + val fishAnim = Animation(620) + val teleAnim = Animation(714) + val telegfx = Graphics(308, 100, 50) + + val northFishingZone = ZoneBorders(3421, 4789, 3427, 4792) + val eastFishingZone = ZoneBorders(3437, 4774, 3440, 4780) + val southFishingZone = ZoneBorders(3419, 4763, 3426, 4765) + val westFishingZone = ZoneBorders(3405, 4773, 3408, 4779) + + fun giveEventFishingSpot(player: Player) { + when (RandomFunction.getRandom(3)) { + 0 -> setAttribute(player, assignedFishingZone, northFishingZone.toString()) + 1 -> setAttribute(player, assignedFishingZone, southFishingZone.toString()) + 2 -> setAttribute(player, assignedFishingZone, eastFishingZone.toString()) + 3 -> setAttribute(player, assignedFishingZone, westFishingZone.toString()) + else -> setAttribute(player, assignedFishingZone, northFishingZone.toString()) + } + } + + fun teleport(player: Player) { + setAttribute(player, prevLocation, player.location) + player.properties.teleportLocation = Location.create(3419, 4776, 0) + } + + fun cleanup(player: Player) { + player.locks.unlockTeleport() + player.properties.teleportLocation = getAttribute(player, prevLocation, null) + removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) + removeAll(player, Items.FISHLIKE_THING_6202) + removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK) + removeAll(player, Items.FISHLIKE_THING_6206) + removeAll(player, Items.FISHLIKE_THING_6206, Container.BANK) + removeAll(player, Items.RAW_FISHLIKE_THING_6200) + removeAll(player, Items.RAW_FISHLIKE_THING_6200, Container.BANK) + removeAll(player, Items.RAW_FISHLIKE_THING_6204) + removeAll(player, Items.RAW_FISHLIKE_THING_6204, Container.BANK) + } + + fun reward(player: Player) { + val experience = 650.0 + if (getStatLevel(player, Skills.MAGIC) > 50 ) { + when (RandomFunction.getRandom(1)) { + 0 -> { + player.skills.addExperience(Skills.FISHING, experience) + runTask(player, 8) { sendDialogue(player, "You feel somehow that you've become better at fishing.") } + } + 1 -> { + player.skills.addExperience(Skills.MAGIC, experience) + runTask(player, 8) { sendDialogue(player, "You feel somehow that you've become better at magic.") } + } + } + } else { + player.skills.addExperience(Skills.FISHING, experience) + runTask(player, 6) { sendDialogue(player, "You feel somehow that you've become better at fishing.") } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt b/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt new file mode 100644 index 000000000..db54e0db9 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt @@ -0,0 +1,150 @@ +package content.global.ame.events.evilbob + +import core.api.* +import core.game.activity.Cutscene +import core.game.node.entity.player.Player + +class ServantCutsceneN(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(30, 43) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(30, 51, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(30, 46, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + } + } +} + +class ServantCutsceneS(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(29, 38) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(29, 30, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(29, 35, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + } + } +} + +class ServantCutsceneE(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(35, 41) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(43, 41, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(38, 41, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + } + } +} + +class ServantCutsceneW(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(25, 40) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(18, 40, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(22, 40, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt b/Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt new file mode 100644 index 000000000..09c659c5b --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt @@ -0,0 +1,57 @@ +package content.global.ame.events.evilbob + +import core.api.getAttribute +import core.api.setAttribute +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class ServantDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SERVANT_2481) + when (stage) { + 0 -> { + if (getAttribute(player!!, EvilBobUtils.eventComplete, false)) { + playerl(FacialExpression.NEUTRAL, "Evil Bob has fallen asleep, come quickly!").also { stage = 2 } + } else if (!getAttribute(player!!, EvilBobUtils.servantHelpDialogueSeen, false)) { + playerl(FacialExpression.ANGRY, "I need help, I've been kidnapped by an evil cat!").also { stage = 200 } + } else if (getAttribute(player!!, EvilBobUtils.attentiveNewSpot, false)) { + npcl(FacialExpression.SAD, "Look... over t-t-there! That fishing spot c-c-contains the f-f-f-fish he likes.").also { stage = 1 } + } else npcl(FacialExpression.SAD, "F-f-f-fish... give him the f-f-f-fish he likes and he might f- f-f-fall asleep.").also { stage = END_DIALOGUE } + + } + 1 -> { + end() + setAttribute(player!!, EvilBobUtils.attentiveNewSpot, false) + when (getAttribute(player!!, EvilBobUtils.assignedFishingZone, EvilBobUtils.northFishingZone.toString())) { + EvilBobUtils.northFishingZone.toString() -> ServantCutsceneN(player!!).start() + EvilBobUtils.southFishingZone.toString() -> ServantCutsceneS(player!!).start() + EvilBobUtils.eastFishingZone.toString() -> ServantCutsceneE(player!!).start() + EvilBobUtils.westFishingZone.toString() -> ServantCutsceneW(player!!).start() + } + } + 2 -> npcl(FacialExpression.SAD, "Come? Come where?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Away from this place! To 2009Scape proper!").also { stage++ } + 4 -> npcl(FacialExpression.SAD, "You go, ${player!!.username}, I don't belong there... I belong here, in Scape2009. This is the only place I can ever go...").also { stage++ } + 5 -> options("But I love you!", "Oh alright then.").also { stage++ } + 6 -> when(buttonID) { + 1 -> playerl(FacialExpression.SAD, "But I love you!").also { stage = 100 } + 2 -> playerl(FacialExpression.NEUTRAL, "Oh, alright then, I'll be off! See you around!").also { stage = END_DIALOGUE} + } + + 100 -> npcl(FacialExpression.NEUTRAL, "Our love can never be, sweet ${player!!.username}.").also { stage++ } + 101 -> npcl(FacialExpression.NEUTRAL, "Go now! Go, and don't look back!").also { stage = END_DIALOGUE } + + 200 -> npcl(FacialExpression.SAD, "Meow! Errr... I c-c-c-can't help you... He'll kill us all!").also { stage++ } + 201 -> playerl(FacialExpression.ANGRY, "Now you listen to me! He's just a little cat! There must be something I can do!").also { stage++ } + 202 -> npcl(FacialExpression.SAD, "F-f-f-fish... give him the f-f-f-fish he likes and he might f- f-f-fall asleep.").also { stage++ } + 203 -> { + npcl(FacialExpression.SAD, "Look... over t-t-there! That fishing spot c-c-contains the f-f-f-fish he likes.").also { stage = 1 } + setAttribute(player!!, EvilBobUtils.servantHelpDialogueSeen, true) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/activity/Cutscene.kt b/Server/src/main/core/game/activity/Cutscene.kt index d1627936f..9a3bf85b6 100644 --- a/Server/src/main/core/game/activity/Cutscene.kt +++ b/Server/src/main/core/game/activity/Cutscene.kt @@ -257,12 +257,6 @@ abstract class Cutscene(val player: Player) { 8 -> player.properties.teleportLocation = exitLocation 9 -> fadeFromBlack() 16 -> { - try { - endActions?.invoke() - } catch (e: Exception) { - log(this::class.java, Log.ERR, "There's some bad nasty code in ${this::class.java.simpleName} end actions!") - e.printStackTrace() - } return true } } @@ -283,6 +277,12 @@ abstract class Cutscene(val player: Player) { player.logoutListeners.remove("cutscene") content.global.ame.RandomEventManager.getInstance(player)?.enabled = true PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + try { + endActions?.invoke() + } catch (e: Exception) { + log(this::class.java, Log.ERR, "There's some bad nasty code in ${this::class.java.simpleName} end actions!") + e.printStackTrace() + } } }) } diff --git a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt index 98fb94a9c..14742786b 100644 --- a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt @@ -556,6 +556,11 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ content.global.ame.RandomEventManager.getInstance(player)!!.event!!.init() } + define("bob", Privilege.ADMIN){ player, _ -> + content.global.ame.RandomEventManager.getInstance(player)!!.event = RandomEvents.EVIL_BOB.npc.create(player) + content.global.ame.RandomEventManager.getInstance(player)!!.event!!.init() + } + define("revent", Privilege.ADMIN){ player, _ -> println(player.pulseManager.current) content.global.ame.RandomEventManager.getInstance(player)!!.fireEvent()