mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Port Herblore plugin to Kotlin
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
plugin {
|
||||
name = "herblore_skill"
|
||||
authors = [
|
||||
"Chivvon",
|
||||
"Chris Fletcher",
|
||||
"Major"
|
||||
]
|
||||
|
||||
dependencies = ["api"]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import org.apollo.game.action.ActionBlock
|
||||
import org.apollo.game.action.AsyncAction
|
||||
import org.apollo.game.model.Animation
|
||||
import org.apollo.game.model.entity.Player
|
||||
import java.util.Objects
|
||||
|
||||
class CrushIngredientAction(
|
||||
player: Player,
|
||||
private val ingredient: CrushableIngredient
|
||||
) : AsyncAction<Player>(0, true, player) {
|
||||
|
||||
override fun action(): ActionBlock = {
|
||||
mob.playAnimation(GRINDING_ANIM)
|
||||
wait(pulses = 1)
|
||||
|
||||
val inventory = mob.inventory
|
||||
if (inventory.remove(ingredient.uncrushed)) {
|
||||
inventory.add(ingredient.id)
|
||||
|
||||
mob.sendMessage("You carefully grind the ${ingredient.uncrushedName} to dust.")
|
||||
}
|
||||
|
||||
stop()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CrushIngredientAction
|
||||
return mob == other.mob && ingredient == other.ingredient
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = Objects.hash(mob, ingredient)
|
||||
|
||||
private companion object {
|
||||
private val GRINDING_ANIM = Animation(364)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import org.apollo.game.plugin.api.Definitions
|
||||
|
||||
enum class Herb(
|
||||
val identified: Int,
|
||||
val unidentified: Int,
|
||||
val level: Int,
|
||||
val experience: Double
|
||||
) {
|
||||
GUAM_LEAF(identified = 249, unidentified = 199, level = 1, experience = 2.5),
|
||||
MARRENTILL(identified = 251, unidentified = 201, level = 5, experience = 3.8),
|
||||
TARROMIN(identified = 253, unidentified = 203, level = 11, experience = 5.0),
|
||||
HARRALANDER(identified = 255, unidentified = 205, level = 20, experience = 6.3),
|
||||
RANARR(identified = 257, unidentified = 207, level = 25, experience = 7.5),
|
||||
TOADFLAX(identified = 2998, unidentified = 2998, level = 30, experience = 8.0),
|
||||
IRIT_LEAF(identified = 259, unidentified = 209, level = 40, experience = 8.8),
|
||||
AVANTOE(identified = 261, unidentified = 211, level = 48, experience = 10.0),
|
||||
KWUARM(identified = 263, unidentified = 213, level = 54, experience = 11.3),
|
||||
SNAPDRAGON(identified = 3000, unidentified = 3051, level = 59, experience = 11.8),
|
||||
CADANTINE(identified = 265, unidentified = 215, level = 65, experience = 12.5),
|
||||
LANTADYME(identified = 2481, unidentified = 2485, level = 67, experience = 13.1),
|
||||
DWARF_WEED(identified = 267, unidentified = 217, level = 70, experience = 13.8),
|
||||
TORSTOL(identified = 269, unidentified = 219, level = 75, experience = 15.0);
|
||||
|
||||
val identifiedName: String = Definitions.item(identified)!!.name
|
||||
|
||||
companion object {
|
||||
private val identified = Herb.values().map(Herb::identified).toHashSet()
|
||||
private val herbs = Herb.values().associateBy(Herb::unidentified)
|
||||
|
||||
operator fun get(id: Int): Herb? = herbs[id]
|
||||
internal fun Int.isUnidentified(): Boolean = this in herbs
|
||||
internal fun Int.isIdentified(): Boolean = this in identified
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
import org.apollo.game.action.ActionBlock
|
||||
import org.apollo.game.action.AsyncAction
|
||||
import org.apollo.game.model.entity.Player
|
||||
import org.apollo.game.plugin.api.herblore
|
||||
import org.apollo.util.LanguageUtil
|
||||
import java.util.Objects
|
||||
|
||||
class IdentifyHerbAction(
|
||||
player: Player,
|
||||
private val slot: Int,
|
||||
private val herb: Herb
|
||||
) : AsyncAction<Player>(0, true, player) {
|
||||
|
||||
override fun action(): ActionBlock = {
|
||||
if (mob.herblore.current < herb.level) {
|
||||
mob.sendMessage("You need a Herblore level of ${herb.level} to clean this herb.")
|
||||
stop()
|
||||
}
|
||||
|
||||
val inventory = mob.inventory
|
||||
|
||||
if (inventory.removeSlot(slot, 1) > 0) {
|
||||
inventory.add(herb.identified)
|
||||
mob.herblore.experience += herb.experience
|
||||
|
||||
val name = herb.identifiedName
|
||||
val article = LanguageUtil.getIndefiniteArticle(name)
|
||||
|
||||
mob.sendMessage("You identify the herb as $article $name.")
|
||||
}
|
||||
|
||||
stop()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as IdentifyHerbAction
|
||||
return mob == other.mob && herb == other.herb && slot == other.slot
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = Objects.hash(mob, herb, slot)
|
||||
|
||||
companion object {
|
||||
const val IDENTIFY_OPTION = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import CrushableIngredient.Companion.isCrushable
|
||||
import NormalIngredient.Companion.isNormalIngredient
|
||||
import org.apollo.game.plugin.api.Definitions
|
||||
|
||||
/**
|
||||
* A secondary ingredient in a potion.
|
||||
*/
|
||||
interface Ingredient {
|
||||
val id: Int
|
||||
|
||||
companion object {
|
||||
internal fun Int.isIngredient(): Boolean = isNormalIngredient() || isCrushable()
|
||||
}
|
||||
}
|
||||
|
||||
enum class CrushableIngredient(val uncrushed: Int, override val id: Int) : Ingredient {
|
||||
UNICORN_HORN(uncrushed = 237, id = 235),
|
||||
DRAGON_SCALE(uncrushed = 243, id = 241),
|
||||
CHOCOLATE_BAR(uncrushed = 1973, id = 1975),
|
||||
BIRDS_NEST(uncrushed = 5075, id = 6693);
|
||||
|
||||
val uncrushedName: String = Definitions.item(uncrushed)!!.name
|
||||
|
||||
companion object {
|
||||
private const val PESTLE_AND_MORTAR = 233
|
||||
private const val KNIFE = 5605
|
||||
|
||||
private val ingredients = CrushableIngredient.values().associateBy(CrushableIngredient::uncrushed)
|
||||
operator fun get(id: Int): CrushableIngredient? = ingredients[id]
|
||||
|
||||
internal fun Int.isCrushable(): Boolean = this in ingredients
|
||||
internal fun Int.isGrindingTool(): Boolean = this == KNIFE || this == PESTLE_AND_MORTAR
|
||||
}
|
||||
}
|
||||
|
||||
enum class NormalIngredient(override val id: Int) : Ingredient {
|
||||
EYE_NEWT(id = 221),
|
||||
RED_SPIDERS_EGGS(id = 223),
|
||||
LIMPWURT_ROOT(id = 225),
|
||||
SNAPE_GRASS(id = 231),
|
||||
WHITE_BERRIES(id = 239),
|
||||
WINE_ZAMORAK(id = 245),
|
||||
JANGERBERRIES(id = 247),
|
||||
TOADS_LEGS(id = 2152),
|
||||
MORT_MYRE_FUNGI(id = 2970),
|
||||
POTATO_CACTUS(id = 3138),
|
||||
PHOENIX_FEATHER(id = 4621),
|
||||
FROG_SPAWN(id = 5004),
|
||||
PAPAYA_FRUIT(id = 5972),
|
||||
POISON_IVY_BERRIES(id = 6018),
|
||||
YEW_ROOTS(id = 6049),
|
||||
MAGIC_ROOTS(id = 6051);
|
||||
|
||||
companion object {
|
||||
private val ingredients = NormalIngredient.values().associateBy(NormalIngredient::id)
|
||||
operator fun get(id: Int): NormalIngredient? = ingredients[id]
|
||||
|
||||
internal fun Int.isNormalIngredient(): Boolean = this in ingredients
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import org.apollo.game.action.ActionBlock
|
||||
import org.apollo.game.action.AsyncAction
|
||||
import org.apollo.game.model.Animation
|
||||
import org.apollo.game.model.entity.Player
|
||||
import org.apollo.game.plugin.api.herblore
|
||||
import java.util.Objects
|
||||
|
||||
class MakeFinishedPotionAction(
|
||||
player: Player,
|
||||
private val potion: FinishedPotion
|
||||
) : AsyncAction<Player>(1, true, player) {
|
||||
|
||||
override fun action(): ActionBlock = {
|
||||
val level = mob.herblore.current
|
||||
|
||||
if (level < potion.level) {
|
||||
mob.sendMessage("You need a Herblore level of ${potion.level} to make this.")
|
||||
stop()
|
||||
}
|
||||
|
||||
val unfinished = potion.unfinished.id
|
||||
val inventory = mob.inventory
|
||||
|
||||
if (inventory.contains(unfinished) && inventory.contains(potion.ingredient)) {
|
||||
inventory.remove(unfinished)
|
||||
inventory.remove(potion.ingredient)
|
||||
|
||||
mob.playAnimation(MIXING_ANIMATION)
|
||||
|
||||
inventory.add(potion.id)
|
||||
mob.herblore.experience += potion.experience
|
||||
|
||||
mob.sendMessage("You mix the ${potion.ingredientName} into your potion.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as MakeFinishedPotionAction
|
||||
return mob == other.mob && potion == other.potion
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = Objects.hash(mob, potion)
|
||||
|
||||
private companion object {
|
||||
private val MIXING_ANIMATION = Animation(363)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import org.apollo.game.action.ActionBlock
|
||||
import org.apollo.game.action.AsyncAction
|
||||
import org.apollo.game.model.Animation
|
||||
import org.apollo.game.model.entity.Player
|
||||
import org.apollo.game.plugin.api.herblore
|
||||
import java.util.Objects
|
||||
|
||||
class MakeUnfinishedPotionAction(
|
||||
player: Player,
|
||||
private val potion: UnfinishedPotion
|
||||
) : AsyncAction<Player>(1, true, player) {
|
||||
|
||||
override fun action(): ActionBlock = {
|
||||
val level = mob.herblore.current
|
||||
|
||||
if (level < potion.level) {
|
||||
mob.sendMessage("You need a Herblore level of ${potion.level} to make this.")
|
||||
stop()
|
||||
}
|
||||
|
||||
val inventory = mob.inventory
|
||||
|
||||
if (inventory.contains(VIAL_OF_WATER) && inventory.contains(potion.herb)) {
|
||||
inventory.remove(VIAL_OF_WATER)
|
||||
inventory.remove(potion.herb)
|
||||
|
||||
mob.playAnimation(MIXING_ANIMATION)
|
||||
|
||||
inventory.add(potion.id)
|
||||
mob.sendMessage("You put the ${potion.herbName} into the vial of water.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as MakeUnfinishedPotionAction
|
||||
return mob == other.mob && potion == other.potion
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = Objects.hash(mob, potion)
|
||||
|
||||
private companion object {
|
||||
private val MIXING_ANIMATION = Animation(363)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import CrushableIngredient.CHOCOLATE_BAR
|
||||
import CrushableIngredient.DRAGON_SCALE
|
||||
import CrushableIngredient.UNICORN_HORN
|
||||
import NormalIngredient.*
|
||||
import UnfinishedPotion.*
|
||||
import org.apollo.game.plugin.api.Definitions
|
||||
|
||||
const val VIAL_OF_WATER = 227
|
||||
|
||||
enum class UnfinishedPotion(val id: Int, herb: Herb, val level: Int) {
|
||||
GUAM(id = 91, herb = Herb.GUAM_LEAF, level = 1),
|
||||
MARRENTILL(id = 93, herb = Herb.MARRENTILL, level = 5),
|
||||
TARROMIN(id = 95, herb = Herb.TARROMIN, level = 12),
|
||||
HARRALANDER(id = 97, herb = Herb.HARRALANDER, level = 22),
|
||||
RANARR(id = 99, herb = Herb.RANARR, level = 30),
|
||||
TOADFLAX(id = 3002, herb = Herb.TOADFLAX, level = 34),
|
||||
IRIT(id = 101, herb = Herb.IRIT_LEAF, level = 45),
|
||||
AVANTOE(id = 103, herb = Herb.AVANTOE, level = 50),
|
||||
KWUARM(id = 105, herb = Herb.KWUARM, level = 55),
|
||||
SNAPDRAGON(id = 3004, herb = Herb.SNAPDRAGON, level = 63),
|
||||
CADANTINE(id = 107, herb = Herb.CADANTINE, level = 66),
|
||||
LANTADYME(id = 2483, herb = Herb.LANTADYME, level = 69),
|
||||
DWARF_WEED(id = 109, herb = Herb.DWARF_WEED, level = 72),
|
||||
TORSTOL(id = 111, herb = Herb.TORSTOL, level = 78);
|
||||
|
||||
val herb = herb.identified
|
||||
val herbName: String = Definitions.item(herb.identified)!!.name
|
||||
|
||||
companion object {
|
||||
private val ids = values().map(UnfinishedPotion::id).toHashSet()
|
||||
private val potions = values().associateBy(UnfinishedPotion::herb)
|
||||
|
||||
operator fun get(id: Int) = potions[id]
|
||||
internal fun Int.isUnfinished(): Boolean = this in ids
|
||||
}
|
||||
}
|
||||
|
||||
enum class FinishedPotion(
|
||||
val id: Int,
|
||||
val unfinished: UnfinishedPotion,
|
||||
ingredient: Ingredient,
|
||||
val level: Int,
|
||||
val experience: Double
|
||||
) {
|
||||
ATTACK(id = 121, unfinished = GUAM, ingredient = EYE_NEWT, level = 1, experience = 25.0),
|
||||
ANTIPOISON(id = 175, unfinished = MARRENTILL, ingredient = UNICORN_HORN, level = 5, experience = 37.5),
|
||||
STRENGTH(id = 115, unfinished = TARROMIN, ingredient = LIMPWURT_ROOT, level = 12, experience = 50.0),
|
||||
RESTORE(id = 127, unfinished = HARRALANDER, ingredient = RED_SPIDERS_EGGS, level = 18, experience = 62.5),
|
||||
ENERGY(id = 3010, unfinished = HARRALANDER, ingredient = CHOCOLATE_BAR, level = 26, experience = 67.5),
|
||||
DEFENCE(id = 133, unfinished = RANARR, ingredient = WHITE_BERRIES, level = 30, experience = 75.0),
|
||||
AGILITY(id = 3034, unfinished = TOADFLAX, ingredient = TOADS_LEGS, level = 34, experience = 80.0),
|
||||
PRAYER(id = 139, unfinished = RANARR, ingredient = SNAPE_GRASS, level = 38, experience = 87.5),
|
||||
SUPER_ATTACK(id = 145, unfinished = IRIT, ingredient = EYE_NEWT, level = 45, experience = 100.0),
|
||||
SUPER_ANTIPOISON(id = 181, unfinished = IRIT, ingredient = UNICORN_HORN, level = 48, experience = 106.3),
|
||||
FISHING(id = 151, unfinished = AVANTOE, ingredient = SNAPE_GRASS, level = 50, experience = 112.5),
|
||||
SUPER_ENERGY(id = 3018, unfinished = AVANTOE, ingredient = MORT_MYRE_FUNGI, level = 52, experience = 117.5),
|
||||
SUPER_STRENGTH(id = 157, unfinished = KWUARM, ingredient = LIMPWURT_ROOT, level = 55, experience = 125.0),
|
||||
WEAPON_POISON(id = 187, unfinished = KWUARM, ingredient = DRAGON_SCALE, level = 60, experience = 137.5),
|
||||
SUPER_RESTORE(id = 3026, unfinished = SNAPDRAGON, ingredient = RED_SPIDERS_EGGS, level = 63, experience = 142.5),
|
||||
SUPER_DEFENCE(id = 163, unfinished = CADANTINE, ingredient = WHITE_BERRIES, level = 66, experience = 150.0),
|
||||
ANTIFIRE(id = 2428, unfinished = LANTADYME, ingredient = DRAGON_SCALE, level = 69, experience = 157.5),
|
||||
RANGING(id = 169, unfinished = DWARF_WEED, ingredient = WINE_ZAMORAK, level = 72, experience = 162.5),
|
||||
MAGIC(id = 3042, unfinished = LANTADYME, ingredient = POTATO_CACTUS, level = 76, experience = 172.5),
|
||||
ZAMORAK_BREW(id = 189, unfinished = TORSTOL, ingredient = JANGERBERRIES, level = 78, experience = 175.0);
|
||||
|
||||
val ingredientName = Definitions.item(ingredient.id)!!.name.toLowerCase()
|
||||
val ingredient = ingredient.id
|
||||
|
||||
companion object {
|
||||
private val potions = FinishedPotion.values().associateBy { Pair(it.unfinished.id, it.ingredient) }
|
||||
operator fun get(key: Pair<Int, Int>) = potions[key]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
import CrushableIngredient.Companion.isCrushable
|
||||
import CrushableIngredient.Companion.isGrindingTool
|
||||
import Herb.Companion.isIdentified
|
||||
import Herb.Companion.isUnidentified
|
||||
import Ingredient.Companion.isIngredient
|
||||
import UnfinishedPotion.Companion.isUnfinished
|
||||
import org.apollo.game.message.impl.ItemOnItemMessage
|
||||
import org.apollo.game.message.impl.ItemOptionMessage
|
||||
|
||||
on { ItemOptionMessage::class }
|
||||
.where { option == IdentifyHerbAction.IDENTIFY_OPTION && id.isUnidentified() }
|
||||
.then { player ->
|
||||
val unidentified = Herb[id]!!
|
||||
|
||||
player.startAction(IdentifyHerbAction(player, slot, unidentified))
|
||||
terminate()
|
||||
}
|
||||
|
||||
on { ItemOnItemMessage::class }
|
||||
.where { (id.isGrindingTool() && targetId.isCrushable() || id.isCrushable() && targetId.isGrindingTool()) }
|
||||
.then { player ->
|
||||
val crushableId = if (id.isCrushable()) id else targetId
|
||||
val raw = CrushableIngredient[crushableId]!!
|
||||
|
||||
player.startAction(CrushIngredientAction(player, raw))
|
||||
terminate()
|
||||
}
|
||||
|
||||
on { ItemOnItemMessage::class }
|
||||
.where { id == VIAL_OF_WATER && targetId.isIdentified() || id.isIdentified() && targetId == VIAL_OF_WATER }
|
||||
.then { player ->
|
||||
val herbId = if (id.isIdentified()) id else targetId
|
||||
val unfinished = UnfinishedPotion[herbId]!!
|
||||
|
||||
player.startAction(MakeUnfinishedPotionAction(player, unfinished))
|
||||
terminate()
|
||||
}
|
||||
|
||||
on { ItemOnItemMessage::class }
|
||||
.where { id.isUnfinished() && targetId.isIngredient() || id.isIngredient() && targetId.isUnfinished() }
|
||||
.then { player ->
|
||||
val key = if (id.isUnfinished()) Pair(id, targetId) else Pair(targetId, id)
|
||||
val finished = FinishedPotion[key]!!
|
||||
|
||||
player.startAction(MakeFinishedPotionAction(player, finished))
|
||||
terminate()
|
||||
}
|
||||
Reference in New Issue
Block a user