Fix all issues. Wood cutting now works.

This commit is contained in:
Trevor Flynn
2017-09-16 21:48:45 -07:00
committed by Gary Tierney
parent da7c7e10b4
commit 75a9b828b2
5 changed files with 109 additions and 123 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ plugin {
name = "woodcutting_skill" name = "woodcutting_skill"
packageName = "org.apollo.game.plugin.skills.woodcutting" packageName = "org.apollo.game.plugin.skills.woodcutting"
authors = [ authors = [
"tlf30" "tlf30"
] ]
dependencies = ["api"] dependencies = ["api"]
} }
-9
View File
@@ -1,9 +0,0 @@
name = "woodcutting-skill"
package = "org.apollo.game.plugin.skills.woodcutting"
authors = [
"tlf30"
]
[config]
srcDir = "src/"
testDir = "test/"
+9 -9
View File
@@ -2,7 +2,7 @@ package org.apollo.game.plugin.skills.woodcutting
import org.apollo.game.model.Animation; import org.apollo.game.model.Animation;
//Animation IDs: https://www.rune-server.ee/runescape-development/rs2-client/configuration/272373-emote-gfx-id-list.html //Animation IDs thanks to Deadly A G S at rune-server.ee
enum class Axe(val id: Int, val level: Int, val animation: Animation, val pulses: Int) { enum class Axe(val id: Int, val level: Int, val animation: Animation, val pulses: Int) {
RUNE(1359, 41, Animation(867), 3), RUNE(1359, 41, Animation(867), 3),
ADAMANT(1357, 31, Animation(869), 4), ADAMANT(1357, 31, Animation(869), 4),
@@ -10,14 +10,14 @@ enum class Axe(val id: Int, val level: Int, val animation: Animation, val pulses
BLACK(1361, 11, Animation(873), 6), BLACK(1361, 11, Animation(873), 6),
STEEL(1353, 6, Animation(875), 6), STEEL(1353, 6, Animation(875), 6),
IRON(1349, 1, Animation(877), 7), IRON(1349, 1, Animation(877), 7),
BRONZE(1351, 1, Animation(879), 8) BRONZE(1351, 1, Animation(879), 8);
companion object {
private val AXES = Axe.values()
fun getAxes(): Array<Axe> {
return AXES
}
}
} }
val AXES = Axe.values()
fun getAxes(): Array<Axe> {
return AXES
}
fun lookupPickaxe(id: Int): Axe? = AXES.find { it.id == id }
+54 -67
View File
@@ -1,85 +1,72 @@
package org.apollo.game.plugin.skills.woodcutting package org.apollo.game.plugin.skills.woodcutting
private val NORMAL_STUMP = 1342
private val ACHEY_STUMP = 3371
private val OAK_STUMP = 1342
private val WILLOW_STUMP = 1342
private val TEAK_STUMP = 1342
private val MAPLE_STUMP = 1342
private val MAHOGANY_STUMP = 1342
private val YEW_STUMP = 1342
private val MAGIC_STUMP = 1324
private val NORMAL_OBJECTS = hashSetOf(
1276, 1277, 1278, 1279, 1280, 1282, 1283, 1284, 1285, 1285, 1286, 1289, 1290, 1291, 1315,
1316, 1318, 1330, 1331, 1332, 1365, 1383, 1384, 2409, 3033, 3034, 3035, 3036, 3881, 3882,
3883, 5902, 5903, 5904, 10041
)
private val ACHEY_OBJECTS = hashSetOf(
2023
)
private val OAK_OBJECTS = hashSetOf(
1281, 3037
)
private val WILLOW_OBJECTS = hashSetOf(
5551, 5552, 5553
)
private val TEAK_OBJECTS = hashSetOf(
9036
)
private val MAPLE_OBJECTS = hashSetOf(
1307, 4674
)
private val MAHOGANY_OBJECTS = hashSetOf(
9034
)
private val YEW_OBJECTS = hashSetOf(
1309
)
private val MAGIC_OBJECTS = hashSetOf(
1292, 1306
)
/** /**
* values thanks to: http://oldschoolrunescape.wikia.com/wiki/Woodcutting * values thanks to: http://oldschoolrunescape.wikia.com/wiki/Woodcutting
*/ */
enum class Wood(val id: Int, val objects: IntArray, val stump: Int, val level: Int, val exp: Double, val chance: Double) { enum class Tree(val id: Int, val objects: HashSet<Int>, val stump: Int, val level: Int, val exp: Double, val chance: Double) {
NORMAL(1511, NORMAL_OBJECTS, NORMAL_STUMP, 1, 25.0, 100.0), NORMAL(1511, NORMAL_OBJECTS, NORMAL_STUMP, 1, 25.0, 100.0),
ACHEY(2862, ACHEY_OBJECTS, ACHEY_STUMP, 1, 25.0, 100.0), ACHEY(2862, ACHEY_OBJECTS, ACHEY_STUMP, 1, 25.0, 100.0),
OAK(1521, OAK_OBJECTS, OAK_STUMP, 15, 37.5, 0.125), OAK(1521, OAK_OBJECTS, OAK_STUMP, 15, 37.5, 0.125),
WILLOW(1519, WILLOW_OBJECTS, WILLOW_STUMP, 30, 67.5, 0.125), WILLOW(1519, WILLOW_OBJECTS, WILLOW_STUMP, 30, 67.5, 0.125),
TEAK(6333, TEAK_OBJECTS, TEAK_STUMP, 35, 85.0, 0.125), TEAK(6333, TEAK_OBJECTS, TEAK_STUMP, 35, 85.0, 0.125),
MAPLE(1517, MAPLE_OBJECTS, MAPLE_STUMP, 45, 100.0, 0.125), MAPLE(1517, MAPLE_OBJECTS, MAPLE_STUMP, 45, 100.0, 0.125),
MAHOGANY(6332, MAHOGANY_OBJECTS, MAHOGANY_STUMP, 50, 125.0,0.125), MAHOGANY(6332, MAHOGANY_OBJECTS, MAHOGANY_STUMP, 50, 125.0, 0.125),
YEW(1515, YEW_OBJECTS, YEW_STUMP, 60, 175.0, 0.125), YEW(1515, YEW_OBJECTS, YEW_STUMP, 60, 175.0, 0.125),
MAGIC(1513, MAGIC_OBJECTS, MAGIC_STUMP, 75, 250.0, 0.125), MAGIC(1513, MAGIC_OBJECTS, MAGIC_STUMP, 75, 250.0, 0.125);
}
val WOOD = Wood.values() companion object {
private val TREES = Tree.values().flatMap { tree -> tree.objects.map { Pair(it, tree) } }.toMap()
fun lookupWood(id: Int): Wood? =WOOD.find { it.id == id } fun lookup(id: Int): Tree? = TREES[id]
fun lookupTree(id: Int): Wood? {
for (wood in WOOD) {
for (tree in wood.objects) {
if (tree == id) {
return wood
}
}
} }
return null
} }
val NORMAL_STUMP = 1342
val ACHEY_STUMP = 3371
val OAK_STUMP = 1342
val WILLOW_STUMP = 1342
val TEAK_STUMP = 1342
val MAPLE_STUMP = 1342
val MAHOGANY_STUMP = 1342
val YEW_STUMP = 1342
val MAGIC_STUMP = 1324
val NORMAL_OBJECTS = intArrayOf(
1276, 1277, 1278, 1279, 1280, 1282, 1283, 1284, 1285, 1285, 1286, 1289, 1290, 1291, 1315,
1316, 1318, 1330, 1331, 1332, 1365, 1383, 1384, 2409, 3033, 3034, 3035, 3036, 3881, 3882,
3883, 5902, 5903, 5904, 10041
)
val ACHEY_OBJECTS = intArrayOf(
2023
)
val OAK_OBJECTS = intArrayOf(
1281, 3037
)
val WILLOW_OBJECTS = intArrayOf(
5551, 5552, 5553
)
val TEAK_OBJECTS = intArrayOf(
9036
)
val MAPLE_OBJECTS = intArrayOf(
1307, 4674
)
val MAHOGANY_OBJECTS = intArrayOf(
9034
)
val YEW_OBJECTS = intArrayOf(
1309
)
val MAGIC_OBJECTS = intArrayOf(
1292, 1306
)
@@ -1,4 +1,5 @@
import org.apollo.cache.def.ItemDefinition import org.apollo.cache.def.ItemDefinition
import org.apollo.game.GameConstants
import org.apollo.game.action.AsyncDistancedAction import org.apollo.game.action.AsyncDistancedAction
import org.apollo.game.message.impl.ObjectActionMessage import org.apollo.game.message.impl.ObjectActionMessage
import org.apollo.game.model.Position import org.apollo.game.model.Position
@@ -7,34 +8,41 @@ import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.Skill import org.apollo.game.model.entity.Skill
import org.apollo.game.model.entity.obj.GameObject import org.apollo.game.model.entity.obj.GameObject
import org.apollo.game.plugin.skills.woodcutting.* import org.apollo.game.plugin.skills.woodcutting.*
import org.apollo.game.plugins.api.Definitions
import org.apollo.game.plugins.api.woodcutting import org.apollo.game.plugins.api.woodcutting
import org.apollo.game.plugins.api.skills import org.apollo.game.plugins.api.skills
import org.apollo.game.scheduling.ScheduledTask
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit
class WoodcuttingTarget(val objectId: Int, val position: Position, val wood: Wood) { class WoodcuttingTarget(val objectId: Int, val position: Position, val tree: Tree) {
/**
* Get the tree object in the world
*/
fun getObject(world: World): Optional<GameObject> { fun getObject(world: World): Optional<GameObject> {
val region = world.regionRepository.fromPosition(position) val region = world.regionRepository.fromPosition(position)
val obj = region.findObject(position, objectId) return region.findObject(position, objectId)
return obj
} }
fun isSuccessful(mob: Player): Boolean { /**
return rand(100) <= wood.chance * 100 * Check if the tree was cut down
*/
fun isCutDown(mob: Player): Boolean {
return rand(100) <= tree.chance * 100
} }
} }
class WoodcuttingAction(val player: Player, val tool: Axe, val target: WoodcuttingTarget) : AsyncDistancedAction<Player>(PULSES, true, player, target.position, TREE_SIZE) { class WoodcuttingAction(val player: Player, val tool: Axe, val target: WoodcuttingTarget) : AsyncDistancedAction<Player>(DELAY, true, player, target.position, TREE_SIZE) {
companion object { companion object {
private val PULSES = 0 private val DELAY = 0
private val TREE_SIZE = 1; private val TREE_SIZE = 2
private val MINIMUM_RESPAWN_TIME = 30L //In seconds
fun axeFor(player: Player): Axe? { /**
return AXES * Find the highest level axe the player has
*/
private fun axeFor(player: Player): Axe? {
return getAxes()
.filter { it.level <= player.skills.woodcutting.currentLevel } .filter { it.level <= player.skills.woodcutting.currentLevel }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) } .filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level } .sortedByDescending { it.level }
@@ -44,27 +52,30 @@ class WoodcuttingAction(val player: Player, val tool: Axe, val target: Woodcutti
/** /**
* Starts a [WoodcuttingAction] for the specified [Player], terminating the [Message] that triggered it. * Starts a [WoodcuttingAction] for the specified [Player], terminating the [Message] that triggered it.
*/ */
fun start(message: ObjectActionMessage, player: Player, wood: Wood) { fun start(message: ObjectActionMessage, player: Player, wood: Tree) {
val axe = axeFor(player) val axe = axeFor(player)
if (axe != null) { if (axe != null) {
//Check that the player had room in their inventory
if (player.inventory.freeSlots() == 0) {
player.inventory.forceCapacityExceeded()
return
}
val action = WoodcuttingAction(player, axe, WoodcuttingTarget(message.id, message.position, wood)) val action = WoodcuttingAction(player, axe, WoodcuttingTarget(message.id, message.position, wood))
player.startAction(action) player.startAction(action)
} else { } else {
player.sendMessage("You do not have a axe for which you have the level to use.") player.sendMessage("You do not have an axe for which you have the level to use.")
} }
message.terminate() message.terminate()
} }
} }
override fun start() { override fun start() {
mob.turnTo(position) mob.turnTo(position)
val level = mob.skills.woodcutting.currentLevel val level = mob.skills.woodcutting.currentLevel
if (level < target.wood.level) { if (level < target.tree.level) {
mob.sendMessage("You do not have the required level to cut down this tree.") mob.sendMessage("You do not have the required level to cut down this tree.")
stop() stop()
} }
@@ -75,39 +86,36 @@ class WoodcuttingAction(val player: Player, val tool: Axe, val target: Woodcutti
mob.playAnimation(tool.animation) mob.playAnimation(tool.animation)
wait(tool.pulses) wait(tool.pulses)
//
//Check that the object exists in the world
val obj = target.getObject(mob.world) val obj = target.getObject(mob.world)
if (!obj.isPresent) { if (!obj.isPresent) {
stop() stop()
return return
} }
if (mob.inventory.freeSlots() == 0) { if (mob.inventory.add(target.tree.id)) {
mob.inventory.forceCapacityExceeded()
stop()
return
}
if (mob.inventory.add(target.wood.id)) {
//TODO: Use lookup from utils once it has a lookup function for IDs //TODO: Use lookup from utils once it has a lookup function for IDs
val woodName = ItemDefinition.lookup(target.wood.id).name.toLowerCase(); val logName = ItemDefinition.lookup(target.tree.id).name.toLowerCase();
mob.sendMessage("You managed to cut some $woodName.") mob.sendMessage("You managed to cut some $logName.")
mob.skillSet.addExperience(Skill.WOODCUTTING, target.wood.exp) mob.skillSet.addExperience(Skill.WOODCUTTING, target.tree.exp)
} }
if (target.isSuccessful(mob)) { //Check if the tree was cut down. If it was, we stop the task.
if (target.isCutDown(mob)) {
//respawn time: http://runescape.wikia.com/wiki/Trees //respawn time: http://runescape.wikia.com/wiki/Trees
val respawn = ((30 * 1000) / 600) + ((rand(150) * 1000) / 600) // between 30 sec and 3 min respawm val respawn = TimeUnit.SECONDS.toMillis(MINIMUM_RESPAWN_TIME + rand(150)) / GameConstants.PULSE_DELAY
mob.world.expireObject(obj.get(), target.wood.stump, respawn) mob.world.expireObject(obj.get(), target.tree.stump, respawn.toInt())
stop()
} }
} }
} }
on { ObjectActionMessage::class } on { ObjectActionMessage::class }
.where { option == 1 } .where { option == 1 }
.then { .then {
val wood = lookupTree(id) val tree = Tree.lookup(id)
if (wood != null) { if (tree != null) {
WoodcuttingAction.start(this, it, wood) WoodcuttingAction.start(this, it, tree)
}
} }
}