Finish up porting mining plugin to Kotlin

This commit is contained in:
Trevor Flynn
2017-08-17 21:29:15 -08:00
committed by Gary Tierney
parent e61f4ef95a
commit a54485e263
6 changed files with 257 additions and 53 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
name = "Mining Skill"
name = "mining-skill"
package = "org.apollo.game.plugin.skills.mining"
authors = [
"Graham",
@@ -11,4 +11,4 @@ authors = [
[config]
srcDir = "src/"
testDir = "test/"
testDir = "test/"
+9 -7
View File
@@ -1,10 +1,12 @@
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)
}
data class Gem(id: Int, chance: Int)
val GEMS = Gem.values()
val GEMS = Array(
Gem(1623, 0), // uncut sapphire
Gem(1605, 0), // uncut emerald
Gem(1619, 0), // uncut ruby
Gem(1617, 0) // uncut diamond
)
fun lookupGem(id: Int): Gem? = GEMS.find { it.id == id }
@@ -1,5 +1,200 @@
import org.apollo.cache.def.ItemDefinition
import org.apollo.cache.def.ObjectDefinition
import org.apollo.game.action.DistancedAction
import org.apollo.game.message.impl.ObjectActionMessage
import org.apollo.game.model.Animation
import org.apollo.game.model.Position
import org.apollo.game.model.entity.Entity
import org.apollo.game.model.entity.EquipmentConstants
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.Skill
import org.apollo.game.model.entity.obj.StaticGameObject
import org.apollo.game.plugin.skills.mining.*
import org.apollo.game.scheduling.ScheduledTask
import org.apollo.game.scheduling.Scheduler
import java.util.*
import kotlin.properties.Delegates
class MiningAction(val player: Player, val objectID: Int, val p: Position, val ore: Ore) : DistancedAction<Player>(PULSES, true, player, p, ORE_SIZE) {
companion object {
private val PULSES = 0
private val ORE_SIZE = 1;
}
private var counter: Int = 0
private var started: Boolean = false
private val rand: Random = Random()
override fun executeAction() {
val level = mob.skillSet.getSkill(Skill.MINING).currentLevel
val pickaxe = findPickaxe()
//check that our pick can mine the ore
if (pickaxe == null || level < pickaxe.level) {
mob.sendMessage("You do not have a pickaxe for which you have the level to use.")
stop()
return
}
//check that we can mine the ore
if (level < ore.level) {
mob.sendMessage("You do not have the required level to mine this rock.")
stop()
return
}
//start the process of mining
if (started) {
if (counter == 0) {
if (!miningSuccessful(ore.chance, ore.chanceOffset, level)) {
mine(pickaxe)
return //We did not mine the ore... Keep going
}
//Check inv capacity
if (mob.inventory.freeSlots() == 0) {
mob.inventory.forceCapacityExceeded()
stop()
return
}
if (mob.inventory.add(ore.id)) {
//TODO: Use lookup from utils once it has a lookup function for IDs
val oreName = ItemDefinition.lookup(ore.id).name.toLowerCase();
mob.sendMessage("You managed to mine some " + oreName + ".")
mob.skillSet.addExperience(Skill.MINING, ore.exp)
//Expire ore
var rockEntity: StaticGameObject? = null
val region = mob.world.regionRepository.fromPosition(position)
val entities = region.getEntities(position)
for (entity: Entity in entities) {
if (entity is StaticGameObject) {
if (entity.id == objectID) {
rockEntity = entity
}
}
}
if (rockEntity == null) { //Mining entity not found at location...
stop()
return
}
//Get ID of exipred ore
val expiredObjectID = ore.objects.get(objectID);
val expiredRockEntity = StaticGameObject(mob.world, expiredObjectID!!, position, rockEntity!!.type, rockEntity!!.orientation)
//add task to remove normal ore and replace with depleted
mob.world.schedule(object: ScheduledTask(0, true) {
override fun execute() {
//Replace normal ore with expired ore
region.removeEntity(rockEntity);
region.addEntity(expiredRockEntity)
this.stop() //Makes task run once
}
})
//add task to respawn normal ore
mob.world.schedule(object: ScheduledTask(ore.respawn, false) {
override fun execute() {
//Replace expired ore with normal ore
region.removeEntity(expiredRockEntity)
region.addEntity(rockEntity);
this.stop() //Makes task run once
}
})
} //If we did not add to inv, the action will still stop
stop(); //Force this action to stop after we are done
}
counter -= 1
} else {
started = true
mine(pickaxe)
}
}
private fun findPickaxe(): Pickaxe? {
for (pick in getPickaxes()) {
if (pick!!.level > mob.skillSet.getSkill(Skill.MINING).currentLevel) {
continue;
}
val weaponSlot = mob.equipment.get(EquipmentConstants.WEAPON)
if (weaponSlot != null && weaponSlot.id == pick.id) {
return pick;
} else if (mob.inventory.contains(pick.id)) {
return pick;
}
}
return null;
}
private fun mine(pickaxe: Pickaxe) {
mob.sendMessage("You swing your pick at the rock.")
mob.playAnimation(pickaxe.animation)
counter = pickaxe.pulses
mob.turnTo(position)
}
/**
* Returns the chance of mining being successful.
* Algorithm comes from: http://runescape.wikia.com/wiki/Talk:Mining#Mining_success_rate_formula
*/
private fun miningSuccessful(oreChance: Double, oreChanceOffset: Boolean, playerLevel: Int): Boolean {
val percent: Double
if (oreChanceOffset) {
percent = (oreChance * playerLevel + 1) * 100
} else {
percent = (oreChance * playerLevel) * 100
}
return rand.nextInt(100) < percent;
}
}
class ExpiredProspectingAction : DistancedAction<Player> {
constructor(mob: Player, position: Position) : super(PROSPECT_PULSES, true, mob, position, ORE_SIZE)
companion object {
private val PROSPECT_PULSES = 0
private val ORE_SIZE = 1;
}
override fun executeAction() {
mob.sendMessage("There is currently no ore available in this rock.")
stop();
}
}
class ProspectingAction(val m: Player, val p: Position, val ore: Ore) : DistancedAction<Player>(PROSPECT_PULSES, true, m, p, ORE_SIZE) {
companion object {
private val PROSPECT_PULSES = 3
private val ORE_SIZE = 1;
}
var started = false;
override fun executeAction() {
if (started) {
val oreName = ItemDefinition.lookup(ore.id).name.toLowerCase()
mob.sendMessage("This rock contains " + oreName + ".")
stop();
} else {
started = true
mob.sendMessage("You examine the rock for ores...")
mob.turnTo(position)
}
}
}
on {ObjectActionMessage::class}
.where {option == 1}
.then {
if (lookupOreRock(id) != null) {
it.startAction(MiningAction(it, id, this.position, lookupOreRock(id)!!))
}
}
on {ObjectActionMessage::class}
.where {option == 2}
.then {
if (lookupOreRock(id) != null) {
it.startAction(ProspectingAction(it, this.position, lookupOreRock(id)!!))
}
}
+32 -21
View File
@@ -1,4 +1,6 @@
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
@@ -7,33 +9,41 @@ Thanks to Clifton <http://www.rune-server.org/members/clifton/> for helping
to find some of the expired object IDs.
*/
data class Ore(id: Int, objects: Map<Int, Int>, level: Int, exp: Float, respawn: Int)
val ORE_OBJECTS = Array(
Ore(434, CLAY_OBJECTS, 1, 5, 3), // clay
Ore(436, COPPER_OBJECTS, 1, 17.5, 6), // copper
Ore(438, TIN_OBJECTS, 1, 17.5, 6), // tin
Ore(440, IRON_OBJECTS, 15, 35, 16), // iron
Ore(453, COAL_OBJECTS, 30, 50, 100), // coal
Ore(444, GOLD_OBJECTS, 40, 65, 200), // gold
Ore(442, SILVER_OBJECTS, 20, 40, 200), // silver
Ore(447, MITHRIL_OBJECTS, 55, 80, 400), // mithril
Ore(449, ADAMANT_OBJECTS, 70, 95, 800), // adamant
Ore(451, RUNITE_OBJECTS, 85, 125, 2500) // runite
)
/**
* 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)
}
val ORES = asMap()
val EXPIRED_ORES = asMap()
val ORES = Ore.values()
for (ore in ORE_OBJECTS) {
for (key in ore.objects.keys) {
ORES.put(key, ore)
EXPIRED_ORES.put(ore.objects.(get), true)
fun lookupOre(id: Int): Ore? = ORES.find { it.id == id }
fun lookupOreRock(id: Int): Ore? {
for (ore in ORES) {
for (rock in ore.objects) {
if (rock.key == id) {
return ore
}
}
}
return null
}
val CLAY_OBJECTS = mapOf(
2180 to 450,
2108 to 450,
2109 to 451,
14904 to 14896,
14905 to 14897
@@ -141,4 +151,5 @@ val RUNITE_OBJECTS = mapOf(
14859 to 14832,
14860 to 14833,
14861 to 14834
)
)
+19 -17
View File
@@ -1,21 +1,23 @@
package org.apollo.game.plugin.skills.mining
import org.apollo.game.model.Animation;
data class Pickaxe(id: Int, level: Int, animation: Animation, pulses: Int)
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)
}
val PICKAXES = Array(
Pickaxe(1265, 1, 625, 8), // bronze
Pickaxe(1267, 1, 626, 7), // iron
Pickaxe(1269, 1, 627, 6), // steel
Pickaxe(1273, 21, 629, 5), // mithril
Pickaxe(1271, 31, 628, 4), // adamant
Pickaxe(1275, 41, 624, 3) // rune
)
val PICKAXES = Pickaxe.values()
fun getPickaxes(): Array<Pickaxe> {
return PICKAXES
}
fun lookupPickaxe(id: Int): Pickaxe? = PICKAXES.find { it.id == id }
val PICKAXE_IDS: IntArray = intArrayOf(
1275, // rune
1271 // adamant
1273, // mithril
1269, // steel
1267, // iron
1265, // bronze
)
@@ -1,6 +0,0 @@
fun respawn_pulses(base: Int, players: Int) {
return base - players * base / (world.playerRepository.size() * 2);
}