Woodcutting now uses Async Action

This commit is contained in:
Trevor Flynn
2017-09-16 21:26:29 -07:00
committed by Gary Tierney
parent 3e6415f0d2
commit da7c7e10b4
4 changed files with 87 additions and 136 deletions
@@ -4,4 +4,5 @@ plugin {
authors = [
"tlf30"
]
dependencies = ["api"]
}
+1 -1
View File
@@ -1,4 +1,4 @@
package org.apollo.game.plugin.skills.mining
package org.apollo.game.plugin.skills.woodcutting
import org.apollo.game.model.Animation;
+1 -1
View File
@@ -1,4 +1,4 @@
package org.apollo.game.plugin.skills.mining
package org.apollo.game.plugin.skills.woodcutting
/**
@@ -1,163 +1,113 @@
import org.apollo.cache.def.ItemDefinition
import org.apollo.game.action.DistancedAction
import org.apollo.game.action.AsyncDistancedAction
import org.apollo.game.message.impl.ObjectActionMessage
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.World
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.model.entity.obj.GameObject
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.skills
import org.apollo.game.scheduling.ScheduledTask
import java.util.*
class WoodcuttingAction(val player: Player, val objectID: Int, val p: Position, val wood: Wood) : DistancedAction<Player>(PULSES, true, player, p, TREE_SIZE) {
class WoodcuttingTarget(val objectId: Int, val position: Position, val wood: Wood) {
fun getObject(world: World): Optional<GameObject> {
val region = world.regionRepository.fromPosition(position)
val obj = region.findObject(position, objectId)
return obj
}
fun isSuccessful(mob: Player): Boolean {
return rand(100) <= wood.chance * 100
}
}
class WoodcuttingAction(val player: Player, val tool: Axe, val target: WoodcuttingTarget) : AsyncDistancedAction<Player>(PULSES, true, player, target.position, TREE_SIZE) {
companion object {
private val PULSES = 0
private val TREE_SIZE = 1;
}
private var counter: Int = 0
private var started: Boolean = false
private val rand: Random = Random()
override fun executeAction() {
System.out.println("Cutting " + wood.id + " @ " + p)
val level = mob.skillSet.getSkill(Skill.WOODCUTTING).currentLevel
val axe = findAxe()
//check that our pick can mine the wood
if (axe == null || level < axe.level) {
mob.sendMessage("You do not have a axe for which you have the level to use.")
stop()
return
fun axeFor(player: Player): Axe? {
return AXES
.filter { it.level <= player.skills.woodcutting.currentLevel }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level }
.firstOrNull()
}
//check that we can mine the wood
if (level < wood.level) {
mob.sendMessage("You do not have the required level to mine this rock.")
stop()
return
}
//start the process of cutting
if (started) {
if (counter == 0) {
//Check inv capacity
if (mob.inventory.freeSlots() == 0) {
mob.inventory.forceCapacityExceeded()
stop()
return
}
if (mob.inventory.add(wood.id)) {
//TODO: Use lookup from utils once it has a lookup function for IDs
val woodName = ItemDefinition.lookup(wood.id).name.toLowerCase();
mob.sendMessage("You managed to cut some " + woodName + ".")
mob.skillSet.addExperience(Skill.WOODCUTTING, wood.exp)
} else {
System.out.println("Failed to add wood to inv");
stop();
return;
}
if (!cuttingSuccessful(wood.chance)) {
System.out.println("Chopping...")
cut(axe)
return //We did not cut down the tree... Keep going
} else {
//We cut down the tree
var treeEntity: StaticGameObject? = null
val region = mob.world.regionRepository.fromPosition(position)
val entities = region.getEntities(position)
for (entity: Entity in entities) {
if (entity is StaticGameObject) {
System.out.println("Entity at cutting location: " + entity.id + " with type: " + entity.entityType)
if (entity.id == objectID) {
treeEntity = entity
}
}
}
if (treeEntity == null) { //tree entity not found at location...
System.out.println("WARNING: Invalid cutting condition on tree");
stop()
return
}
//Get ID of exipred wood
val expiredObjectID = wood.stump;
val expiredRockEntity = StaticGameObject(mob.world, expiredObjectID!!, position, treeEntity!!.type, treeEntity!!.orientation)
//Remove normal wood and replace with expired
System.out.println("Removing " + objectID + " addding " + expiredObjectID)
System.out.println("Adding tasks")
//add task to remove normal wood and replace with depleted
mob.world.schedule(object: ScheduledTask(0, true) {
override fun execute() {
System.out.println("running deplete task")
//Replace normal wood with expired wood
region.removeEntity(treeEntity);
region.addEntity(expiredRockEntity)
this.stop() //Makes task run once
}
})
//add task to respawn normal wood
//respawn time: http://runescape.wikia.com/wiki/Trees
val respawn = ((30 * 1000) / 600) + ((rand.nextInt(150) * 1000) / 600) // between 30 sec and 3 min respawm
mob.world.schedule(object: ScheduledTask(respawn, false) {
override fun execute() {
System.out.println("running wood task")
//Replace expired wood with normal wood
region.removeEntity(expiredRockEntity)
region.addEntity(treeEntity);
this.stop() //Makes task run once
}
})
stop()
return
}
/**
* Starts a [WoodcuttingAction] for the specified [Player], terminating the [Message] that triggered it.
*/
fun start(message: ObjectActionMessage, player: Player, wood: Wood) {
val axe = axeFor(player)
if (axe != null) {
val action = WoodcuttingAction(player, axe, WoodcuttingTarget(message.id, message.position, wood))
player.startAction(action)
} else {
player.sendMessage("You do not have a axe for which you have the level to use.")
}
counter -= 1
} else {
started = true
cut(axe)
message.terminate()
}
}
private fun findAxe(): Axe? {
for (axe in getAxes()) {
if (axe!!.level > mob.skillSet.getSkill(Skill.WOODCUTTING).currentLevel) {
continue;
}
val weponSlot = mob.equipment.get(EquipmentConstants.WEAPON)
if (weponSlot != null && weponSlot.id == axe.id) {
return axe;
} else if (mob.inventory.contains(axe.id)) {
return axe;
}
}
return null;
}
private fun cut(axe: Axe) {
mob.sendMessage("You swing your axe at the tree.")
mob.playAnimation(axe.animation)
counter = axe.pulses
override fun start() {
mob.turnTo(position)
val level = mob.skills.woodcutting.currentLevel
if (level < target.wood.level) {
mob.sendMessage("You do not have the required level to cut down this tree.")
stop()
}
}
private fun cuttingSuccessful(woodChance: Double): Boolean {
return rand.nextInt(100) <= woodChance * 100;
override suspend fun executeActionAsync() {
mob.sendMessage("You swing your axe at the tree.")
mob.playAnimation(tool.animation)
wait(tool.pulses)
//
val obj = target.getObject(mob.world)
if (!obj.isPresent) {
stop()
return
}
if (mob.inventory.freeSlots() == 0) {
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
val woodName = ItemDefinition.lookup(target.wood.id).name.toLowerCase();
mob.sendMessage("You managed to cut some $woodName.")
mob.skillSet.addExperience(Skill.WOODCUTTING, target.wood.exp)
}
if (target.isSuccessful(mob)) {
//respawn time: http://runescape.wikia.com/wiki/Trees
val respawn = ((30 * 1000) / 600) + ((rand(150) * 1000) / 600) // between 30 sec and 3 min respawm
mob.world.expireObject(obj.get(), target.wood.stump, respawn)
}
}
}
on {ObjectActionMessage::class}
.where {option == 1}
on { ObjectActionMessage::class }
.where { option == 1 }
.then {
if (lookupTree(id) != null) {
it.startAction(WoodcuttingAction(it, id, this.position, lookupTree(id)!!))
} else {
System.out.println("Unknown wood: " + id)
val wood = lookupTree(id)
if (wood != null) {
WoodcuttingAction.start(this, it, wood)
}
}