Skip to content

Commit 68b7891

Browse files
committed
Merge pull request #396 from chivvon/herblore
2 parents 3c6d251 + a528379 commit 68b7891

File tree

9 files changed

+410
-0
lines changed

9 files changed

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

0 commit comments

Comments
 (0)