diff --git a/game/plugin/skills/woodcutting/build.gradle b/game/plugin/skills/woodcutting/build.gradle index 886112d7..d52d61ca 100644 --- a/game/plugin/skills/woodcutting/build.gradle +++ b/game/plugin/skills/woodcutting/build.gradle @@ -4,4 +4,5 @@ plugin { authors = [ "tlf30" ] + dependencies = ["api"] } \ No newline at end of file diff --git a/game/plugin/skills/woodcutting/src/axe.kt b/game/plugin/skills/woodcutting/src/axe.kt index ae3e11a7..02ad7d36 100644 --- a/game/plugin/skills/woodcutting/src/axe.kt +++ b/game/plugin/skills/woodcutting/src/axe.kt @@ -1,4 +1,4 @@ -package org.apollo.game.plugin.skills.mining +package org.apollo.game.plugin.skills.woodcutting import org.apollo.game.model.Animation; diff --git a/game/plugin/skills/woodcutting/src/wood.kt b/game/plugin/skills/woodcutting/src/wood.kt index 6201d8cd..550b98ca 100644 --- a/game/plugin/skills/woodcutting/src/wood.kt +++ b/game/plugin/skills/woodcutting/src/wood.kt @@ -1,4 +1,4 @@ -package org.apollo.game.plugin.skills.mining +package org.apollo.game.plugin.skills.woodcutting /** diff --git a/game/plugin/skills/woodcutting/src/woodcutting.plugin.kts b/game/plugin/skills/woodcutting/src/woodcutting.plugin.kts index 8b5d0a48..9facda64 100644 --- a/game/plugin/skills/woodcutting/src/woodcutting.plugin.kts +++ b/game/plugin/skills/woodcutting/src/woodcutting.plugin.kts @@ -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(PULSES, true, player, p, TREE_SIZE) { +class WoodcuttingTarget(val objectId: Int, val position: Position, val wood: Wood) { + + fun getObject(world: World): Optional { + 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(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) } }