mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Woodcutting now uses Async Action
This commit is contained in:
committed by
Gary Tierney
parent
3e6415f0d2
commit
da7c7e10b4
@@ -4,4 +4,5 @@ plugin {
|
||||
authors = [
|
||||
"tlf30"
|
||||
]
|
||||
dependencies = ["api"]
|
||||
}
|
||||
@@ -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,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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user