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()