Rewrote Stat Spy

Refactored lunar spell handlers
This commit is contained in:
bushtail 2023-10-12 01:43:43 +00:00 committed by Ryan
parent 1913d0c83f
commit 9989ee9905
4 changed files with 441 additions and 405 deletions

View file

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

View file

@ -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<Item>()
@ -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)
setDelay(player, true)
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)
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<Item>()
// Level 68
private fun humidify(player: Player) {
val playerEmpties = ArrayDeque<Item>()
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)) {
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_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()
}
})
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<Item>()
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)
}
}
private fun humidify(player: Player) {
val playerEmpties = ArrayDeque<Item>()
for(item in player.inventory.toArray()) {
if(item == null) continue
if(!HumidifyItems.emptyContains(item.id)) continue
playerEmpties.add(item)
}
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)
// Level 92
/**
queueScript(player) {
return@queueScript stopExecuting(player)
}
* 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 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)
}
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)
}
}
}
}
}

View file

@ -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<SpellType> 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;
}
}

View file

@ -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