mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-06 00:38:18 +00:00
106 lines
3.5 KiB
Kotlin
106 lines
3.5 KiB
Kotlin
|
|
import org.apollo.game.GameConstants
|
|
import org.apollo.game.action.ActionBlock
|
|
import org.apollo.game.action.AsyncDistancedAction
|
|
import org.apollo.game.message.impl.ObjectActionMessage
|
|
import org.apollo.game.model.Position
|
|
import org.apollo.game.model.World
|
|
import org.apollo.game.model.entity.Player
|
|
import org.apollo.game.model.entity.obj.GameObject
|
|
import org.apollo.game.plugin.api.*
|
|
import org.apollo.game.plugin.skills.woodcutting.Axe
|
|
import org.apollo.game.plugin.skills.woodcutting.Tree
|
|
import java.util.concurrent.TimeUnit
|
|
|
|
// TODO Accurate chopping rates, e.g. https://twitter.com/JagexKieren/status/713403124464107520
|
|
|
|
on { ObjectActionMessage::class }
|
|
.where { option == 1 }
|
|
.then { player ->
|
|
Tree.lookup(id)?.let { WoodcuttingAction.start(this, player, it) }
|
|
}
|
|
|
|
class WoodcuttingTarget(private val objectId: Int, val position: Position, val tree: Tree) {
|
|
|
|
/**
|
|
* Get the tree object in the world
|
|
*/
|
|
fun getObject(world: World): GameObject? {
|
|
return world.findObject(position, objectId)
|
|
}
|
|
|
|
/**
|
|
* Returns whether or not the tree was cut down.
|
|
*/
|
|
fun isCutDown(): Boolean = rand(100) <= tree.chance * 100
|
|
|
|
}
|
|
|
|
class WoodcuttingAction(
|
|
player: Player,
|
|
private val tool: Axe,
|
|
private val target: WoodcuttingTarget
|
|
) : AsyncDistancedAction<Player>(DELAY, true, player, target.position, TREE_SIZE) {
|
|
|
|
companion object {
|
|
private const val DELAY = 0
|
|
private const val TREE_SIZE = 2
|
|
private const val MINIMUM_RESPAWN_TIME = 30L // In seconds
|
|
|
|
/**
|
|
* Starts a [WoodcuttingAction] for the specified [Player], terminating the [ObjectActionMessage] that triggered
|
|
* it.
|
|
*/
|
|
fun start(message: ObjectActionMessage, player: Player, wood: Tree) {
|
|
val axe = Axe.bestFor(player)
|
|
if (axe != null) {
|
|
if (player.inventory.freeSlots() == 0) {
|
|
player.inventory.forceCapacityExceeded()
|
|
return
|
|
}
|
|
|
|
val action = WoodcuttingAction(player, axe, WoodcuttingTarget(message.id, message.position, wood))
|
|
player.startAction(action)
|
|
} else {
|
|
player.sendMessage("You do not have an axe for which you have the level to use.")
|
|
}
|
|
|
|
message.terminate()
|
|
}
|
|
}
|
|
|
|
override fun action(): ActionBlock = {
|
|
mob.turnTo(position)
|
|
|
|
val level = mob.woodcutting.current
|
|
if (level < target.tree.level) {
|
|
mob.sendMessage("You do not have the required level to cut down this tree.")
|
|
stop()
|
|
}
|
|
|
|
while (isRunning) {
|
|
mob.sendMessage("You swing your axe at the tree.")
|
|
mob.playAnimation(tool.animation)
|
|
|
|
wait(tool.pulses)
|
|
|
|
// Check that the object exists in the world
|
|
val obj = target.getObject(mob.world) ?: stop()
|
|
|
|
if (mob.inventory.add(target.tree.id)) {
|
|
val logName = Definitions.item(target.tree.id)!!.name.toLowerCase()
|
|
mob.sendMessage("You managed to cut some $logName.")
|
|
mob.woodcutting.experience += target.tree.exp
|
|
}
|
|
|
|
if (target.isCutDown()) {
|
|
// respawn time: http://runescape.wikia.com/wiki/Trees
|
|
val respawn = TimeUnit.SECONDS.toMillis(MINIMUM_RESPAWN_TIME + rand(150)) / GameConstants.PULSE_DELAY
|
|
|
|
mob.world.expireObject(obj, target.tree.stump, respawn.toInt())
|
|
stop()
|
|
}
|
|
}
|
|
}
|
|
|
|
} |