diff --git a/Server/src/main/java/core/game/content/activity/mta/AlchemySpell.java b/Server/src/main/java/core/game/content/activity/mta/AlchemySpell.java deleted file mode 100644 index 3572d8239..000000000 --- a/Server/src/main/java/core/game/content/activity/mta/AlchemySpell.java +++ /dev/null @@ -1,132 +0,0 @@ -package core.game.content.activity.mta; - -import core.game.content.activity.mta.impl.AlchemistZone; -import core.game.content.activity.mta.impl.AlchemistZone.AlchemistItem; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.equipment.SpellType; -import core.game.node.entity.player.Player; -import core.game.node.entity.player.link.SpellBookManager.SpellBook; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.node.entity.skill.magic.MagicSpell; -import core.game.node.item.Item; -import core.game.world.map.zone.ZoneBorders; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Plugin; -import org.rs09.consts.Items; - -/** - * Represents the plugin for the magic spell alchemy. - * @author Emperor - * @author 'Vexia - * @version 1.0 - */ -public final class AlchemySpell extends MagicSpell { - - /** - * If the spell is high alchemy. - */ - private boolean highAlchemy; - - /** - * Constructs a new {@code AlchemySpell} {@code Object}. - */ - public AlchemySpell() { - /** - * empty. - */ - } - - /** - * Constructs a new {@code AlchemySpell} {@code Object}. - * @param level The required level. - * @param anim the animation. - * @param graphic The graphic. - * @param highAlchemy If this spell is high alchemy. - * @param runes The runes required. - */ - public AlchemySpell(int level, final double experience, Animation anim, Graphics graphic, boolean highAlchemy, Item... runes) { - super(SpellBook.MODERN, level, experience, anim, graphic, null, runes); - this.highAlchemy = highAlchemy; - } - - @Override - public Plugin newInstance(SpellType arg) throws Throwable { - //SpellBook.MODERN.register(13, new AlchemySpell(21, 31, Animation.create(712), new Graphics(112, 96), false, Runes.FIRE_RUNE.getItem(3), Runes.NATURE_RUNE.getItem(1))); - //SpellBook.MODERN.register(34, new AlchemySpell(55, 65, Animation.create(713), new Graphics(113, 96), true, Runes.FIRE_RUNE.getItem(5), Runes.NATURE_RUNE.getItem(1))); - return this; - } - - @Override - public boolean cast(Entity entity, Node target) { - Item item = (Item) target; - Player p = (Player) entity; - p.getInterfaceManager().setViewedTab(6); - if (item == null || p.getInventory().get(item.getSlot()) != item) { - p.sendMessage("Error! Report to admin."); - return false; - } - if (item.getId() == 995 || item.getName().equals("Coins")) { - p.getPacketDispatch().sendMessage("You can't cast this spell on an object made of gold."); - return false; - } - if (!item.getDefinition().isTradeable()) { - p.getPacketDispatch().sendMessage("You can't cast this spell on an object like that."); - return false; - } - boolean alchZone = p.getZoneMonitor().isInZone("Alchemists' Playground"); - AlchemistItem alch = null; - if (alchZone) { - alch = AlchemistItem.forItem(item.getId()); - if (alch == null) { - p.getDialogueInterpreter().sendDialogue("You can only convert the items you find in the cupboards."); - return false; - } - } - Item coins = new Item(995, item.getDefinition().getAlchemyValue(highAlchemy)); - if (alchZone) { - coins = new Item(AlchemistZone.COINS.getId(), alch.getCost()); - if (p.getInventory().getAmount(AlchemistZone.COINS.getId()) + alch.getCost() > 10000) { - p.getDialogueInterpreter().sendDialogue("Warning: You can't deposit more than 12000 coins at a time."); - } - } - if (coins.getAmount() > 1 && !p.getInventory().hasSpaceFor(coins)) { - p.getPacketDispatch().sendMessage("Not enough space in your inventory!"); - return false; - } - boolean freeAlch = alchZone && alch == AlchemistZone.freeConvert; - boolean explorerRing = !highAlchemy && p.getSavedData().getGlobalData().getLowAlchemyCharges() > 0; - if (explorerRing && !checkLevelRequirement(p, true)) { - return false; - } - if (!alchZone || !freeAlch) { - if (!explorerRing && !meetsRequirements(p, true, true)) { - return false; - } - } - p.lock(3); - visualize(p, target); - if (p.getInventory().remove(new Item(item.getId(), 1))) { - if (explorerRing) { - p.getSavedData().getGlobalData().setLowAlchemyCharges(p.getSavedData().getGlobalData().getLowAlchemyCharges() - 1); - int charge = p.getSavedData().getGlobalData().getLowAlchemyCharges(); - p.sendMessages("You use a free cast due to the power of your explorer's ring.", "You have " + charge + " charge" + (charge == 1 ? "" : "s") + " left."); - } - p.getAudioManager().send(highAlchemy ? 97 : 98); - if (coins.getAmount() != 0) { - p.getInventory().add(coins); - } - - if ((item.getId() == Items.MAGIC_SHORTBOW_861 || item.getId() == Items.MAGIC_SHORTBOW_862) - && highAlchemy - && new ZoneBorders(2721,3493,2730,3487).insideBorder(p)) { - p.getAchievementDiaryManager().finishTask(p, DiaryType.SEERS_VILLAGE, 2, 6); - } - } else { - return false; - } - return true; - } - -} diff --git a/Server/src/main/java/core/game/content/activity/mta/MageTrainingArenaPlugin.java b/Server/src/main/java/core/game/content/activity/mta/MageTrainingArenaPlugin.java index 0ccb3ff71..9cbac0409 100644 --- a/Server/src/main/java/core/game/content/activity/mta/MageTrainingArenaPlugin.java +++ b/Server/src/main/java/core/game/content/activity/mta/MageTrainingArenaPlugin.java @@ -52,7 +52,7 @@ public class MageTrainingArenaPlugin extends OptionHandler { ItemDefinition.forId(TelekineticZone.STATUE).getHandlers().put("option:observe", this); ItemDefinition.forId(TelekineticZone.STATUE).getHandlers().put("option:reset", this); NPCDefinition.forId(3102).getHandlers().put("option:talk-to", this); - PluginManager.definePlugins(new CharmedWarriorDialogue(), new EntranceGuardianDialogue(), new RewardsGuardianDialogue(), new ProgressHatDialogue(), new EnchantmentGuardianDialogue(), new EnchantSpell(), new BonesConvertingSpells(), new GraveyardGuardianDialogue(), new AlchemyGuardianDialogue(), new AlchemySpell(), new TelekineticGrabSpell(), new TelekineticGuardianDialogue(), new MazeGuardianDialogue()); + PluginManager.definePlugins(new CharmedWarriorDialogue(), new EntranceGuardianDialogue(), new RewardsGuardianDialogue(), new ProgressHatDialogue(), new EnchantmentGuardianDialogue(), new EnchantSpell(), new BonesConvertingSpells(), new GraveyardGuardianDialogue(), new AlchemyGuardianDialogue(), new TelekineticGrabSpell(), new TelekineticGuardianDialogue(), new MazeGuardianDialogue()); return this; } diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/Master.java b/Server/src/main/java/core/game/node/entity/skill/slayer/Master.java index 324a28449..660f71dd1 100644 --- a/Server/src/main/java/core/game/node/entity/skill/slayer/Master.java +++ b/Server/src/main/java/core/game/node/entity/skill/slayer/Master.java @@ -223,6 +223,8 @@ public enum Master { List tasks; Master(int npc_id, int required_combat, int required_slayer, int[] assignment_range, int[] streakPoints, Task... tasks) { this.npc_id = npc_id; + this.required_combat = required_combat; + this.required_slayer = required_slayer; this.assignment_range = assignment_range; this.streakPoints = streakPoints; this.tasks = new ArrayList<>(Arrays.asList(tasks)); diff --git a/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt b/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt index 78bba76db..fb3584176 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt @@ -1,7 +1,14 @@ package rs09.game.content.activity.mta +import core.game.content.activity.mta.impl.AlchemistZone +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener +import rs09.game.node.entity.skill.magic.SpellListener +import rs09.game.node.entity.skill.magic.spellconsts.Modern class MTAListeners : InteractionListener() { override fun defineListeners() { @@ -10,4 +17,86 @@ class MTAListeners : InteractionListener() { return@on true } } +} + +class MTASpellListeners : SpellListener("modern"){ + private val LOW_ALCH_ANIM = Animation(712) + private val LOW_ALCH_GFX = Graphics(112,5) + private val HIGH_ALCH_ANIM = Animation(713) + private val HIGH_ALCH_GFX = Graphics(113,5) + private val MTA_ALCH_ITEMS = AlchemistZone.AlchemistItem.values().map{it.item.id}.toIntArray() + + override fun defineListeners() { + + onCast(Modern.HIGH_ALCHEMY,ITEM,*MTA_ALCH_ITEMS){p, node -> + val item = node?.asItem() ?: return@onCast + requires(p,55) + val alchItem = AlchemistZone.AlchemistItem.forItem(item.id) ?: return@onCast + val coins = Item(AlchemistZone.COINS.id, alchItem.cost) + val freeAlch = alchItem == AlchemistZone.freeConvert + + if (p.inventory.getAmount(AlchemistZone.COINS.id) + alchItem.cost > 10000) { + p.dialogueInterpreter.sendDialogue("Warning: You can't deposit more than 12000 coins at a time.") + } + + if (coins.amount > 1 && !p.inventory.hasSpaceFor(coins)) { + p.packetDispatch.sendMessage("Not enough space in your inventory!") + return@onCast + } + + if(!freeAlch){ + requires(p,55,arrayOf(Item(Items.FIRE_RUNE_554,5),Item(Items.NATURE_RUNE_561,1))) + } + + p.lock(3) + p.visualize(HIGH_ALCH_ANIM,HIGH_ALCH_GFX) + if(p.inventory.remove(Item(item.id,1))){ + p.audioManager.send(97) + if (coins.amount != 0) { + p.inventory.add(coins) + } + } + + showMagicTab(p) + addXP(p,65.0) + setDelay(p,false) + removeRunes(p) + } + + onCast(Modern.LOW_ALCHEMY,ITEM,*MTA_ALCH_ITEMS){p, node -> + val item = node?.asItem() ?: return@onCast + requires(p,21) + val alchItem = AlchemistZone.AlchemistItem.forItem(item.id) ?: return@onCast + val coins = Item(AlchemistZone.COINS.id, alchItem.cost) + val freeAlch = alchItem == AlchemistZone.freeConvert + + if (p.inventory.getAmount(AlchemistZone.COINS.id) + alchItem.cost > 10000) { + p.dialogueInterpreter.sendDialogue("Warning: You can't deposit more than 12000 coins at a time.") + } + + if (coins.amount > 1 && !p.inventory.hasSpaceFor(coins)) { + p.packetDispatch.sendMessage("Not enough space in your inventory!") + return@onCast + } + + if(!freeAlch){ + requires(p,21,arrayOf(Item(Items.FIRE_RUNE_554,3),Item(Items.NATURE_RUNE_561,1))) + } + + p.lock(3) + p.visualize(LOW_ALCH_ANIM,LOW_ALCH_GFX) + if(p.inventory.remove(Item(item.id,1))){ + p.audioManager.send(97) + if (coins.amount != 0) { + p.inventory.add(coins) + } + } + + showMagicTab(p) + addXP(p,31.0) + setDelay(p,false) + removeRunes(p) + } + + } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonUtils.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonUtils.kt index 69a1e2c50..751d1bafc 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonUtils.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonUtils.kt @@ -102,9 +102,8 @@ object DrillDemonUtils { } else if(!hasPants){ Item(Items.CAMO_BOTTOMS_6655) } else { - Item(Items.COINS_995,500) + Item(Items.COINS_995, 500) } - if(!player.inventory.add(reward)){ GroundItemManager.create(reward,player) } diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/SeargentDamienDialogue.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/SeargentDamienDialogue.kt index 39b933669..67d9fe549 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/SeargentDamienDialogue.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/SeargentDamienDialogue.kt @@ -16,7 +16,7 @@ class SeargentDamienDialogue(val isCorrect: Boolean = false) : DialogueFile() { end() player!!.unlock() DrillDemonUtils.cleanup(player!!) - player!!.pulseManager.run(object : Pulse(){ + player!!.pulseManager.run(object : Pulse(2){ override fun pulse(): Boolean { DrillDemonUtils.reward(player!!) return true diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SurpriseExamUtils.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SurpriseExamUtils.kt index d634915de..9f16dc29f 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SurpriseExamUtils.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SurpriseExamUtils.kt @@ -40,7 +40,7 @@ object SurpriseExamUtils { player.removeAttribute(SE_KEY_LOC) player.removeAttribute(SE_KEY_INDEX) player.removeAttribute(SE_KEY_CORRECT) - player.pulseManager.run(object : Pulse(){ + player.pulseManager.run(object : Pulse(2){ override fun pulse(): Boolean { val reward = Item(Items.BOOK_OF_KNOWLEDGE_11640) if(!player.inventory.add(reward)){ diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt index 574fdb725..9ba69f524 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/ModernListeners.kt @@ -1,5 +1,8 @@ package rs09.game.node.entity.skill.magic +import core.game.node.entity.Entity +import core.game.node.entity.impl.Animator.Priority +import core.game.node.entity.impl.Projectile import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager import core.game.node.entity.player.link.diary.DiaryType @@ -16,6 +19,35 @@ import rs09.ServerConstants import rs09.game.node.entity.skill.magic.spellconsts.Modern class ModernListeners : SpellListener("modern"){ + + private val CONFUSE_START = Graphics(102, 96) + private val CONFUSE_PROJECTILE = Projectile.create(null as Entity?, null, 103, 40, 36, 52, 75, 15, 11) + private val CONFUSE_END = Graphics(104, 96) + private val WEAKEN_START = Graphics(105, 96) + private val WEAKEN_PROJECTILE = Projectile.create(null as Entity?, null, 106, 40, 36, 52, 75, 15, 11) + private val WEAKEN_END = Graphics(107, 96) + private val CURSE_START = Graphics(108, 96) + private val CURSE_PROJECTILE = Projectile.create(null as Entity?, null, 109, 40, 36, 52, 75, 15, 11) + private val CURSE_END = Graphics(110, 96) + private val VULNER_START = Graphics(167, 96) + private val VULNER_PROJECTILE = Projectile.create(null as Entity?, null, 168, 40, 36, 52, 75, 15, 11) + private val VULNER_END = Graphics(169, 96) + private val ENFEEBLE_START = Graphics(170, 96) + private val ENFEEBLE_PROJECTILE = Projectile.create(null as Entity?, null, 171, 40, 36, 52, 75, 15, 11) + private val ENFEEBLE_END = Graphics(172, 96) + private val STUN_START = Graphics(173, 96) + private val STUN_PROJECTILE = Projectile.create(null as Entity?, null, 174, 40, 36, 52, 75, 15, 11) + private val STUN_END = Graphics(107, 96) + private val LOW_ANIMATION = Animation(716, Priority.HIGH) + private val HIGH_ANIMATION = Animation(729, Priority.HIGH) + private val LOW_ALCH_ANIM = Animation(712) + private val LOW_ALCH_GFX = Graphics(112,5) + private val HIGH_ALCH_ANIM = Animation(713) + private val HIGH_ALCH_GFX = Graphics(113,5) + private val BONE_CONVERT_GFX = Graphics(141, 96) + private val BONE_CONVERT_ANIM = Animation(722) + + override fun defineListeners() { onCast(Modern.HOME_TELEPORT,NONE){player, _ -> @@ -85,6 +117,24 @@ class ModernListeners : SpellListener("modern"){ superheat(player,item) } + onCast(Modern.BONES_TO_BANANAS,NONE){player, _ -> + requires(player,15, arrayOf(Item(Items.EARTH_RUNE_557,2), Item(Items.WATER_RUNE_555,2), Item(Items.NATURE_RUNE_561,1))) + boneConvert(player,true) + } + + onCast(Modern.BONES_TO_PEACHES,NONE){player, _ -> + requires(player,60, arrayOf(Item(Items.EARTH_RUNE_557,4), Item(Items.WATER_RUNE_555,4), Item(Items.NATURE_RUNE_561,2))) + boneConvert(player,false) + } + } + + private fun boneConvert(player: Player,bananas: Boolean){ + if(!bananas && !player.savedData.activityData.isBonesToPeaches){ + player.sendMessage("You can only learn this spell from the Mage Training Arena.") + return + } + + } private fun superheat(player: Player,item: Item){ @@ -112,7 +162,7 @@ class ModernListeners : SpellListener("modern"){ removeRunes(player) addXP(player,53.0) player.audioManager.send(117) - player.interfaceManager.setViewedTab(6) + showMagicTab(player) player.pulseManager.run(SmeltingPulse(player, item, bar, 1, true)) setDelay(player,false) } @@ -121,6 +171,11 @@ class ModernListeners : SpellListener("modern"){ if(item.name == "Coins") player.sendMessage("You can't alchemize something that's already gold!").also { return } if(!item.definition.isTradeable) player.sendMessage("You can't cast this spell on something like that.").also { return } + if(player.zoneMonitor.isInZone("Alchemists' Playground")){ + player.sendMessage("You can only alch items from the cupboards!") + return + } + val coins = Item(995, item.definition.getAlchemyValue(high)) if (coins.amount > 0 && !player.inventory.hasSpaceFor(coins)) { player.sendMessage("Not enough space in your inventory!") @@ -133,9 +188,9 @@ class ModernListeners : SpellListener("modern"){ removeRunes(player) player.audioManager.send(if (high) 97 else 98) if (high) { - player.visualize(Animation(713), Graphics(113, 5)) + player.visualize(HIGH_ALCH_ANIM,HIGH_ALCH_GFX) } else { - player.visualize(Animation(712), Graphics(112, 5)) + player.visualize(LOW_ALCH_ANIM,LOW_ALCH_GFX) } if(coins.amount > 0) @@ -146,7 +201,7 @@ class ModernListeners : SpellListener("modern"){ } addXP(player,if(high) 65.0 else 31.0) - player.interfaceManager.setViewedTab(6) + showMagicTab(player) setDelay(player,false) } } diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListener.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListener.kt index 8468c3e24..57cf36e83 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListener.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListener.kt @@ -27,8 +27,8 @@ abstract class SpellListener(val bookName: String) : Listener { SpellListeners.add(spellID,type,bookName,method) } - fun onCast(spellID: Int,type: Int, id: Int,method: (player: Player,node: Node?) -> Unit){ - SpellListeners.add(spellID,type,id,bookName,method) + fun onCast(spellID: Int, type: Int, vararg ids: Int, method: (player: Player, node: Node?) -> Unit){ + SpellListeners.add(spellID,type,ids,bookName,method) } fun requires(player: Player, magicLevel: Int = 0, runes: Array = arrayOf(), specialEquipment: IntArray = intArrayOf()){ @@ -69,4 +69,8 @@ abstract class SpellListener(val bookName: String) : Listener { fun interrupt(player: Player){ player.pulseManager.clear() } + + fun showMagicTab(player: Player){ + player.interfaceManager.setViewedTab(6) + } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListeners.kt index e301491ae..36032a7ea 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListeners.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellListeners.kt @@ -8,15 +8,13 @@ object SpellListeners { val castMap = HashMap Unit>() fun add(spellID: Int, type: Int, book: String, method: (Player,Node?) -> Unit){ - SystemLogger.logInfo("add $book:$spellID:$type") - castMap["$book:$spellID:$type"] = method } - fun add(spellID: Int, type: Int, id: Int, book: String, method: (Player, Node?) -> Unit){ - SystemLogger.logInfo("add $book:$spellID:$type") - - castMap["$book:$spellID:$type:$id"] = method + fun add(spellID: Int, type: Int, ids: IntArray, book: String, method: (Player, Node?) -> Unit){ + for(id in ids) { + castMap["$book:$spellID:$type:$id"] = method + } } fun get(spellID: Int, type: Int, book: String): ((Player,Node?) -> Unit)?{ diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellUtils.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellUtils.kt index 49f868d58..bb9d77526 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellUtils.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellUtils.kt @@ -1,5 +1,6 @@ package rs09.game.node.entity.skill.magic +import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.skill.magic.CombinationRune import core.game.node.entity.skill.magic.MagicStaff @@ -81,6 +82,10 @@ object SpellUtils { return true } + fun attackableNPC(npc: NPC): Boolean{ + return npc.definition.hasAction("attack") + } + @JvmStatic fun getBookFromInterface(id: Int): String{ return when(id){ diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/spellconsts/Modern.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/spellconsts/Modern.kt index 46c68cae1..0cef959bc 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/spellconsts/Modern.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/spellconsts/Modern.kt @@ -2,16 +2,24 @@ package rs09.game.node.entity.skill.magic.spellconsts object Modern { const val HOME_TELEPORT = 0 + const val CONFUSE = 2 + const val BONES_TO_BANANAS = 9 + const val WEAKEN = 11 + const val LOW_ALCHEMY = 13 const val VARROCK_TELEPORT = 15 const val LUMBRIDGE_TELEPORT = 18 + const val CURSE = 19 const val FALADOR_TELEPORT = 21 + const val SUPERHEAT = 25 const val CAMELOT_TELEPORT = 26 const val TELEPORT_TO_HOUSE = 23 const val ARDOUGNE_TELEPORT = 32 + const val HIGH_ALCHEMY = 34 const val WATCHTOWER_TELEPORT = 37 + const val BONES_TO_PEACHES = 40 const val TROLLHEIM_TELEPORT = 44 const val APE_ATOLL_TELEPORT = 47 - const val LOW_ALCHEMY = 13 - const val HIGH_ALCHEMY = 34 - const val SUPERHEAT = 25 + const val VULNERABILITY = 50 + const val ENFEEBLE = 53 + const val STUN = 57 } \ No newline at end of file