Fix nitpicks in Mining plugin

Also adds equals() and hashcode() implementations to the various
Mining actions.
This commit is contained in:
Major
2018-03-28 16:50:43 +01:00
parent 173623b76b
commit 6941fc9de0
5 changed files with 257 additions and 214 deletions
+1
View File
@@ -3,6 +3,7 @@ plugin {
authors = [
"Graham",
"Mikey`",
"Major",
"WH:II:DOW",
"Requa",
"Clifton",
+10 -9
View File
@@ -1,12 +1,13 @@
package org.apollo.game.plugin.skills.mining
enum class Gem(val id: Int, val chance: Int) {
UNCUT_SAPPHIRE(1623, 0),
UNCUT_EMERALD(1605, 0),
UNCUT_RUBY(1619, 0),
UNCUT_DIAMOND(1617, 0)
}
enum class Gem(val id: Int) { // TODO add gem drop chances
UNCUT_SAPPHIRE(1623),
UNCUT_EMERALD(1605),
UNCUT_RUBY(1619),
UNCUT_DIAMOND(1617);
val GEMS = Gem.values()
fun lookupGem(id: Int): Gem? = GEMS.find { it.id == id }
companion object {
private val GEMS = Gem.values().associateBy({ it.id }, { it })
fun lookup(id: Int): Gem? = GEMS[id]
}
}
+87 -49
View File
@@ -12,17 +12,33 @@ import org.apollo.game.plugin.api.findObject
import org.apollo.game.plugin.api.mining
import org.apollo.game.plugin.api.rand
import org.apollo.game.plugin.skills.mining.Ore
import org.apollo.game.plugin.skills.mining.PICKAXES
import org.apollo.game.plugin.skills.mining.Pickaxe
import org.apollo.game.plugin.skills.mining.lookupOreRock
import org.apollo.net.message.Message
import java.util.Optional
import java.util.Objects
class MiningTarget(val objectId: Int, val position: Position, val ore: Ore) {
on { ObjectActionMessage::class }
.where { option == Actions.MINING }
.then { player ->
Ore.fromRock(id)?.let { ore ->
MiningAction.start(this, player, ore)
}
}
fun getObject(world: World): Optional<GameObject> {
on { ObjectActionMessage::class }
.where { option == Actions.PROSPECTING }
.then { player ->
val ore = Ore.fromRock(id)
if (ore != null) {
ProspectingAction.start(this, player, ore)
}
}
data class MiningTarget(val objectId: Int, val position: Position, val ore: Ore) {
fun getObject(world: World): GameObject? {
val region = world.regionRepository.fromPosition(position)
return region.findObject(position, objectId)
return region.findObject(position, objectId).orElse(null)
}
fun isSuccessful(mob: Player): Boolean {
@@ -41,27 +57,22 @@ class MiningAction(
) : AsyncDistancedAction<Player>(PULSES, true, player, target.position, ORE_SIZE) {
companion object {
private val PULSES = 0
private val ORE_SIZE = 1
fun pickaxeFor(player: Player): Pickaxe? {
return PICKAXES
.filter { it.level <= player.mining.current }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level }
.firstOrNull()
}
private const val PULSES = 0
private const val ORE_SIZE = 1
/**
* Starts a [MiningAction] for the specified [Player], terminating the [Message] that triggered it.
*/
fun start(message: ObjectActionMessage, player: Player, ore: Ore) {
val pickaxe = pickaxeFor(player)
if (pickaxe != null) {
val action = MiningAction(player, pickaxe, MiningTarget(message.id, message.position, ore))
player.startAction(action)
} else {
val pickaxe = Pickaxe.bestFor(player)
if (pickaxe == null) {
player.sendMessage("You do not have a pickaxe for which you have the level to use.")
} else {
val target = MiningTarget(message.id, message.position, ore)
val action = MiningAction(player, pickaxe, target)
player.startAction(action)
}
message.terminate()
@@ -83,7 +94,7 @@ class MiningAction(
wait(tool.pulses)
val obj = target.getObject(mob.world)
if (!obj.isPresent) {
if (obj == null) {
stop()
}
@@ -94,25 +105,46 @@ class MiningAction(
}
if (mob.inventory.add(target.ore.id)) {
val oreName = Definitions.item(target.ore.id)?.name?.toLowerCase()
val oreName = Definitions.item(target.ore.id)!!.name.toLowerCase()
mob.sendMessage("You manage to mine some $oreName")
mob.mining.experience += target.ore.exp
mob.world.expireObject(obj.get(), target.ore.objects[target.objectId]!!, target.ore.respawn)
mob.world.expireObject(obj!!, target.ore.objects[target.objectId]!!, target.ore.respawn)
stop()
}
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as MiningAction
return mob == other.mob && target == other.target
}
override fun hashCode(): Int = Objects.hash(mob, target)
}
class ExpiredProspectingAction(
mob: Player,
position: Position
) : DistancedAction<Player>(PROSPECT_PULSES, true, mob, position, ORE_SIZE) {
) : DistancedAction<Player>(DELAY, true, mob, position, ORE_SIZE) {
companion object {
private val PROSPECT_PULSES = 0
private val ORE_SIZE = 1
private const val DELAY = 0
private const val ORE_SIZE = 1
/**
* Starts a [ExpiredProspectingAction] for the specified [Player], terminating the [Message] that triggered it.
*/
fun start(message: ObjectActionMessage, player: Player) {
val action = ExpiredProspectingAction(player, message.position)
player.startAction(action)
message.terminate()
}
}
override fun executeAction() {
@@ -120,17 +152,27 @@ class ExpiredProspectingAction(
stop()
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ExpiredProspectingAction
return mob == other.mob && position == other.position
}
override fun hashCode(): Int = Objects.hash(mob, position)
}
class ProspectingAction(
player: Player,
position: Position,
private val ore: Ore
) : AsyncDistancedAction<Player>(PROSPECT_PULSES, true, player, position, ORE_SIZE) {
) : AsyncDistancedAction<Player>(DELAY, true, player, position, ORE_SIZE) {
companion object {
private val PROSPECT_PULSES = 3
private val ORE_SIZE = 1
private const val DELAY = 3
private const val ORE_SIZE = 1
/**
* Starts a [MiningAction] for the specified [Player], terminating the [Message] that triggered it.
@@ -141,7 +183,6 @@ class ProspectingAction(
message.terminate()
}
}
override fun action(): ActionBlock = {
@@ -151,27 +192,24 @@ class ProspectingAction(
wait()
val oreName = Definitions.item(ore.id)?.name?.toLowerCase()
mob.sendMessage("This rock contains $oreName")
mob.sendMessage("This rock contains $oreName.")
stop()
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as ProspectingAction
return mob == other.mob && position == other.position && ore == other.ore
}
override fun hashCode(): Int = Objects.hash(mob, position, ore)
}
on { ObjectActionMessage::class }
.where { option == 1 }
.then {
val ore = lookupOreRock(id)
if (ore != null) {
MiningAction.start(this, it, ore)
}
}
on { ObjectActionMessage::class }
.where { option == 2 }
.then {
val ore = lookupOreRock(id)
if (ore != null) { // TODO send expired action if rock is expired
ProspectingAction.start(this, it, ore)
}
}
private object Actions {
const val MINING = 1
const val PROSPECTING = 2
}
+136 -137
View File
@@ -1,155 +1,154 @@
package org.apollo.game.plugin.skills.mining
import com.google.common.collect.Maps.asMap
/*
Thanks to Mikey` <http://www.rune-server.org/members/mikey%60/> for helping
to find some of the item/object IDs, minimum levels and experiences.
Thanks to Clifton <http://www.rune-server.org/members/clifton/> for helping
to find some of the expired object IDs.
*/
val CLAY_OBJECTS = mapOf(
2108 to 450,
2109 to 451,
14904 to 14896,
14905 to 14897
)
val COPPER_OBJECTS = mapOf(
11960 to 11555,
11961 to 11556,
11962 to 11557,
11936 to 11552,
11937 to 11553,
11938 to 11554,
2090 to 450,
2091 to 451,
14906 to 14898,
14907 to 14899,
14856 to 14832,
14857 to 14833,
14858 to 14834
)
val TIN_OBJECTS = mapOf(
11597 to 11555,
11958 to 11556,
11959 to 11557,
11933 to 11552,
11934 to 11553,
11935 to 11554,
2094 to 450,
2095 to 451,
14092 to 14894,
14903 to 14895
)
val IRON_OBJECTS = mapOf(
11954 to 11555,
11955 to 11556,
11956 to 11557,
2092 to 450,
2093 to 451,
14900 to 14892,
14901 to 14893,
14913 to 14915,
14914 to 14916
)
val COAL_OBJECTS = mapOf(
11963 to 11555,
11964 to 11556,
11965 to 11557,
11930 to 11552,
11931 to 11553,
11932 to 11554,
2096 to 450,
2097 to 451,
14850 to 14832,
14851 to 14833,
14852 to 14834
)
val SILVER_OBJECTS = mapOf (
11948 to 11555,
11949 to 11556,
11950 to 11557,
2100 to 450,
2101 to 451
)
val GOLD_OBJECTS = mapOf(
11951 to 11555,
11952 to 11556,
11953 to 11557,
2098 to 450,
2099 to 451
)
val MITHRIL_OBJECTS = mapOf(
11945 to 11555,
11946 to 11556,
11947 to 11557,
11942 to 11552,
11943 to 11553,
11944 to 11554,
2102 to 450,
2103 to 451,
14853 to 14832,
14854 to 14833,
14855 to 14834
)
val ADAMANT_OBJECTS = mapOf(
11939 to 11552,
11940 to 11553,
11941 to 11554,
2104 to 450,
2105 to 451,
14862 to 14832,
14863 to 14833,
14864 to 14834
)
val RUNITE_OBJECTS = mapOf(
2106 to 450,
2107 to 451,
14859 to 14832,
14860 to 14833,
14861 to 14834
)
/**
* Chance values thanks to: http://runescape.wikia.com/wiki/Talk:Mining#Mining_success_rate_formula
* Respawn times and xp thanks to: http://oldschoolrunescape.wikia.com/wiki/
*/
enum class Ore(val id: Int, val objects: Map<Int, Int>, val level: Int, val exp: Double, val respawn: Int, val chance: Double, val chanceOffset: Boolean) {
CLAY(434, CLAY_OBJECTS, 1, 5.0, 1, 0.0085, true),
COPPER(436, COPPER_OBJECTS, 1, 17.5, 4, 0.0085, true),
TIN(438, TIN_OBJECTS, 1, 17.5, 4, 0.0085, true),
IRON(440, IRON_OBJECTS, 15, 35.0, 9, 0.0085, true),
COAL(453, COAL_OBJECTS, 30, 50.0, 50, 0.004, false),
GOLD(444, GOLD_OBJECTS, 40, 65.0, 100, 0.003, false),
SILVER(442, SILVER_OBJECTS, 20, 40.0, 100, 0.0085, false),
MITHRIL(447, MITHRIL_OBJECTS, 55, 80.0, 200, 0.002, false),
ADAMANT(449, ADAMANT_OBJECTS, 70, 95.0, 800, 0.001, false),
RUNITE(451, RUNITE_OBJECTS, 85, 125.0, 1200, 0.0008, false)
}
enum class Ore(
val objects: Map<Int, Int>,
val id: Int,
val level: Int,
val exp: Double,
val respawn: Int,
val chance: Double,
val chanceOffset: Boolean = false
) {
CLAY(CLAY_OBJECTS, id = 434, level = 1, exp = 5.0, respawn = 1, chance = 0.0085, chanceOffset = true),
COPPER(COPPER_OBJECTS, id = 436, level = 1, exp = 17.5, respawn = 4, chance = 0.0085, chanceOffset = true),
TIN(TIN_OBJECTS, id = 438, level = 1, exp = 17.5, respawn = 4, chance = 0.0085, chanceOffset = true),
IRON(IRON_OBJECTS, id = 440, level = 15, exp = 35.0, respawn = 9, chance = 0.0085, chanceOffset = true),
COAL(COAL_OBJECTS, id = 453, level = 30, exp = 50.0, respawn = 50, chance = 0.004),
GOLD(GOLD_OBJECTS, id = 444, level = 40, exp = 65.0, respawn = 100, chance = 0.003),
SILVER(SILVER_OBJECTS, id = 442, level = 20, exp = 40.0, respawn = 100, chance = 0.0085),
MITHRIL(MITHRIL_OBJECTS, id = 447, level = 55, exp = 80.0, respawn = 200, chance = 0.002),
ADAMANT(ADAMANT_OBJECTS, id = 449, level = 70, exp = 95.0, respawn = 800, chance = 0.001),
RUNITE(RUNITE_OBJECTS, id = 451, level = 85, exp = 125.0, respawn = 1_200, chance = 0.0008);
val ORES = enumValues<Ore>()
companion object {
private val ORE_ROCKS = Ore.values().flatMap { ore -> ore.objects.map { Pair(it.key, ore) } }.toMap()
private val EXPIRED_ORE = Ore.values().flatMap { ore -> ore.objects.map { Pair(it.value, ore) } }.toMap()
fun lookupOre(id: Int): Ore? = ORES.find { it.id == id }
fun fromRock(id: Int): Ore? = ORE_ROCKS[id]
fun fromExpiredRock(id: Int): Ore? = EXPIRED_ORE[id]
fun lookupOreRock(id: Int): Ore? {
for (ore in enumValues<Ore>()) {
for (rock in ore.objects) {
if (rock.key == id) {
return ore
}
}
}
return null
}
// Maps from regular rock id to expired rock id.
val CLAY_OBJECTS = mapOf(
2108 to 450,
2109 to 451,
14904 to 14896,
14905 to 14897
)
val COPPER_OBJECTS = mapOf(
11960 to 11555,
11961 to 11556,
11962 to 11557,
11936 to 11552,
11937 to 11553,
11938 to 11554,
2090 to 450,
2091 to 451,
14906 to 14898,
14907 to 14899,
14856 to 14832,
14857 to 14833,
14858 to 14834
)
val TIN_OBJECTS = mapOf(
11597 to 11555,
11958 to 11556,
11959 to 11557,
11933 to 11552,
11934 to 11553,
11935 to 11554,
2094 to 450,
2095 to 451,
14092 to 14894,
14903 to 14895
)
val IRON_OBJECTS = mapOf(
11954 to 11555,
11955 to 11556,
11956 to 11557,
2092 to 450,
2093 to 451,
14900 to 14892,
14901 to 14893,
14913 to 14915,
14914 to 14916
)
val COAL_OBJECTS = mapOf(
11963 to 11555,
11964 to 11556,
11965 to 11557,
11930 to 11552,
11931 to 11553,
11932 to 11554,
2096 to 450,
2097 to 451,
14850 to 14832,
14851 to 14833,
14852 to 14834
)
val SILVER_OBJECTS = mapOf(
11948 to 11555,
11949 to 11556,
11950 to 11557,
2100 to 450,
2101 to 451
)
val GOLD_OBJECTS = mapOf(
11951 to 11555,
11952 to 11556,
11953 to 11557,
2098 to 450,
2099 to 451
)
val MITHRIL_OBJECTS = mapOf(
11945 to 11555,
11946 to 11556,
11947 to 11557,
11942 to 11552,
11943 to 11553,
11944 to 11554,
2102 to 450,
2103 to 451,
14853 to 14832,
14854 to 14833,
14855 to 14834
)
val ADAMANT_OBJECTS = mapOf(
11939 to 11552,
11940 to 11553,
11941 to 11554,
2104 to 450,
2105 to 451,
14862 to 14832,
14863 to 14833,
14864 to 14834
)
val RUNITE_OBJECTS = mapOf(
2106 to 450,
2107 to 451,
14859 to 14832,
14860 to 14833,
14861 to 14834
)
+23 -19
View File
@@ -1,23 +1,27 @@
package org.apollo.game.plugin.skills.mining
import org.apollo.game.model.Animation;
import org.apollo.game.model.Animation
import org.apollo.game.model.entity.Player
import org.apollo.game.plugin.api.mining
enum class Pickaxe(val id: Int, val level: Int, val animation: Animation, val pulses: Int) {
RUNE(1275, 41, Animation(624), 3),
ADAMANT(1271, 31, Animation(628), 4),
MITHRIL(1273, 21, Animation(629), 5),
STEEL(1269, 1, Animation(627), 6),
ITRON(1267, 1, Animation(626), 7),
BRONZE(1265, 1, Animation(625), 8)
enum class Pickaxe(val id: Int, val level: Int, animation: Int, val pulses: Int) {
BRONZE(id = 1265, level = 1, animation = 625, pulses = 8),
ITRON(id = 1267, level = 1, animation = 626, pulses = 7),
STEEL(id = 1269, level = 1, animation = 627, pulses = 6),
MITHRIL(id = 1273, level = 21, animation = 629, pulses = 5),
ADAMANT(id = 1271, level = 31, animation = 628, pulses = 4),
RUNE(id = 1275, level = 41, animation = 624, pulses = 3);
val animation = Animation(animation)
companion object {
private val PICKAXES = Pickaxe.values().sortedByDescending { it.level }
fun bestFor(player: Player): Pickaxe? {
return PICKAXES.asSequence()
.filter { it.level <= player.mining.current }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.firstOrNull()
}
}
}
val PICKAXES = Pickaxe.values()
fun getPickaxes(): Array<Pickaxe> {
return PICKAXES
}
fun lookupPickaxe(id: Int): Pickaxe? = PICKAXES.find { it.id == id }