diff --git a/game/plugin/skills/mining/src/MiningAction.kt b/game/plugin/skills/mining/src/MiningAction.kt index 0f159b388..e19f6a476 100644 --- a/game/plugin/skills/mining/src/MiningAction.kt +++ b/game/plugin/skills/mining/src/MiningAction.kt @@ -1,22 +1,22 @@ -import java.util.* + import org.apollo.game.action.ActionBlock import org.apollo.game.action.AsyncDistancedAction import org.apollo.game.message.impl.ObjectActionMessage import org.apollo.game.model.entity.Player -import org.apollo.game.plugin.api.* +import org.apollo.game.plugin.api.rand import org.apollo.game.plugin.skills.mining.Ore import org.apollo.game.plugin.skills.mining.Pickaxe import org.apollo.net.message.Message +import java.util.Objects class MiningAction( player: Player, - private val tool: Pickaxe, + private val tool: Pickaxe?, private val target: MiningTarget -) : AsyncDistancedAction(PULSES, true, player, target.position, ORE_SIZE) { +) : AsyncDistancedAction(PULSES, true, player, target.position, target.ore.objectSize) { companion object { private const val PULSES = 0 - private const val ORE_SIZE = 1 /** * Starts a [MiningAction] for the specified [Player], terminating the [Message] that triggered it. @@ -24,14 +24,10 @@ class MiningAction( fun start(message: ObjectActionMessage, player: Player, ore: Ore) { val pickaxe = Pickaxe.bestFor(player) - if (pickaxe == null) { - player.sendMessage("You do not have a pickaxe for which you have the level to use.") - } else { - val target = MiningTarget(message.id, message.position, ore) - val action = MiningAction(player, pickaxe, target) + val target = MiningTarget(message.id, message.position, ore) + val action = MiningAction(player, pickaxe, target) - player.startAction(action) - } + player.startAction(action) message.terminate() } @@ -40,33 +36,43 @@ class MiningAction( override fun action(): ActionBlock = { mob.turnTo(position) + if (tool == null) { + mob.sendMessage("You do not have a pickaxe for which you have the level to use.") + stop() + } + if (!target.skillRequirementsMet(mob)) { mob.sendMessage("You do not have the required level to mine this rock.") stop() } mob.sendMessage("You swing your pick at the rock.") - mob.playAnimation(tool.animation) - wait(tool.pulses) + while (isRunning) { + mob.playAnimation(tool.animation) - if (!target.isValid(mob.world)) { - stop() - } - - val successChance = rand(100) + wait(tool.pulses) - if (target.isSuccessful(mob, successChance)) { - if (mob.inventory.freeSlots() == 0) { - mob.inventory.forceCapacityExceeded() + if (!target.isValid(mob.world)) { stop() } - if (target.reward(mob)) { - mob.sendMessage("You manage to mine some ${target.oreName()}") - target.deplete(mob.world) + val successChance = rand(100) - stop() + if (target.isSuccessful(mob, successChance)) { + if (mob.inventory.freeSlots() == 0) { + mob.inventory.forceCapacityExceeded() + stop() + } + + if (target.reward(mob)) { + mob.sendMessage("You manage to mine some ${target.oreName(mob)}") + + if (target.ore.respawn != -1) { + target.deplete(mob.world) + stop() + } + } } } } diff --git a/game/plugin/skills/mining/src/MiningTarget.kt b/game/plugin/skills/mining/src/MiningTarget.kt index 5bbe1b4a1..48c34825b 100644 --- a/game/plugin/skills/mining/src/MiningTarget.kt +++ b/game/plugin/skills/mining/src/MiningTarget.kt @@ -6,6 +6,8 @@ import org.apollo.game.plugin.api.findObject import org.apollo.game.plugin.api.mining import org.apollo.game.plugin.api.replaceObject import org.apollo.game.plugin.skills.mining.Ore +import org.apollo.game.plugin.skills.mining.PURE_ESSENCE +import org.apollo.game.plugin.skills.mining.RUNE_ESSENCE data class MiningTarget(val objectId: Int, val position: Position, val ore: Ore) { @@ -35,13 +37,22 @@ data class MiningTarget(val objectId: Int, val position: Position, val ore: Ore) /** * Get the normalized name of the [Ore] represented by this target. */ - fun oreName() = Definitions.item(ore.id).name.toLowerCase() + fun oreName(mob: Player) = Definitions.item(oreReward(mob)).name.toLowerCase() + + /** + * Get the item id for the [Ore]. + */ + fun oreReward(mob: Player): Int = when (ore) { + Ore.ESSENCE -> if (mob.isMembers && mob.mining.current >= 30) PURE_ESSENCE else RUNE_ESSENCE + else -> ore.id + } /** * Reward a [player] with experience and ore if they have the inventory capacity to take a new ore. */ fun reward(player: Player): Boolean { - val hasInventorySpace = player.inventory.add(ore.id) + val itemId = oreReward(player) + val hasInventorySpace = player.inventory.add(itemId) if (hasInventorySpace) { player.mining.experience += ore.exp @@ -54,5 +65,5 @@ data class MiningTarget(val objectId: Int, val position: Position, val ore: Ore) * Check if the [mob] has met the skill requirements to mine te [Ore] represented by * this [MiningTarget]. */ - fun skillRequirementsMet(mob: Player) = mob.mining.current < ore.level + fun skillRequirementsMet(mob: Player) = mob.mining.current >= ore.level } \ No newline at end of file diff --git a/game/plugin/skills/mining/src/Ore.kt b/game/plugin/skills/mining/src/Ore.kt index 1f4a94ff9..e130a3d6f 100644 --- a/game/plugin/skills/mining/src/Ore.kt +++ b/game/plugin/skills/mining/src/Ore.kt @@ -17,8 +17,11 @@ enum class Ore( val exp: Double, val respawn: Int, val chance: Double, - val chanceOffset: Double = 0.0 + val chanceOffset: Double = 0.0, + val prospectName: String? = null, + val objectSize: Int = 1 ) { + ESSENCE(ESSENCE_OBJECTS, id = -1, level = 1, exp = 5.0, respawn = -1, chance = 0.0085, chanceOffset = 0.45, prospectName = "Rune Stone essence", objectSize = 7), CLAY(CLAY_OBJECTS, id = 434, level = 1, exp = 5.0, respawn = 1, chance = 0.0085, chanceOffset = 0.45), COPPER(COPPER_OBJECTS, id = 436, level = 1, exp = 17.5, respawn = 4, chance = 0.0085, chanceOffset = 0.45), TIN(TIN_OBJECTS, id = 438, level = 1, exp = 17.5, respawn = 4, chance = 0.0085, chanceOffset = 0.45), @@ -39,6 +42,9 @@ enum class Ore( } } +const val RUNE_ESSENCE = 1436 +const val PURE_ESSENCE = 7936 + // Maps from regular rock id to expired rock id. val CLAY_OBJECTS = mapOf( @@ -150,4 +156,8 @@ val RUNITE_OBJECTS = mapOf( 14859 to 14832, 14860 to 14833, 14861 to 14834 +) + +val ESSENCE_OBJECTS = mapOf( + 2491 to -1 ) \ No newline at end of file diff --git a/game/plugin/skills/mining/src/ProspectingAction.kt b/game/plugin/skills/mining/src/ProspectingAction.kt index 10bf83a11..34de4a294 100644 --- a/game/plugin/skills/mining/src/ProspectingAction.kt +++ b/game/plugin/skills/mining/src/ProspectingAction.kt @@ -1,4 +1,4 @@ -import java.util.Objects + import org.apollo.game.action.ActionBlock import org.apollo.game.action.AsyncDistancedAction import org.apollo.game.message.impl.ObjectActionMessage @@ -7,16 +7,16 @@ import org.apollo.game.model.entity.Player import org.apollo.game.plugin.api.Definitions import org.apollo.game.plugin.skills.mining.Ore import org.apollo.net.message.Message +import java.util.Objects class ProspectingAction( player: Player, position: Position, private val ore: Ore -) : AsyncDistancedAction(DELAY, true, player, position, ORE_SIZE) { +) : AsyncDistancedAction(DELAY, true, player, position, ore.objectSize) { companion object { private const val DELAY = 3 - private const val ORE_SIZE = 1 /** * Starts a [MiningAction] for the specified [Player], terminating the [Message] that triggered it. @@ -35,7 +35,7 @@ class ProspectingAction( wait() - val oreName = Definitions.item(ore.id)?.name?.toLowerCase() + val oreName = ore.prospectName ?: Definitions.item(ore.id).name?.toLowerCase() mob.sendMessage("This rock contains $oreName.") stop() diff --git a/game/plugin/skills/mining/test/TestData.kt b/game/plugin/skills/mining/test/TestData.kt index aa798d24a..022f7adaf 100644 --- a/game/plugin/skills/mining/test/TestData.kt +++ b/game/plugin/skills/mining/test/TestData.kt @@ -1,13 +1,15 @@ -import java.util.stream.Stream + import org.apollo.game.plugin.skills.mining.Ore import org.junit.jupiter.api.extension.ExtensionContext import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.ArgumentsProvider +import java.util.stream.Stream data class MiningTestData(val rockId: Int, val expiredRockId: Int, val ore: Ore) fun miningTestData(): Collection = Ore.values() - .flatMap { ore -> ore.objects.map { MiningTestData(it.key, it.value, ore) } } + .filter { it.id != -1 } + .flatMap { ore -> ore.objects.filter { it.value != -1 }.map { MiningTestData(it.key, it.value, ore) } } .toList() class MiningTestDataProvider : ArgumentsProvider {