Merge pull request #396 from chivvon/herblore

This commit is contained in:
Major
2018-04-08 02:32:53 +01:00
9 changed files with 410 additions and 0 deletions
+10
View File
@@ -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)
}
}
+34
View File
@@ -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)
}
}
+73
View File
@@ -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()
}