From 1ab6773910335ca9ed4ce9d9a429cfb1fa1ffd74 Mon Sep 17 00:00:00 2001 From: Zerken Date: Sun, 3 Sep 2023 13:33:26 +0000 Subject: [PATCH] Random event improvements Implemented smoke puff sound when random event npcs disappear Fixed smoke puff repeating Admins will no longer get random events Can no longer talk to a random event NPC if they are leaving Rewrote Drill Demon event: The event can no longer be avoided and Sergeant Damien automatically teleports you to the event The player can no longer escape the event by logging out Sergeant Damien now walks around the area in a circle as he should authentically Corrected all of Sergeant Damien's dialogue to be authentic Implemented the authentic item dialogues that show the player the picture of the sign to exercise at Implemented all the exercise sounds Evil Bob's Island: Rewrote all uses of pulses to scripts Fixed evil bob not teleporting players when in combat Fixed the reward dialogue Freaky Forester: Rewrote the freaky forester teleport to a script instead of a pulse Fixed an issue where nearby players could talk to the NPC Genie Event: Rewrote most of the event The genie now leaves after completing the dialogue Implemented the genie appearing sound Evil Chicken: Now uses the correct attack sound Misc: Added admin command ::barrage [radius] that new barrage command hits all the players in the radius defines with a custom weak ice barrage. It will play the ice barrage sound, display graphics and hit the player for a random 0-3 damage. A fail safe has been added so the command will hit 0 if the player is low on health so this command will not accidentally kill players --- Server/data/configs/npc_configs.json | 12 +- .../main/content/global/ame/RandomEventNPC.kt | 8 +- .../events/drilldemon/DrillDemonListeners.kt | 111 ++++++++++++------ .../ame/events/drilldemon/DrillDemonUtils.kt | 94 ++++++--------- .../drilldemon/SeargentDamienDefaultPlugin.kt | 29 ----- .../drilldemon/SeargentDamienDialogue.kt | 85 +++++++------- .../events/drilldemon/SeargentDamienNPC.kt | 28 +++-- .../drilldemon/SergeantDamienBehavior.kt | 22 ++++ .../ame/events/evilbob/EvilBobDialogue.kt | 10 +- .../ame/events/evilbob/EvilBobListeners.kt | 56 ++++----- .../global/ame/events/evilbob/EvilBobNPC.kt | 36 +++--- .../global/ame/events/evilbob/EvilBobUtils.kt | 6 +- .../events/freakyforester/FreakListeners.kt | 12 +- .../ame/events/freakyforester/FreakUtils.kt | 2 + .../freakyforester/FreakyForesterNPC.kt | 41 ++++--- .../global/ame/events/genie/GenieDialogue.kt | 17 +-- .../global/ame/events/genie/GenieNPC.kt | 12 +- .../global/handlers/npc/NPCTalkListener.kt | 2 +- .../game/system/command/sets/FunCommandSet.kt | 43 +++++-- .../core/game/system/timer/impl/AntiMacro.kt | 4 + 20 files changed, 351 insertions(+), 279 deletions(-) delete mode 100644 Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDefaultPlugin.kt create mode 100644 Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json index 057d3b2dc..c10ff586b 100644 --- a/Server/data/configs/npc_configs.json +++ b/Server/data/configs/npc_configs.json @@ -24223,7 +24223,7 @@ "combat_style": "2", "melee_animation": "2302", "range_animation": "2302", - "combat_audio": "355,357,356", + "combat_audio": "2288,357,356", "magic_level": "5", "respawn_delay": "25", "defence_animation": "2300", @@ -24246,7 +24246,7 @@ "combat_style": "2", "melee_animation": "2302", "range_animation": "2302", - "combat_audio": "355,357,356", + "combat_audio": "2288,357,356", "magic_level": "10", "respawn_delay": "25", "defence_animation": "2300", @@ -24269,7 +24269,7 @@ "combat_style": "2", "melee_animation": "2302", "range_animation": "2302", - "combat_audio": "355,357,356", + "combat_audio": "2288,357,356", "magic_level": "15", "respawn_delay": "25", "defence_animation": "2300", @@ -24292,7 +24292,7 @@ "combat_style": "2", "melee_animation": "2302", "range_animation": "2302", - "combat_audio": "355,357,356", + "combat_audio": "2288,357,356", "magic_level": "25", "respawn_delay": "25", "defence_animation": "2300", @@ -24315,7 +24315,7 @@ "combat_style": "2", "melee_animation": "2302", "range_animation": "2302", - "combat_audio": "355,357,356", + "combat_audio": "2288,357,356", "magic_level": "35", "respawn_delay": "25", "defence_animation": "2300", @@ -24338,7 +24338,7 @@ "combat_style": "2", "melee_animation": "2302", "range_animation": "2302", - "combat_audio": "355,357,356", + "combat_audio": "2288,357,356", "magic_level": "45", "respawn_delay": "25", "defence_animation": "2300", diff --git a/Server/src/main/content/global/ame/RandomEventNPC.kt b/Server/src/main/content/global/ame/RandomEventNPC.kt index cbcf794ce..c0aba00af 100644 --- a/Server/src/main/content/global/ame/RandomEventNPC.kt +++ b/Server/src/main/content/global/ame/RandomEventNPC.kt @@ -1,6 +1,7 @@ package content.global.ame import content.global.ame.events.MysteriousOldManNPC +import core.api.playGlobalAudio import core.api.poofClear import core.game.interaction.MovementPulse import core.game.node.entity.impl.PulseType @@ -14,6 +15,8 @@ import core.game.world.update.flag.context.Graphics import core.integrations.discord.Discord import core.api.utils.WeightBasedTable import core.tools.secondsToTicks +import core.tools.ticksToCycles +import org.rs09.consts.Sounds import kotlin.random.Random import kotlin.reflect.full.createInstance @@ -37,11 +40,12 @@ abstract class RandomEventNPC(id: Int) : NPC(id) { } open fun terminate() { - finalized = true pulseManager.clear(PulseType.STANDARD) - if (initialized) { + if (initialized && !finalized) { poofClear(this) + playGlobalAudio(this.location, Sounds.SMOKEPUFF_1930, ticksToCycles(1)) } + finalized = true } open fun follow() { diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt index 5f7881710..cb270f02f 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt @@ -1,50 +1,93 @@ package content.global.ame.events.drilldemon +import core.api.* import core.game.node.entity.npc.NPC -import core.game.system.task.Pulse import org.rs09.consts.NPCs import core.game.interaction.InteractionListener import core.game.interaction.IntType +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.tools.secondsToTicks -class DrillDemonListeners : InteractionListener { +import org.rs09.consts.Sounds + +class DrillDemonListeners : InteractionListener, MapArea { val MATS = intArrayOf(10076,10077,10078,10079) override fun defineListeners() { - on(MATS, IntType.SCENERY, "use"){ player, node -> - val correctTask = player.getAttribute(DrillDemonUtils.DD_KEY_TASK,-1) - if(correctTask == -1){ - player.sendMessage("You can't do that right now.") - return@on true + on(DrillDemonUtils.DD_NPC, IntType.NPC, "talk-to") { player, _ -> + if (inBorders(player, DrillDemonUtils.DD_AREA)) { + openDialogue(player, SeargentDamienDialogue(isCorrect = true), DrillDemonUtils.DD_NPC) + } else { + sendMessage(player, "They aren't interested in talking to you.") } - - val task = DrillDemonUtils.getMatTask(node.id,player) - val npc = NPC(NPCs.SERGEANT_DAMIEN_2790) - - player.lock() - val anim = DrillDemonUtils.animationForTask(task) - player.walkingQueue.reset() - player.walkingQueue.addPath(node.location.x,4820) - player.pulseManager.run(object : Pulse(){ - var counter = 0 - override fun pulse(): Boolean { - when(counter++){ - 2 -> player.faceLocation(player.location.transform(0,-1,0)) - 3 -> player.animator.animate(DrillDemonUtils.animationForTask(task)).also { delay = anim.duration / 2 } - 6 -> { - if(task == correctTask){ - player.incrementAttribute(DrillDemonUtils.DD_CORRECT_COUNTER) - player.dialogueInterpreter.open(SeargentDamienDialogue(true),npc) - } else { - player.dialogueInterpreter.open(SeargentDamienDialogue(false),npc) - } - return true - } - } - return false - } - }) return@on true } + on(MATS, IntType.SCENERY, "use") { player, node -> + val correctTask = getAttribute(player, DrillDemonUtils.DD_KEY_TASK, -1) + if (correctTask == -1) { + sendMessage(player,"You can't do that right now.") + return@on true + } + + val task = DrillDemonUtils.getMatTask(node.id, player) + val npc = NPC(NPCs.SERGEANT_DAMIEN_2790) + val anim = DrillDemonUtils.animationForTask(task) + + lock(player, secondsToTicks(30)) + player.walkingQueue.reset() + player.walkingQueue.addPath(node.location.x,4820) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + player.faceLocation(player.location.transform(0, -1, 0)) + return@queueScript delayScript(player, 2) + } + 1 -> { + animate(player, DrillDemonUtils.animationForTask(task)) + when (task) { + DrillDemonUtils.DD_SIGN_JOG -> playAudio(player, Sounds.RUNONSPOT_2484, 0, 5) + DrillDemonUtils.DD_SIGN_SITUP -> playAudio(player, Sounds.SITUPS_2486, 40, 5) + DrillDemonUtils.DD_SIGN_PUSHUP -> playAudio(player, Sounds.PRESSUPS_2481, 25, 5) + DrillDemonUtils.DD_SIGN_JUMP -> playAudio(player, Sounds.STAR_JUMP_2492, 0, 5) + } + return@queueScript delayScript(player, anim.duration + 2) + } + 2 -> { + DrillDemonUtils.changeSignsAndAssignTask(player) + if (task == correctTask) { + player.incrementAttribute(DrillDemonUtils.DD_CORRECT_COUNTER) + openDialogue(player, SeargentDamienDialogue(true), npc) + } else { + openDialogue(player, SeargentDamienDialogue(false), npc) + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + } + + override fun defineAreaBorders(): Array { + return arrayOf(DrillDemonUtils.DD_AREA) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + entity.asPlayer().interfaceManager.closeDefaultTabs() + entity.locks.lockTeleport(1000000) + setComponentVisibility(entity.asPlayer(), 548, 69, true) + setComponentVisibility(entity.asPlayer(), 746, 12, true) + } } } \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt index cce73abaf..8c6cc0899 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt @@ -1,39 +1,32 @@ package content.global.ame.events.drilldemon import core.api.* -import core.game.dialogue.FacialExpression import core.game.node.entity.player.Player -import core.game.node.item.GroundItemManager -import core.game.node.item.Item 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 import org.rs09.consts.NPCs object DrillDemonUtils { - val DD_KEY_NPC = "drilldemon:npc" - val DD_KEY_TASK = "drilldemon:task" - val DD_KEY_RETURN_LOC = "drilldemon:original-loc" + val DD_KEY_TASK = "/save:drilldemon:task" + val DD_KEY_RETURN_LOC = "/save:drilldemon:original-loc" val DD_SIGN_VARP = 531 val DD_SIGN_JOG = 0 val DD_SIGN_SITUP = 1 val DD_SIGN_PUSHUP = 2 val DD_SIGN_JUMP = 3 - val DD_CORRECT_OFFSET = "drilldemon:offset" - val DD_CORRECT_COUNTER = "drilldemon:numcorrect" + val DD_CORRECT_OFFSET = "/save:drilldemon:offset" + val DD_CORRECT_COUNTER = "/save:drilldemon:numcorrect" + val DD_AREA = ZoneBorders(3158,4817, 3168, 4823) + val DD_NPC = NPCs.SERGEANT_DAMIEN_2790 fun teleport(player: Player){ - player.setAttribute(DD_KEY_RETURN_LOC,player.location) - player.properties.teleportLocation = Location.create(3163, 4819, 0) + setAttribute(player, DD_KEY_RETURN_LOC,player.location) + teleport(player, Location.create(3163, 4819, 0)) player.interfaceManager.closeDefaultTabs() - player.packetDispatch.sendInterfaceConfig(548, 69, true) - player.packetDispatch.sendInterfaceConfig(746, 12, true) - - registerLogoutListener(player, "drilldemon"){p -> - teleport(p, player.getAttribute(DD_KEY_RETURN_LOC, p.location)) - } - - changeSignsAndAssignTask(player) + setComponentVisibility(player, 548, 69, true) + setComponentVisibility(player, 746, 12, true) } fun changeSignsAndAssignTask(player: Player){ @@ -43,28 +36,19 @@ object DrillDemonUtils { val task = tempList.random() val taskOffset = tempOffsetList.random() - player.setAttribute(DD_KEY_TASK,task) - player.setAttribute(DD_CORRECT_OFFSET,taskOffset) + setAttribute(player, DD_KEY_TASK,task) + setAttribute(player, DD_CORRECT_OFFSET,taskOffset) tempList.remove(task) tempOffsetList.remove(taskOffset) setVarbit(player, taskOffset, task) - for(i in 0 until tempList.size){ - setVarbit(player, tempOffsetList[i], tempList[i]) + for (i in 0 until tempList.size) { + setVarbit(player, tempOffsetList[i], tempList[i], true) } - - player.dialogueInterpreter.sendDialogues(NPCs.SERGEANT_DAMIEN_2790, FacialExpression.OLD_NORMAL,when(task){ - DD_SIGN_JOG -> "Get over there and jog in place!" - DD_SIGN_JUMP -> "I need 40 jumping jacks stat!" - DD_SIGN_PUSHUP -> "Get over there and give me 20 pushups!" - DD_SIGN_SITUP -> "I need 30 situps pronto!" - else -> "REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" - }) - player.unlock() } fun getVarbitForId(id: Int): Int{ - return when(id){ + return when (id) { 10076 -> 1335 10077 -> 1336 10078 -> 1337 @@ -77,21 +61,21 @@ object DrillDemonUtils { return getVarbit(player, getVarbitForId(id)) } - fun cleanup(player: Player){ - clearLogoutListener(player, "drilldemon") - player.properties.teleportLocation = player.getAttribute(DD_KEY_RETURN_LOC) - player.removeAttribute(DD_KEY_NPC) - player.removeAttribute(DD_KEY_RETURN_LOC) - player.removeAttribute(DD_KEY_TASK) - player.removeAttribute(DD_CORRECT_OFFSET) - player.removeAttribute(DD_CORRECT_COUNTER) + fun cleanup(player: Player) { + player.locks.unlockTeleport() + unlock(player) + teleport(player, getAttribute(player, DD_KEY_RETURN_LOC, Location.create(3222, 3218, 0))) + removeAttribute(player, DD_KEY_RETURN_LOC) + removeAttribute(player, DD_KEY_TASK) + removeAttribute(player, DD_CORRECT_OFFSET) + removeAttribute(player, DD_CORRECT_COUNTER) player.interfaceManager.openDefaultTabs() - player.packetDispatch.sendInterfaceConfig(548, 69, false) - player.packetDispatch.sendInterfaceConfig(746, 12, false) + setComponentVisibility(player, 548, 69, false) + setComponentVisibility(player, 746, 12, false) } fun animationForTask(task: Int): Animation { - return when(task){ + return when (task) { DD_SIGN_SITUP -> Animation(2763) DD_SIGN_PUSHUP -> Animation(2762) DD_SIGN_JUMP -> Animation(2761) @@ -100,21 +84,15 @@ object DrillDemonUtils { } } - fun reward(player: Player){ - val hasHat = player.inventory.contains(Items.CAMO_HELMET_6656,1) || player.bank.contains(Items.CAMO_HELMET_6656,1) || player.equipment.contains(Items.CAMO_HELMET_6656,1) - val hasShirt = player.inventory.contains(Items.CAMO_TOP_6654,1) || player.bank.contains(Items.CAMO_TOP_6654,1) || player.equipment.contains(Items.CAMO_TOP_6654,1) - val hasPants = player.inventory.contains(Items.CAMO_BOTTOMS_6655,1) || player.bank.contains(Items.CAMO_BOTTOMS_6655,1) || player.equipment.contains(Items.CAMO_BOTTOMS_6655,1) - val reward = if(!hasHat){ - Item(Items.CAMO_HELMET_6656) - } else if(!hasShirt){ - Item(Items.CAMO_TOP_6654) - } else if(!hasPants){ - Item(Items.CAMO_BOTTOMS_6655) - } else { - Item(Items.COINS_995, 500) - } - if(!player.inventory.add(reward)){ - GroundItemManager.create(reward,player) + fun reward(player: Player) { + val hasHat = hasAnItem(player, Items.CAMO_HELMET_6656).container != null + val hasShirt = hasAnItem(player, Items.CAMO_TOP_6654).container != null + val hasPants = hasAnItem(player, Items.CAMO_BOTTOMS_6655).container != null + when { + !hasHat -> addItemOrDrop(player, Items.CAMO_HELMET_6656) + !hasShirt -> addItemOrDrop(player, Items.CAMO_TOP_6654) + !hasPants -> addItemOrDrop(player, Items.CAMO_BOTTOMS_6655) + else -> addItemOrDrop(player, Items.COINS_995, 500) } } } diff --git a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDefaultPlugin.kt b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDefaultPlugin.kt deleted file mode 100644 index 121f78a88..000000000 --- a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDefaultPlugin.kt +++ /dev/null @@ -1,29 +0,0 @@ -package content.global.ame.events.drilldemon - -import core.game.dialogue.DialoguePlugin -import core.game.node.entity.player.Player -import core.plugin.Initializable -import core.tools.END_DIALOGUE -import org.rs09.consts.NPCs - -@Initializable -class SeargentDamienDefaultPlugin(player: Player? = null) : DialoguePlugin(player) { - override fun newInstance(player: Player?): DialoguePlugin { - return SeargentDamienDefaultPlugin(player) - } - - override fun open(vararg args: Any?): Boolean { - npc("GET BACK TO WORK MAGGOT!") - stage = END_DIALOGUE - return true - } - - override fun handle(interfaceId: Int, buttonId: Int): Boolean { - return true - } - - override fun getIds(): IntArray { - return intArrayOf(NPCs.SERGEANT_DAMIEN_2790) - } - -} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt index 93e529fbf..d65aafd71 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt @@ -1,54 +1,53 @@ package content.global.ame.events.drilldemon -import core.game.system.task.Pulse +import core.api.* import core.game.dialogue.DialogueFile -import core.game.system.timer.impl.AntiMacro -import core.tools.END_DIALOGUE -import core.tools.START_DIALOGUE +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC -class SeargentDamienDialogue(val isCorrect: Boolean = false) : DialogueFile() { +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class SeargentDamienDialogue(var isCorrect: Boolean = false, var eventStart: Boolean = false) : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - var correctAmt = player!!.getAttribute(DrillDemonUtils.DD_CORRECT_COUNTER,0) - if(correctAmt == 4 && AntiMacro.getEventNpc(player!!) == null) { - when(stage){ - 0 -> npc(core.game.dialogue.FacialExpression.OLD_NORMAL,"My god you actually did it, you limp","wristed worm-bodied MAGGOT! Take this","and get out of my sight.").also { stage++ } - 1 -> { - end() - player!!.unlock() - DrillDemonUtils.cleanup(player!!) - player!!.pulseManager.run(object : Pulse(2){ - override fun pulse(): Boolean { - DrillDemonUtils.reward(player!!) - return true - } - }) - } - } - } else if(AntiMacro.getEventNpc(player!!) == null){ - when(stage){ - START_DIALOGUE -> if(isCorrect) npc(core.game.dialogue.FacialExpression.OLD_NORMAL,"Good! Now...").also { stage++ } else npc(core.game.dialogue.FacialExpression.OLD_ANGRY1,"WRONG, MAGGOT!").also { stage++ } - 1 -> { - end() + npc = NPC(NPCs.SERGEANT_DAMIEN_2790) + val correctCounter = player!!.getAttribute(DrillDemonUtils.DD_CORRECT_COUNTER,0) + when(stage) { + 0 -> { + if (correctCounter >= 4) { + npcl(FacialExpression.OLD_NORMAL, "Well I'll be, you actually did it private. Now take this and get yourself out of my sight.") + stage = 100 + } else if (eventStart) { + npcl(FacialExpression.OLD_NORMAL, "Move yourself private! Follow my orders and you may, just may, leave here in a fit state for my corps!") DrillDemonUtils.changeSignsAndAssignTask(player!!) + stage = 0 + eventStart = false + } else { + npcl(FacialExpression.OLD_NORMAL, when (getAttribute(player!!, DrillDemonUtils.DD_KEY_TASK, -1)) { + DrillDemonUtils.DD_SIGN_JOG -> if (!isCorrect) "Wrong exercise, worm! Get yourself over there and jog on that mat private!" else "Get yourself over there and jog on that mat private!" + DrillDemonUtils.DD_SIGN_JUMP -> if (!isCorrect) "Wrong exercise, worm! I want to see you on that mat doing star jumps private!" else "I want to see you on that mat doing star jumps private!" + DrillDemonUtils.DD_SIGN_PUSHUP -> if (!isCorrect) "Wrong exercise, worm! Drop and give me push ups on that mat private!" else "Drop and give me push ups on that mat private!" + DrillDemonUtils.DD_SIGN_SITUP -> if (!isCorrect) "Wrong exercise, worm! Get on that mat and give me sit ups private!" else "Get on that mat and give me sit ups private!" + else -> "REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + }) + stage = 1 + unlock(player!!) } + } + 1 -> { + when (getAttribute(player!!, DrillDemonUtils.DD_KEY_TASK, -1)) { + DrillDemonUtils.DD_SIGN_JOG -> sendItemDialogue(player!!, Items.RUN_10947, "Go to this mat and jog on the spot!") + DrillDemonUtils.DD_SIGN_JUMP -> sendItemDialogue(player!!, Items.STARJUMP_10949, "Go to this mat and do some starjumps!") + DrillDemonUtils.DD_SIGN_PUSHUP -> sendItemDialogue(player!!, Items.PUSHUP_10946, "Go to this mat and do some pushups!") + DrillDemonUtils.DD_SIGN_SITUP -> sendItemDialogue(player!!, Items.SITUP_10948, "Go to this mat and do some sit ups!") } - } else { - when(stage){ - START_DIALOGUE -> npc(core.game.dialogue.FacialExpression.OLD_NORMAL,"Would you like to come work out?").also { stage++ } - 1 -> options("Yes, please.", "No, thanks.").also { stage++ } - 2 -> when(buttonID){ - 1 -> { - end() - DrillDemonUtils.teleport(player!!) - AntiMacro.terminateEventNpc(player!!) - stage = END_DIALOGUE - } - 2 -> { - end() - AntiMacro.terminateEventNpc(player!!) - stage = END_DIALOGUE - } - } + stage = END_DIALOGUE + } + 100 -> { + end() + DrillDemonUtils.cleanup(player!!) + DrillDemonUtils.reward(player!!) } } } diff --git a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt index 36d8cb9c5..f767b0554 100644 --- a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt +++ b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienNPC.kt @@ -1,26 +1,38 @@ package content.global.ame.events.drilldemon import core.game.node.entity.npc.NPC -import core.tools.RandomFunction import org.rs09.consts.NPCs import content.global.ame.RandomEventNPC +import core.api.* import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.system.timer.impl.AntiMacro +import core.tools.secondsToTicks + class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) { override fun init() { super.init() sendChat(player.username.capitalize() + "! Drop and give me 20!") - } - - override fun tick() { - super.tick() - if(RandomFunction.random(1,10) == 5){ - sendChat(player.username.capitalize() + "! 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 -> { + openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } } } override fun talkTo(npc: NPC) { - player.dialogueInterpreter.open(SeargentDamienDialogue(),npc) + openDialogue(player, SeargentDamienDialogue(), npc) } } \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt new file mode 100644 index 000000000..c52c17e2d --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt @@ -0,0 +1,22 @@ +package content.global.ame.events.drilldemon + +import core.api.inBorders +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class SeargentDamienBehavior: NPCBehavior(NPCs.SERGEANT_DAMIEN_2790) { + + override fun onCreation(self: NPC) { + + // Sergeant Damien is supposed to walk around the perimeter of the exercise mats + if (inBorders(self, DrillDemonUtils.DD_AREA)) { + val movementPath = arrayOf(Location.create(3167, 4822, 0), Location.create(3167, 4818, 0), Location.create(3159, 4818, 0), Location.create(3159, 4822, 0)) + self.configureMovementPath(*movementPath) + self.isWalks = true + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt index 6f39535ae..ce67a8fc4 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt @@ -5,17 +5,21 @@ import core.api.* import core.game.dialogue.DialogueFile import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills import core.tools.END_DIALOGUE import org.rs09.consts.Items import org.rs09.consts.NPCs -class EvilBobDialogue : DialogueFile() { +class EvilBobDialogue(val rewardDialogue: Boolean = false, val rewardXpSkill: Int = Skills.FISHING) : 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)) { + if (rewardDialogue) { + sendPlayerDialogue(player!!, "That was the strangest dream I've ever had! Assuming it was a dream...", FacialExpression.HALF_ASKING) + stage = if (rewardXpSkill == Skills.FISHING) 900 else 901 + } else 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) @@ -104,6 +108,8 @@ class EvilBobDialogue : DialogueFile() { 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 } + 900 -> sendDialogue(player!!, "You feel somehow that you've become better at fishing.").also { stage = END_DIALOGUE } + 901 -> sendDialogue(player!!, "You feel somehow that you've become better at magic.").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 index cefd4e729..67d085368 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt @@ -4,8 +4,10 @@ import core.api.* import core.game.dialogue.FacialExpression import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength import core.game.node.entity.Entity import core.game.node.entity.player.link.emote.Emotes +import core.game.node.entity.skill.Skills import core.game.system.task.Pulse import core.game.world.map.Location import core.game.world.map.zone.ZoneBorders @@ -98,35 +100,35 @@ class EvilBobListeners : InteractionListener, MapArea { 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) - } + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + forceMove(player, player.location, portal.location, 0, 50, null, 819) + return@queueScript delayScript(player, 3) } - return false + 1 -> { + player.faceLocation(Location.create(3421, 4777, 0)) + emote(player, Emotes.RASPBERRY) + sendChat(player, "Be seeing you!") + return@queueScript delayScript(player,2) + } + 2 -> { + animate(player, EvilBobUtils.teleAnim) + player.graphics(EvilBobUtils.telegfx) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 2) + } + 3 -> { + sendMessage(player, "Welcome back to 2009Scape.") + teleport(player, getAttribute(player, EvilBobUtils.prevLocation, Location.create(3222, 3219, 0))) + EvilBobUtils.reward(player) + EvilBobUtils.cleanup(player) + resetAnimator(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) } - }) + } } else sendNPCDialogue(player, NPCs.EVIL_BOB_2479, "You're going nowhere, human!", FacialExpression.CHILD_NEUTRAL) return@on true } diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt index f8e778f96..fc0fe2826 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt @@ -3,6 +3,7 @@ package content.global.ame.events.evilbob import content.global.ame.RandomEventNPC 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 org.rs09.consts.NPCs @@ -13,24 +14,31 @@ class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(N 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) - AntiMacro.terminateEventNpc(player) + 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) + 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) } } } override fun talkTo(npc: NPC) { - player.dialogueInterpreter.open(EvilBobDialogue(), this.asNpc()) + openDialogue(player, 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 index 40f0027b9..9d5f4957d 100644 --- a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt @@ -77,16 +77,16 @@ object EvilBobUtils { 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.") } + openDialogue(player, EvilBobDialogue(rewardDialogue = true, rewardXpSkill = Skills.FISHING), NPCs.EVIL_BOB_2479) } 1 -> { player.skills.addExperience(Skills.MAGIC, experience) - runTask(player, 8) { sendDialogue(player, "You feel somehow that you've become better at magic.") } + openDialogue(player, EvilBobDialogue(rewardDialogue = true, rewardXpSkill = Skills.MAGIC), NPCs.EVIL_BOB_2479) } } } else { player.skills.addExperience(Skills.FISHING, experience) - runTask(player, 6) { sendDialogue(player, "You feel somehow that you've become better at fishing.") } + openDialogue(player, EvilBobDialogue(rewardDialogue = true, rewardXpSkill = Skills.FISHING), NPCs.EVIL_BOB_2479) } } } \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt index fe5fc7cf1..e2d36acc0 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt @@ -17,9 +17,13 @@ class FreakListeners : InteractionListener, MapArea { private val freakNpc = NPCs.FREAKY_FORESTER_2458 private val pheasants = intArrayOf(NPCs.PHEASANT_2459,NPCs.PHEASANT_2460,NPCs.PHEASANT_2461,NPCs.PHEASANT_2462) override fun defineListeners() { - on(freakNpc,IntType.NPC,"talk-to"){player, node -> - if (getAttribute(player, FreakUtils.freakTask, -1) == -1) FreakUtils.giveFreakTask(player) - openDialogue(player, FreakyForesterDialogue(), node.asNpc()) + on(freakNpc,IntType.NPC,"talk-to") { player, node -> + if (inBorders(player, FreakUtils.freakArea)) { + if (getAttribute(player, FreakUtils.freakTask, -1) == -1) FreakUtils.giveFreakTask(player) + openDialogue(player, FreakyForesterDialogue(), node.asNpc()) + } else { + sendMessage(player, "They aren't interested in talking to you.") + } return@on true } @@ -49,7 +53,7 @@ class FreakListeners : InteractionListener, MapArea { } } override fun defineAreaBorders(): Array { - return arrayOf(ZoneBorders(2587, 4758, 2616,4788)) + return arrayOf(FreakUtils.freakArea) } override fun getRestrictions(): Array { diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt index bac46f78f..cd76dc23d 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt @@ -5,6 +5,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import core.game.node.entity.player.Player import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders import core.tools.RandomFunction object FreakUtils{ @@ -13,6 +14,7 @@ object FreakUtils{ const val freakTask = "/save:freakyf:task" const val freakComplete = "/save:freakyf:complete" const val pheasantKilled = "freakyf:killed" + val freakArea = ZoneBorders(2587, 4758, 2616, 4788) fun giveFreakTask(player: Player) { when(RandomFunction.getRandom(4)) { 0 -> setAttribute(player, freakTask, NPCs.PHEASANT_2459) diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt index 5661c0d7c..4b0366263 100644 --- a/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt @@ -4,8 +4,8 @@ import content.global.ame.RandomEventNPC 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.task.Pulse import core.game.system.timer.impl.AntiMacro import core.game.world.update.flag.context.Graphics import org.rs09.consts.Sounds @@ -14,28 +14,27 @@ class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEve override fun init() { super.init() - lock(player, 8) - submitWorldPulse(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 0 -> sendChat("Ah, ${player.username}, just the person I need!") - 4 -> { - sendGraphics(Graphics(308, 100, 50), player.location) - animate(player,714) - playAudio(player, Sounds.TELEPORT_ALL_200) - } - 7 -> { - FreakUtils.teleport(player) - FreakUtils.giveFreakTask(player) - AntiMacro.terminateEventNpc(player) - openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc) - resetAnimator(player) - } + 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) } - return false + 1 -> { + FreakUtils.teleport(player) + FreakUtils.giveFreakTask(player) + AntiMacro.terminateEventNpc(player) + openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc) + resetAnimator(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) } - }) + } } override fun talkTo(npc: NPC) { diff --git a/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt b/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt index 919f2e0b0..4022eb26d 100644 --- a/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt +++ b/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt @@ -4,14 +4,17 @@ import core.api.* import core.game.dialogue.FacialExpression import core.game.dialogue.DialogueFile import core.game.system.timer.impl.AntiMacro -import core.tools.END_DIALOGUE +import org.rs09.consts.Items -class GenieDialogue : DialogueFile() { +class GenieDialogue() : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { - val assigned = player!!.getAttribute("genie:item",0) - npcl(FacialExpression.NEUTRAL, "Ah, so you are there, ${player!!.name.capitalize()}. I'm so glad you summoned me. Please take this lamp and make your wish.") - addItemOrDrop(player!!, assigned) - AntiMacro.terminateEventNpc(player!!) - stage = END_DIALOGUE + when (stage) { + 0 -> npcl(FacialExpression.NEUTRAL, "Ah, so you are there, ${player!!.name.capitalize()}. I'm so glad you summoned me. Please take this lamp and make your wish."). also { stage++ } + 1 -> { + end() + addItemOrDrop(player!!, Items.LAMP_2528) + AntiMacro.terminateEventNpc(player!!) + } + } } } \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/genie/GenieNPC.kt b/Server/src/main/content/global/ame/events/genie/GenieNPC.kt index 1f1f270e8..ef69fe786 100644 --- a/Server/src/main/content/global/ame/events/genie/GenieNPC.kt +++ b/Server/src/main/content/global/ame/events/genie/GenieNPC.kt @@ -2,15 +2,14 @@ package content.global.ame.events.genie import core.game.node.entity.npc.NPC import core.tools.RandomFunction -import org.rs09.consts.Items import org.rs09.consts.NPCs import content.global.ame.RandomEventNPC +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!") - var assigned_item = 0 - val items = arrayOf(Items.LAMP_2528) override fun tick() { if(RandomFunction.random(1,15) == 5){ @@ -21,15 +20,10 @@ class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPC override fun init() { super.init() - assignItem() + playAudio(player, Sounds.GENIE_APPEAR_2301) sendChat(phrases.random().replace("@name",player.name.capitalize())) } - fun assignItem(){ - assigned_item = items.random() - player.setAttribute("genie:item",assigned_item) - } - override fun talkTo(npc: NPC) { player.dialogueInterpreter.open(GenieDialogue(),npc) } diff --git a/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt b/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt index 1bc33d344..a6812f692 100644 --- a/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt +++ b/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt @@ -32,7 +32,7 @@ class NPCTalkListener : InteractionListener { on(IntType.NPC,"talk-to","talk","talk to"){ player, node -> val npc = node.asNpc() if(RandomEvents.randomIDs.contains(node.id)){ - if(AntiMacro.getEventNpc(player) == null || AntiMacro.getEventNpc(player) != node.asNpc()){ + 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.") } else { AntiMacro.getEventNpc(player)?.talkTo(node.asNpc()) diff --git a/Server/src/main/core/game/system/command/sets/FunCommandSet.kt b/Server/src/main/core/game/system/command/sets/FunCommandSet.kt index 42170e356..cdacf2c1f 100644 --- a/Server/src/main/core/game/system/command/sets/FunCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/FunCommandSet.kt @@ -1,27 +1,30 @@ package core.game.system.command.sets -import core.api.* +import content.global.handlers.item.SpadeDigListener import content.region.misc.tutisland.handlers.iface.CharacterDesign +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.combat.ImpactHandler import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player -import core.game.system.task.Pulse -import core.game.world.map.Location -import core.game.world.map.RegionManager -import core.game.world.update.flag.context.Animation -import core.plugin.Initializable -import org.json.simple.JSONObject -import core.game.dialogue.DialogueFile -import content.global.handlers.item.SpadeDigListener import core.game.node.entity.player.info.login.PlayerSaver import core.game.system.command.Privilege +import core.game.system.task.Pulse import core.game.world.GameWorld -import core.game.world.repository.Repository +import core.game.world.map.Location +import core.game.world.map.RegionManager import core.game.world.repository.Repository.getPlayerByName +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.json.simple.JSONObject +import org.rs09.consts.Sounds import java.awt.HeadlessException import java.awt.Toolkit import java.awt.datatransfer.StringSelection -import java.util.* +import kotlin.streams.toList @Initializable class FunCommandSet : CommandSet(Privilege.ADMIN) { @@ -186,6 +189,24 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) { CharacterDesign.reopen(player) } + /** + * Cast a weakened version of ice barrage on nearby players within the defined radius. + * This spell will never kill or freeze a player + */ + define("barrage", Privilege.ADMIN, "::barrage radius ", "Cast a weak barrage on all nearby players. Will never kill players") { player, args -> + if (args.size != 2) + reject(player, "Usage: ::barrage radius[max = 50]") + val radius = if (args[1].toInt() > 50) 50 else args[1].toInt() + val nearbyPlayers = RegionManager.getLocalPlayers(player, radius).stream().filter { p: Player -> p.username != player.username }.toList() + animate(player, 1978) + playGlobalAudio(player.location, Sounds.ICE_CAST_171) + for (p in nearbyPlayers) { + playGlobalAudio(p.location, Sounds.ICE_BARRAGE_IMPACT_168, 20) + val impactAmount = if (p.skills.lifepoints < 10 ) 0 else RandomFunction.getRandom(3) + impact(p, impactAmount, ImpactHandler.HitsplatType.NORMAL) + p.graphics(Graphics(369, 0)) + } + } } fun bury(player: Player){ diff --git a/Server/src/main/core/game/system/timer/impl/AntiMacro.kt b/Server/src/main/core/game/system/timer/impl/AntiMacro.kt index c5ce00636..f6cd3b280 100644 --- a/Server/src/main/core/game/system/timer/impl/AntiMacro.kt +++ b/Server/src/main/core/game/system/timer/impl/AntiMacro.kt @@ -5,6 +5,7 @@ import content.global.ame.RandomEvents import core.api.* import core.game.node.entity.Entity import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights import core.game.node.item.Item import core.game.system.command.Privilege import core.game.system.timer.PersistTimer @@ -39,6 +40,9 @@ class AntiMacro : PersistTimer(0, "antimacro", isAuto = true), Commands { override fun onRegister(entity: Entity) { if (entity !is Player || entity.isArtificial) entity.timers.removeTimer(this) + if (entity is Player && entity.rights == Rights.ADMINISTRATOR) { + pause(entity) + } if (runInterval == 0) setNextExecution()