From 9989ee9905dbd1106c0d770d997415eddc7c731f Mon Sep 17 00:00:00 2001 From: bushtail Date: Thu, 12 Oct 2023 01:43:43 +0000 Subject: [PATCH] Rewrote Stat Spy Refactored lunar spell handlers --- .../global/skill/magic/lunar/LunarData.kt | 50 +- .../skill/magic/lunar/LunarListeners.kt | 687 ++++++++++-------- .../skill/magic/lunar/StatSpySpell.java | 100 --- Server/src/main/core/api/ContentAPI.kt | 9 + 4 files changed, 441 insertions(+), 405 deletions(-) delete mode 100644 Server/src/main/content/global/skill/magic/lunar/StatSpySpell.java diff --git a/Server/src/main/content/global/skill/magic/lunar/LunarData.kt b/Server/src/main/content/global/skill/magic/lunar/LunarData.kt index 1d8c2522d..9a1b28f6c 100644 --- a/Server/src/main/content/global/skill/magic/lunar/LunarData.kt +++ b/Server/src/main/content/global/skill/magic/lunar/LunarData.kt @@ -1,8 +1,13 @@ package content.global.skill.magic.lunar -import core.api.* +import core.api.addItemOrDrop +import core.api.freeSlots +import core.api.removeItem +import core.api.sendMessage import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item import org.rs09.consts.Items private val HunterKitContents = intArrayOf( @@ -85,3 +90,46 @@ enum class HumidifyItems(val empty: Int, val full: Int) { } } +enum class PlankType (val log: Item, val plank: Item, val price: Int) { + WOOD(Item(1511), Item(960), 70), + OAK(Item(1521), Item(8778), 175), + TEAK(Item(6333), Item(8780), 350), + MAHOGANY(Item(6332), Item(8782), 1050); + companion object { + fun getForLog(item: Item): PlankType? { + for (plankType in values()) { + if (plankType.log.id == item.id) { + return plankType + } + } + return null + } + } +} + +val statSpySkills = arrayOf( + intArrayOf(Skills.ATTACK, 1, 2), + intArrayOf(Skills.HITPOINTS, 5, 6), + intArrayOf(Skills.MINING, 9, 10), + intArrayOf(Skills.STRENGTH, 13, 14), + intArrayOf(Skills.AGILITY, 17, 18), + intArrayOf(Skills.SMITHING, 21, 22), + intArrayOf(Skills.DEFENCE, 25, 26), + intArrayOf(Skills.HERBLORE, 29, 30), + intArrayOf(Skills.FISHING, 33, 34), + intArrayOf(Skills.RANGE, 37, 38), + intArrayOf(Skills.THIEVING, 41, 42), + intArrayOf(Skills.COOKING, 45, 46), + intArrayOf(Skills.PRAYER, 49, 50), + intArrayOf(Skills.CRAFTING, 53, 54), + intArrayOf(Skills.FIREMAKING, 57, 58), + intArrayOf(Skills.MAGIC, 61, 62), + intArrayOf(Skills.FLETCHING, 65, 66), + intArrayOf(Skills.WOODCUTTING, 69, 70), + intArrayOf(Skills.RUNECRAFTING, 73, 74), + intArrayOf(Skills.SLAYER, 77, 78), + intArrayOf(Skills.FARMING, 81, 82), + intArrayOf(Skills.CONSTRUCTION, 85, 86), + intArrayOf(Skills.HUNTER, 89, 90), + intArrayOf(Skills.SUMMONING, 93, 94) +) \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt index 5999c6207..d6da6f78b 100644 --- a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt +++ b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt @@ -7,6 +7,7 @@ import content.global.skill.farming.FarmingPatch import content.global.skill.magic.SpellListener import content.global.skill.magic.spellconsts.Lunar import core.api.* +import core.game.component.CloseEvent import core.game.component.Component import core.game.node.Node import core.game.node.entity.combat.ImpactHandler @@ -52,23 +53,18 @@ class LunarListeners : SpellListener("lunar"), Commands { // Level 66 onCast(Lunar.MONSTER_EXAMINE, NPC) { player, node -> requires(player,66, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.MIND_RUNE_558), Item(Items.COSMIC_RUNE_564))) - examineMonster(player,node!!.asNpc()) + monsterExamine(player,node!!.asNpc()) } // Level 67 onCast(Lunar.NPC_CONTACT, NONE) { player, _ -> requires(player,67, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.COSMIC_RUNE_564), Item(Items.AIR_RUNE_556,2))) - player.interfaceManager.open(Component(429)) - player.setAttribute("contact-caller"){ - removeRunes(player) - addXP(player,63.0) - setDelay(player,false) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_NPC_CONTACT_4413, Graphics.LUNAR_SPELLBOOK_NPC_CONTACT_728, 130,3618) - } + npcContact(player) } // Level 68 onCast(Lunar.CURE_OTHER, PLAYER) { player, node -> + requires(player, 68, arrayOf(Item(Items.ASTRAL_RUNE_9075, 1), Item(Items.LAW_RUNE_563), Item(Items.EARTH_RUNE_557, 10))) node?.let { cureOther(player, node) } } @@ -80,9 +76,9 @@ class LunarListeners : SpellListener("lunar"), Commands { // Level 69 onCast(Lunar.MOONCLAN_TELEPORT, NONE) { player, _ -> - requires(player,69, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,2))) + requires(player, 69, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,2))) if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) - sendTeleport(player,66.0, Location.create(2111, 3916, 0)) + sendTeleport(player, 66.0, Location.create(2111, 3916, 0)) } // Level 70 @@ -94,22 +90,20 @@ class LunarListeners : SpellListener("lunar"), Commands { // Level 71 onCast(Lunar.OURANIA_TELEPORT, NONE) { player, _ -> - requires( - player, - 71, - arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.EARTH_RUNE_557, 6)) - ) + requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.EARTH_RUNE_557, 6))) if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) sendTeleport(player, 69.0, Location.create(2469, 3247, 0)) } // Level 71 onCast(Lunar.CURE_ME, NONE) { player, _ -> + requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.COSMIC_RUNE_564, 2))) cureMe(player) } // Level 71 onCast(Lunar.HUNTER_KIT, NONE) { player, _ -> + requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 2))) if(freeSlots(player) == 0) sendMessage(player, "Not enough inventory space!").also { return@onCast } hunterKit(player) } @@ -130,13 +124,15 @@ class LunarListeners : SpellListener("lunar"), Commands { // Level 74 onCast(Lunar.CURE_GROUP, NONE) { player, _ -> + requires(player, 74, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 2), Item(Items.COSMIC_RUNE_564, 2))) cureGroup(player) } // Level 75 - /** - * Stat Spy - */ + onCast(Lunar.STAT_SPY, PLAYER) { player, node -> + requires(player, 75, arrayOf(Item(Items.COSMIC_RUNE_564, 2), Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.BODY_RUNE_559, 5))) + node?.let { statSpy(player, node) } + } // Level 75 onCast(Lunar.BARBARIAN_TELEPORT, NONE) { player, _ -> @@ -195,6 +191,7 @@ class LunarListeners : SpellListener("lunar"), Commands { // Level 83 onCast(Lunar.FERTILE_SOIL, OBJECT) { player, node -> + requires(player, 83, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.NATURE_RUNE_561, 2), Item(Items.EARTH_RUNE_557, 15))) node?.let { fertileSoil(player, node.asScenery()) } } @@ -253,6 +250,7 @@ class LunarListeners : SpellListener("lunar"), Commands { // Level 91 onCast(Lunar.ENERGY_TRANSFER, PLAYER) { player, node -> + requires(player, 91, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.LAW_RUNE_563, 2), Item(Items.NATURE_RUNE_561, 1))) node?.let { energyTransfer(player, node) } } @@ -282,135 +280,8 @@ class LunarListeners : SpellListener("lunar"), Commands { */ } - // Lunar spellbook-related debug commands - override fun defineCommands() { - define("poison", privilege = Privilege.ADMIN) { player, strings -> - if(strings.size == 3) { - var dmg = strings[2].toIntOrNull() - val p = Repository.getPlayerByName(strings[1]) - if(p == null) { - sendMessage(player, "Player ${strings[1]} does not exist.") - return@define - } - if(dmg != null) { - p?.let { applyPoison(it, it, dmg) } - } else { - sendMessage(player, "Damage must be an integer. Format:") - sendMessage(player, "::poison username damage") - } - } else { - sendMessage(player, "Invalid arguments provided. Format:") - sendMessage(player, "::poison username damage") - } - } - define("humidifykit", privilege = Privilege.ADMIN) { player, _ -> - if(freeSlots(player) < 24) { - sendMessage(player, "Not enough free space.") - return@define - } else { - addItem(player, Items.ASTRAL_RUNE_9075, 100) - addItem(player, Items.WATER_RUNE_555, 300) - addItem(player, Items.FIRE_RUNE_554, 100) - for(item in HumidifyItems.values()) { - addItem(player, item.empty) - } - } - } - } - private fun plankMake(player: Player, item: Item) { - - val plankType = PlankType.getForLog(item) - if (plankType == null) { - sendMessage(player, "You need to use this spell on logs.") - return - } - if (amountInInventory(player, Items.COINS_995) < plankType.price || !removeItem(player, Item(Items.COINS_995, plankType.price))) { - sendMessage(player, "You need ${plankType.price} coins to convert that log into a plank.") - return - } - lock(player, 3) - setDelay(player, false) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_PLANK_MAKE_6298, Graphics.LUNAR_SPELLBOOK_PLANK_MAKE_1063, 120, Sounds.LUNAR_MAKE_PLANK_3617) - removeRunes(player) - replaceSlot(player, item.slot, plankType.plank) - addXP(player, 90.0) - showMagicTab(player) - } - - enum class PlankType (val log: Item, val plank: Item, val price: Int) { - WOOD(Item(1511), Item(960), 70), - OAK(Item(1521), Item(8778), 175), - TEAK(Item(6333), Item(8780), 350), - MAHOGANY(Item(6332), Item(8782), 1050); - companion object { - fun getForLog(item: Item): PlankType? { - for (plankType in values()) { - if (plankType.log.id == item.id) { - return plankType - } - } - return null - } - } - } - - fun curePlant(player: Player, obj: Scenery){ - val fPatch = FarmingPatch.forObject(obj) - if(fPatch == null){ - player.sendMessage("You attempt to cast Cure Plant on ${obj.definition.name}!") - player.sendMessage("Nothing interesting happens.") - return - } - val patch = fPatch.getPatchFor(player) - if(!patch.isDiseased && !patch.isWeedy()){ - player.sendMessage("It is growing just fine.") - return - } - if(patch.isWeedy()){ - player.sendMessage("The weeds are healthy enough already.") - return - } - if(patch.isDead){ - player.sendMessage("It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.") - return - } - if(patch.isGrown()){ - player.sendMessage("That's not diseased.") - return - } - - patch.cureDisease() - removeRunes(player) - addXP(player,60.0) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_PLANT_4409, Graphics.LUNAR_SPELLBOOK_CURE_PLANT_748, 100, Sounds.LUNAR_CURE_GROUP_2882) - setDelay(player,false) - } - - private fun examineMonster(player: Player, npc: NPC){ - if(!npc.location.withinDistance(player.location)){ - player.sendMessage("You must get closer to use this spell.") - return - } - - player.faceLocation(npc.location) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293, Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, soundID = Sounds.LUNAR_STAT_SPY_3620) - removeRunes(player) - addXP(player,66.0) - setDelay(player,false) - - player.interfaceManager.openSingleTab(Component(Components.DREAM_MONSTER_STAT_522)) - player.packetDispatch.sendString("Monster name : " + npc.definition.name,Components.DREAM_MONSTER_STAT_522,0) - player.packetDispatch.sendString("Combat Level : ${npc.definition.combatLevel}",Components.DREAM_MONSTER_STAT_522,1) - player.packetDispatch.sendString("Hitpoints : ${npc.definition.handlers.get(NPCConfigParser.LIFEPOINTS) ?: 0}",Components.DREAM_MONSTER_STAT_522,2) - player.packetDispatch.sendString("Max hit : ${npc.getSwingHandler(false).calculateHit(npc,player,1.0)}",Components.DREAM_MONSTER_STAT_522,3) - - val poisonStatus = if(npc.definition.handlers.getOrDefault(NPCConfigParser.POISON_IMMUNE,false) == true){ - "This creature is immune to poison." - } else "This creature is not immune to poison." - - player.packetDispatch.sendString(poisonStatus,Components.DREAM_MONSTER_STAT_522,4) - } - + // Spell handlers + // Level 65 private fun bakePie(player: Player){ val playerPies = ArrayList() @@ -431,12 +302,13 @@ class LunarListeners : SpellListener("lunar"), Commands { var counter = 0 override fun pulse(): Boolean { if(playerPies.isEmpty()) return true - if(counter == 0) delay = Animation(Animations.LUNAR_SPELLBOOK_BAKE_PIE_4413).definition.durationTicks + 1 + + if(counter == 0) delay = animationDuration(Animation(Animations.LUNAR_SPELLBOOK_BAKE_PIE_4413)) + 1 val item = playerPies[0] val pie = CookableItems.forId(item.id) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_BAKE_PIE_4413, Graphics.LUNAR_SPELLBOOK_BAKE_PIE_746, 75, Sounds.LUNAR_BAKE_PIE_2879) addXP(player,60.0) - player.skills.addExperience(Skills.COOKING,pie.experience) + player.skills.addExperience(Skills.COOKING, pie.experience) setDelay(player,false) player.inventory.remove(item) player.inventory.add(Item(pie.cooked)) @@ -447,63 +319,212 @@ class LunarListeners : SpellListener("lunar"), Commands { }) } - private fun sendTeleport(player: Player, xp: Double, loc: Location){ - if(player.teleporter.send(loc,TeleportManager.TeleportType.LUNAR)) { - addXP(player, xp) + // Level 66 + fun curePlant(player: Player, obj: Scenery){ + val fPatch = FarmingPatch.forObject(obj) + if(fPatch == null){ + sendMessage(player, "You attempt to cast Cure Plant on ${obj.definition.name}!") + sendMessage(player, "Nothing interesting happens.") + return + } + val patch = fPatch.getPatchFor(player) + if(!patch.isDiseased && !patch.isWeedy()){ + sendMessage(player, "It is growing just fine.") + return + } + if(patch.isWeedy()){ + sendMessage(player, "The weeds are healthy enough already.") + return + } + if(patch.isDead){ + sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.") + return + } + if(patch.isGrown()){ + sendMessage(player, "That's not diseased.") + return + } + patch.cureDisease() + removeRunes(player) + addXP(player,60.0) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_PLANT_4409, Graphics.LUNAR_SPELLBOOK_CURE_PLANT_748, 100, Sounds.LUNAR_CURE_GROUP_2882) + setDelay(player,false) + } + + // Level 66 + private fun monsterExamine(player: Player, npc: NPC){ + if(!npc.location.withinDistance(player.location)){ + sendMessage(player, "You must get closer to use this spell.") + return + } + face(player, npc) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293, Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, soundID = Sounds.LUNAR_STAT_SPY_3620) + removeRunes(player) + addXP(player,66.0) + + setDelay(player, false) + openSingleTab(player, Components.DREAM_MONSTER_STAT_522) + setInterfaceText(player, "Monster name : ${npc.definition.name}", Components.DREAM_MONSTER_STAT_522, 0) + setInterfaceText(player, "Combat Level : ${npc.definition.combatLevel}", Components.DREAM_MONSTER_STAT_522, 1) + setInterfaceText(player, "Hitpoints : ${npc.definition.handlers[NPCConfigParser.LIFEPOINTS] ?: 0}", Components.DREAM_MONSTER_STAT_522, 2) + setInterfaceText(player, "Max hit : ${npc.getSwingHandler(false).calculateHit(npc, player, 1.0)}", Components.DREAM_MONSTER_STAT_522, 3) + + val poisonStatus = if(npc.definition.handlers.getOrDefault(NPCConfigParser.POISON_IMMUNE,false) == true){ + "This creature is immune to poison." + } else "This creature is not immune to poison." + + setInterfaceText(player, poisonStatus, Components.DREAM_MONSTER_STAT_522, 4) + } + + // Level 67 + private fun npcContact(player: Player) { + openInterface(player, 429) + setAttribute(player, "contact-caller") { removeRunes(player) - setDelay(player, true) + addXP(player,63.0) + setDelay(player,false) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_NPC_CONTACT_4413, Graphics.LUNAR_SPELLBOOK_NPC_CONTACT_728, 130,3618) } } - private fun sendGroupTeleport(player: Player, xp: Double, destName: String, loc: Location){ - RegionManager.getLocalPlayers(player,1).forEach { - if(it == player) return@forEach - if(it.isTeleBlocked) return@forEach - if(!it.isActive) return@forEach - if(!it.settings.isAcceptAid) return@forEach - if(it.ironmanManager.isIronman) return@forEach - it.setAttribute("t-o_location",loc) - it.interfaceManager.open(Component(Components.TELEPORT_OTHER_326)) - it.packetDispatch.sendString(player.username,Components.TELEPORT_OTHER_326,1) - it.packetDispatch.sendString(destName,Components.TELEPORT_OTHER_326,3) + // Level 68 + private fun cureOther(player: Player, target: Node) { + if(!isPlayer(target)) { + sendMessage(player, "You can only cast this spell on other players.") + return } - sendTeleport(player,xp,loc) + val p = target.asPlayer() + if(!p.isActive || p.locks.isInteractionLocked) { + sendMessage(player, "This player is busy.") + return + } + if(!p.settings.isAcceptAid) { + sendMessage(player, "This player is not accepting any aid.") + return + } + if(!isPoisoned(p)) { + sendMessage(player, "This player is not poisoned.") + return + } + player.face(p) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_OTHER_4411, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_2886) + visualizeSpell(p, -1, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889) + removeRunes(player, true) + curePoison(p) + sendMessage(p, "You have been cured of poison.") + addXP(player, 65.0) } - private fun stringJewellery(player: Player) { - val playerJewellery = ArrayDeque() + // Level 68 + private fun humidify(player: Player) { + val playerEmpties = ArrayDeque() for(item in player.inventory.toArray()) { if(item == null) continue - if(!StringJewelleryItems.unstrungContains(item.id)) continue - playerJewellery.add(item) + if(!HumidifyItems.emptyContains(item.id)) continue + playerEmpties.add(item) } - player.pulseManager.run(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - removeAttribute(player, "spell:runes") - if (playerJewellery.isEmpty()) - return true - requires(player, 80, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 10), Item(Items.WATER_RUNE_555, 5))) - if(counter == 0) delay = animationDuration(Animation(Animations.LUNAR_SPELLBOOK_STRING_JEWELLERY_4412)) + 1 - val item = playerJewellery[0] - val strung = StringJewelleryItems.forId(item.id) - setDelay(player,false) - if(removeItem(player, item) && addItem(player, strung)) { - removeRunes(player, true) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STRING_JEWELLERY_4412, Graphics.LUNAR_SPELLBOOK_STRING_JEWELLERY_730, 100, Sounds.LUNAR_STRING_AMULET_2903) - rewardXP(player, Skills.CRAFTING, 4.0) - addXP(player, 83.0) - playerJewellery.remove(item) - if(playerJewellery.isNotEmpty()) removeRunes(player,false) else removeRunes(player,true) - } - counter++ - return playerJewellery.isEmpty() - } - }) + if(playerEmpties.isEmpty()) { + sendMessage(player, "You have nothing in your inventory that this spell can humidify.") + return + } + + removeRunes(player) + delayEntity(player, Animation(Animations.LUNAR_SPELLBOOK_HUMIDIFY_6294).duration) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_HUMIDIFY_6294, Graphics.LUNAR_SPELLBOOK_HUMIDIFY_1061, 20, Sounds.LUNAR_HUMIDIFY_3614) + for(item in playerEmpties) { + val filled = HumidifyItems.forId(item.id) + removeItem(player, item.id) && addItem(player, filled) + } + addXP(player, 65.0) + /** + queueScript(player) { + return@queueScript stopExecuting(player) + } + */ } + // Level 71 + private fun cureMe(player: Player) { + if(!isPoisoned(player)) { + sendMessage(player, "You are not poisoned.") + return + } + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_ME_4411, Graphics.LUNAR_SPELLBOOK_CURE_ME_742, 90, Sounds.LUNAR_CURE_2884) + curePoison(player) + addXP(player, 69.0) + playAudio(player, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2900) + sendMessage(player, "You have been cured of poison.") + } + + // Level 71 + private fun hunterKit(player: Player) { + removeRunes(player, true) + if(addItem(player, Items.HUNTER_KIT_11159)) { + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_HUNTER_KIT_6303, Graphics.LUNAR_SPELLBOOK_HUNTER_KIT_1074, soundID = Sounds.LUNAR_HUNTER_KIT_3615) + addXP(player, 70.0) + setDelay(player, 2) + } + } + + // Level 74 + private fun cureGroup(player: Player) { + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_GROUP_4409, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_GROUP_2882) + curePoison(player) + for(acct in RegionManager.getLocalPlayers(player, 1)) { + if(!acct.isActive || acct.locks.isInteractionLocked) { + continue + } + if(!acct.settings.isAcceptAid) { + continue + } + curePoison(acct) + sendMessage(acct, "You have been cured of poison.") + visualizeSpell(acct, -1, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889) + } + addXP(player, 74.0) + } + + // Level 75 + private fun statSpy(player: Player, target: Node) { + if(target !is Player) { + sendMessage(player, "You can only cast this spell on players.") + return + } + val stat = Components.DREAM_PLAYER_STATS_523 + val statCloseEvent = CloseEvent { p, _ -> + p.interfaceManager.restoreTabs() + return@CloseEvent true + } + + removeRunes(player, true) + + face(player, target) + animate(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293) + playAudio(player, Sounds.LUNAR_STAT_SPY_3620) + + rewardXP(player, Skills.MAGIC, 76.0) + + Component(stat).setCloseEvent(statCloseEvent) + + sendGraphics(Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, player.location) + sendGraphics(Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_MONSTER_734, target.location) + + playGlobalAudio(target.location, Sounds.LUNAR_STAT_SPY_IMPACT_3621) + + for(element in statSpySkills) { + setInterfaceText(player, "${ getDynLevel(target, element[0]) }", Components.DREAM_PLAYER_STATS_523, element[1]) + setInterfaceText(player, "${ getStatLevel(target, element[0]) }", Components.DREAM_PLAYER_STATS_523, element[2]) + } + + setInterfaceText(player, target.username, Components.DREAM_PLAYER_STATS_523, 99) + openSingleTab(player, stat) + } + + // Level 77 private fun superglassMake(player: Player) { val GLASS_WEEDS = hashSetOf(Items.SODA_ASH_1781, Items.SEAWEED_401, Items.SWAMP_WEED_10978) val inv = player.inventory.toArray() @@ -546,6 +567,56 @@ class LunarListeners : SpellListener("lunar"), Commands { } } + // Level 79 + /** + * Dream + */ + + private fun stringJewellery(player: Player) { + val playerJewellery = ArrayDeque() + + for(item in player.inventory.toArray()) { + if(item == null) continue + if(!StringJewelleryItems.unstrungContains(item.id)) continue + playerJewellery.add(item) + } + + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + removeAttribute(player, "spell:runes") + if (playerJewellery.isEmpty()) + return true + requires(player, 80, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 10), Item(Items.WATER_RUNE_555, 5))) + if(counter == 0) delay = animationDuration(Animation(Animations.LUNAR_SPELLBOOK_STRING_JEWELLERY_4412)) + 1 + val item = playerJewellery[0] + val strung = StringJewelleryItems.forId(item.id) + setDelay(player,false) + if(removeItem(player, item) && addItem(player, strung)) { + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STRING_JEWELLERY_4412, Graphics.LUNAR_SPELLBOOK_STRING_JEWELLERY_730, 100, Sounds.LUNAR_STRING_AMULET_2903) + rewardXP(player, Skills.CRAFTING, 4.0) + addXP(player, 83.0) + playerJewellery.remove(item) + if(playerJewellery.isNotEmpty()) removeRunes(player,false) else removeRunes(player,true) + } + counter++ + return playerJewellery.isEmpty() + } + }) + } + + // Level 81 + /** + * Stat Restore Pot Share + */ + + // Level 82 + /** + * Magic Imbue + */ + + // Level 83 private fun fertileSoil(player: Player, target: Scenery) { if (CompostBins.forObjectID(target.id) != null) { sendMessage(player, "No, that would be silly.") @@ -567,7 +638,6 @@ class LunarListeners : SpellListener("lunar"), Commands { sendMessage(player, "This patch has already been composted.") return } - requires(player, 83, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.NATURE_RUNE_561, 2), Item(Items.EARTH_RUNE_557, 15))) removeRunes(player, true) animate(player, Animations.LUNAR_SPELLBOOK_FERTILE_SOIL_4413) sendGraphics(Graphics.LUNAR_SPELLBOOK_FERTILE_SOIL_724, target.location) @@ -577,78 +647,43 @@ class LunarListeners : SpellListener("lunar"), Commands { addXP(player, 87.0) } - private fun cureMe(player: Player) { - if(!isPoisoned(player)) { - sendMessage(player, "You are not poisoned.") + // Level 84 + /** + * Boost Potion Share + */ + + // Level 86 + private fun plankMake(player: Player, item: Item) { + val plankType = PlankType.getForLog(item) + if (plankType == null) { + sendMessage(player, "You need to use this spell on logs.") return } - requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.COSMIC_RUNE_564, 2))) - removeRunes(player, true) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_ME_4411, Graphics.LUNAR_SPELLBOOK_CURE_ME_742, 90, Sounds.LUNAR_CURE_2884) - curePoison(player) - addXP(player, 69.0) - playAudio(player, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2900) - sendMessage(player, "You have been cured of poison.") - } - - private fun cureGroup(player: Player) { - requires(player, 74, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 2), Item(Items.COSMIC_RUNE_564, 2))) - removeRunes(player, true) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_GROUP_4409, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_GROUP_2882) - curePoison(player) - for(acct in RegionManager.getLocalPlayers(player, 1)) { - if(!acct.isActive || acct.locks.isInteractionLocked) { - continue - } - if(!acct.settings.isAcceptAid) { - continue - } - curePoison(acct) - sendMessage(acct, "You have been cured of poison.") - visualizeSpell(acct, -1, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889) - } - addXP(player, 74.0) - } - - private fun cureOther(player: Player, target: Node) { - if(!isPlayer(target)) { - sendMessage(player, "You can only cast this spell on other players.") - return - } - val p = target.asPlayer() - if(!p.isActive || p.locks.isInteractionLocked) { - sendMessage(player, "This player is busy.") - return - } - if(!p.settings.isAcceptAid) { - sendMessage(player, "This player is not accepting any aid.") - return - } - if(!isPoisoned(p)) { - sendMessage(player, "This player is not poisoned.") - return - } - requires(player, 68, arrayOf(Item(Items.ASTRAL_RUNE_9075, 1), Item(Items.LAW_RUNE_563), Item(Items.EARTH_RUNE_557, 10))) - player.face(p) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_OTHER_4411, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_2886) - visualizeSpell(p, -1, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889) - removeRunes(player, true) - curePoison(p) - sendMessage(p, "You have been cured of poison.") - addXP(player, 65.0) + if (amountInInventory(player, Items.COINS_995) < plankType.price || !removeItem(player, Item(Items.COINS_995, plankType.price))) { + sendMessage(player, "You need ${plankType.price} coins to convert that log into a plank.") + return + } + lock(player, 3) + setDelay(player, false) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_PLANK_MAKE_6298, Graphics.LUNAR_SPELLBOOK_PLANK_MAKE_1063, 120, Sounds.LUNAR_MAKE_PLANK_3617) + removeRunes(player) + replaceSlot(player, item.slot, plankType.plank) + addXP(player, 90.0) + showMagicTab(player) } + // Level 91 private fun energyTransfer(player: Player, target: Node) { if(!isPlayer(target)) { sendMessage(player, "You can only cast this spell on other players.") return } - val p = target.asPlayer() - if(!p.isActive || p.locks.isInteractionLocked) { + val targetPlayer = target.asPlayer() + if(!targetPlayer.isActive || targetPlayer.locks.isInteractionLocked) { sendMessage(player, "This player is busy.") return } - if(!p.settings.isAcceptAid) { + if(!targetPlayer.settings.isAcceptAid) { sendMessage(player, "This player is not accepting any aid.") return } @@ -656,75 +691,119 @@ class LunarListeners : SpellListener("lunar"), Commands { sendMessage(player, "You need more hitpoints to cast this spell.") return } - requires(player, 91, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.LAW_RUNE_563, 2), Item(Items.NATURE_RUNE_561, 1))) - player.face(p) + player.face(targetPlayer) visualizeSpell(player, Animations.LUNAR_SPELLBOOK_ENERGY_TRANSFER_4411, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738, 90, Sounds.LUNAR_ENERGY_TRANSFER_2885) - visualize(p, -1, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738) + visualize(targetPlayer, -1, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738) val hp = floor(player.skills.lifepoints * 0.10) - var r = hp - if(r > (100 - p.settings.runEnergy)) { - r = (100 - p.settings.runEnergy) + var run = hp + if(run > (100 - targetPlayer.settings.runEnergy)) { + run = (100 - targetPlayer.settings.runEnergy) } - if(r < 0) { - r = 0.0 + if(run < 0) { + run = 0.0 } - p.settings.runEnergy += r - player.settings.runEnergy -= r + targetPlayer.settings.runEnergy += run + player.settings.runEnergy -= run impact(player, hp.toInt(), ImpactHandler.HitsplatType.NORMAL) - var e = 100 - e -= p.settings.specialEnergy - if(e < 0) { - e = 0 + var energy = 100 + energy -= targetPlayer.settings.specialEnergy + if(energy < 0) { + energy = 0 } - if(e > player.settings.specialEnergy) { - e = player.settings.specialEnergy + if(energy > player.settings.specialEnergy) { + energy = player.settings.specialEnergy } - p.settings.specialEnergy += e - player.settings.specialEnergy -= e + targetPlayer.settings.specialEnergy += energy + player.settings.specialEnergy -= energy removeRunes(player, true) addXP(player, 100.0) } - private fun hunterKit(player: Player) { - requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 2))) - removeRunes(player, true) - if(addItem(player, Items.HUNTER_KIT_11159)) { - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_HUNTER_KIT_6303, Graphics.LUNAR_SPELLBOOK_HUNTER_KIT_1074, soundID = Sounds.LUNAR_HUNTER_KIT_3615) - addXP(player, 70.0) - setDelay(player, 2) + // Level 92 + /** + * Heal Other + */ + + // Level 93 + /** + * Vengeance Other + */ + + // Level 94 + /** + * Vengeance + */ + + // Level 95 + /** + * Heal Group + */ + + // Level 96 + /** + * Spellbook Swap + */ + + // Other/Multi spell use-case + private fun sendTeleport(player: Player, xp: Double, loc: Location){ + if(player.teleporter.send(loc,TeleportManager.TeleportType.LUNAR)) { + addXP(player, xp) + removeRunes(player) + setDelay(player, true) } } - private fun humidify(player: Player) { - val playerEmpties = ArrayDeque() - - for(item in player.inventory.toArray()) { - if(item == null) continue - if(!HumidifyItems.emptyContains(item.id)) continue - playerEmpties.add(item) + private fun sendGroupTeleport(player: Player, xp: Double, destName: String, loc: Location){ + RegionManager.getLocalPlayers(player, 1).forEach { + if(it == player) return@forEach + if(it.isTeleBlocked) return@forEach + if(!it.isActive) return@forEach + if(!it.settings.isAcceptAid) return@forEach + if(it.ironmanManager.isIronman) return@forEach + setAttribute(it, "t-o_location", loc) + openInterface(it, Components.TELEPORT_OTHER_326) + setInterfaceText(it, player.username, Components.TELEPORT_OTHER_326, 1) + setInterfaceText(it, destName, Components.TELEPORT_OTHER_326, 3) } - if(playerEmpties.isEmpty()) { - sendMessage(player, "You have nothing in your inventory that this spell can humidify.") - return - } - - - removeRunes(player) - delayEntity(player, Animation(Animations.LUNAR_SPELLBOOK_HUMIDIFY_6294).duration) - visualizeSpell(player, Animations.LUNAR_SPELLBOOK_HUMIDIFY_6294, Graphics.LUNAR_SPELLBOOK_HUMIDIFY_1061, 20, Sounds.LUNAR_HUMIDIFY_3614) - for(item in playerEmpties) { - val filled = HumidifyItems.forId(item.id) - removeItem(player, item.id) && addItem(player, filled) - } - addXP(player, 65.0) - /** - queueScript(player) { - return@queueScript stopExecuting(player) - } - */ + sendTeleport(player, xp, loc) } + override fun defineCommands() { + define("poison", privilege = Privilege.ADMIN) { player, strings -> + if(strings.size == 3) { + val dmg = strings[2].toIntOrNull() + val p = Repository.getPlayerByName(strings[1]) + if(p == null) { + sendMessage(player, "Player ${strings[1]} does not exist.") + return@define + } + if(dmg != null) { + p.let { applyPoison(it, it, dmg) } + } else { + sendMessage(player, "Damage must be an integer. Format:") + sendMessage(player, "::poison username damage") + } + } else { + sendMessage(player, "Invalid arguments provided. Format:") + sendMessage(player, "::poison username damage") + } + } + + define("humidifykit", privilege = Privilege.ADMIN) { player, _ -> + if(freeSlots(player) < 24) { + sendMessage(player, "Not enough free space.") + return@define + } else { + addItem(player, Items.ASTRAL_RUNE_9075, 100) + addItem(player, Items.WATER_RUNE_555, 300) + addItem(player, Items.FIRE_RUNE_554, 100) + for(item in HumidifyItems.values()) { + addItem(player, item.empty) + } + } + } + } } diff --git a/Server/src/main/content/global/skill/magic/lunar/StatSpySpell.java b/Server/src/main/content/global/skill/magic/lunar/StatSpySpell.java deleted file mode 100644 index 4519e870e..000000000 --- a/Server/src/main/content/global/skill/magic/lunar/StatSpySpell.java +++ /dev/null @@ -1,100 +0,0 @@ -package content.global.skill.magic.lunar; - -import core.game.component.CloseEvent; -import core.game.component.Component; -import core.plugin.Initializable; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.combat.spell.MagicSpell; -import core.game.node.entity.combat.spell.Runes; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.spell.SpellType; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -import static core.api.ContentAPIKt.playAudio; - -/** - * The stat spy spell. - * @author 'Vexia - */ -@Initializable -public final class StatSpySpell extends MagicSpell { - - /** - * Represents the animation of this spell. - */ - private final static Animation ANIMATION = new Animation(6293); - - /** - * Repesents the graphics of this spell. - */ - private static final Graphics GRAPHIC = new Graphics(734, 120); - - /** - * Represents the graphics. - */ - private static final Graphics EYE = new Graphics(1059); - - /** - * Represents the component. - */ - private static final Component COMPONENT = new Component(523); - - /** - * Represents the array of skills. - */ - private static int[][] SKILLS = { { Skills.ATTACK, 1, 2 }, { Skills.HITPOINTS, 5, 6 }, { Skills.MINING, 9, 10 }, { Skills.STRENGTH, 13, 14 }, { Skills.AGILITY, 17, 18 }, { Skills.SMITHING, 21, 22 }, { Skills.DEFENCE, 25, 26 }, { Skills.HERBLORE, 29, 30 }, { Skills.FISHING, 33, 34 }, { Skills.RANGE, 37, 38 }, { Skills.THIEVING, 41, 42 }, { Skills.COOKING, 45, 46 }, { Skills.PRAYER, 49, 50 }, { Skills.CRAFTING, 53, 54 }, { Skills.FIREMAKING, 57, 58 }, { Skills.MAGIC, 61, 62 }, { Skills.FLETCHING, 65, 66 }, { Skills.WOODCUTTING, 69, 70 }, { Skills.RUNECRAFTING, 73, 74 }, { Skills.SLAYER, 77, 78 }, { Skills.FARMING, 81, 82 }, { Skills.CONSTRUCTION, 85, 86 }, { Skills.HUNTER, 89, 90 }, { Skills.SUMMONING, 93, 94 } }; - - /** - * Constructs a new {@code CureOtherSpell} {@code Object}. - */ - public StatSpySpell() { - super(SpellBook.LUNAR, 75, 76, ANIMATION, null, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.BODY_RUNE.getId(), 5) }); - } - - @Override - public Plugin newInstance(SpellType arg) throws Throwable { - SpellBook.LUNAR.register(9, this); - return this; - } - - @Override - public boolean cast(Entity entity, Node target) { - final Player player = ((Player) entity); - if (!(target instanceof Player)) { - player.getPacketDispatch().sendMessage("You can only cast this spell on players."); - return false; - } - if (super.meetsRequirements(player, true, true)) { - final Player o = ((Player) target); - player.animate(ANIMATION); - player.face(o); - playAudio(player, Sounds.LUNAR_STAT_SPY_3620); - COMPONENT.setCloseEvent(new CloseEvent() { - @Override - public boolean close(Player player, Component c) { - player.getInterfaceManager().restoreTabs(); - return true; - } - }); - player.graphics(EYE); - o.graphics(GRAPHIC); - playAudio(player, Sounds.LUNAR_STAT_SPY_IMPACT_3621); - for (int[] element : SKILLS) { - player.getPacketDispatch().sendString("" + o.getSkills().getLevel(element[0]) + "", 523, element[1]); - player.getPacketDispatch().sendString("" + o.getSkills().getStaticLevel(element[0]) + "", 523, element[2]); - } - player.getPacketDispatch().sendString((o.getUsername()), 523, 99); - player.getInterfaceManager().openSingleTab(COMPONENT); - return true; - } - return true; - } - -} diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 4d98f4361..ae2f42df1 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -2996,4 +2996,13 @@ fun calculateDragonfireMaxHit(entity: Entity, maxDamage: Int, wyvern: Boolean = return Math.max(unprotectableDamage, effectiveDamage.toInt()) } +/** + * Opens a single interface tab from given ID. + * @param player the player to open interface for + * @param component the component ID to open + */ +fun openSingleTab(player: Player, component: Int) { + player.interfaceManager.openSingleTab(Component(component)) +} + private class ContentAPI