Add skill extension properties

This commit is contained in:
Major
2017-09-24 19:44:17 +01:00
parent 8c2f086ae5
commit b4e8a7136b
5 changed files with 161 additions and 103 deletions
@@ -1,28 +0,0 @@
package org.apollo.game.plugins.api
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.Skill
import org.apollo.game.model.entity.SkillSet
val Player.skills: SkillSet get() = skillSet
val SkillSet.attack: Skill get() = getSkill(Skill.ATTACK)
val SkillSet.defence: Skill get() = getSkill(Skill.DEFENCE)
val SkillSet.strength: Skill get() = getSkill(Skill.STRENGTH)
val SkillSet.hitpoints: Skill get() = getSkill(Skill.HITPOINTS)
val SkillSet.ranged: Skill get() = getSkill(Skill.RANGED)
val SkillSet.prayer: Skill get() = getSkill(Skill.PRAYER)
val SkillSet.magic: Skill get() = getSkill(Skill.MAGIC)
val SkillSet.cooking: Skill get() = getSkill(Skill.COOKING)
val SkillSet.woodcutting: Skill get() = getSkill(Skill.WOODCUTTING)
val SkillSet.fletching: Skill get() = getSkill(Skill.FLETCHING)
val SkillSet.fishing: Skill get() = getSkill(Skill.FISHING)
val SkillSet.firemaking: Skill get() = getSkill(Skill.FIREMAKING)
val SkillSet.crafting: Skill get() = getSkill(Skill.CRAFTING)
val SkillSet.smithing: Skill get() = getSkill(Skill.SMITHING)
val SkillSet.mining: Skill get() = getSkill(Skill.MINING)
val SkillSet.herblore: Skill get() = getSkill(Skill.HERBLORE)
val SkillSet.agility: Skill get() = getSkill(Skill.AGILITY)
val SkillSet.thieving: Skill get() = getSkill(Skill.THIEVING)
val SkillSet.slayer: Skill get() = getSkill(Skill.SLAYER)
val SkillSet.farming: Skill get() = getSkill(Skill.FARMING)
val SkillSet.runecraft: Skill get() = getSkill(Skill.RUNECRAFT)
+81
View File
@@ -0,0 +1,81 @@
package org.apollo.game.plugin.api
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.Skill
import org.apollo.game.model.entity.SkillSet
val Player.attack: SkillProxy get() = SkillProxy(skillSet, Skill.ATTACK)
val Player.defence: SkillProxy get() = SkillProxy(skillSet, Skill.DEFENCE)
val Player.strength: SkillProxy get() = SkillProxy(skillSet, Skill.STRENGTH)
val Player.hitpoints: SkillProxy get() = SkillProxy(skillSet, Skill.HITPOINTS)
val Player.ranged: SkillProxy get() = SkillProxy(skillSet, Skill.RANGED)
val Player.prayer: SkillProxy get() = SkillProxy(skillSet, Skill.PRAYER)
val Player.magic: SkillProxy get() = SkillProxy(skillSet, Skill.MAGIC)
val Player.cooking: SkillProxy get() = SkillProxy(skillSet, Skill.COOKING)
val Player.woodcutting: SkillProxy get() = SkillProxy(skillSet, Skill.WOODCUTTING)
val Player.fletching: SkillProxy get() = SkillProxy(skillSet, Skill.FLETCHING)
val Player.fishing: SkillProxy get() = SkillProxy(skillSet, Skill.FISHING)
val Player.firemaking: SkillProxy get() = SkillProxy(skillSet, Skill.FIREMAKING)
val Player.crafting: SkillProxy get() = SkillProxy(skillSet, Skill.CRAFTING)
val Player.smithing: SkillProxy get() = SkillProxy(skillSet, Skill.SMITHING)
val Player.mining: SkillProxy get() = SkillProxy(skillSet, Skill.MINING)
val Player.herblore: SkillProxy get() = SkillProxy(skillSet, Skill.HERBLORE)
val Player.agility: SkillProxy get() = SkillProxy(skillSet, Skill.AGILITY)
val Player.thieving: SkillProxy get() = SkillProxy(skillSet, Skill.THIEVING)
val Player.slayer: SkillProxy get() = SkillProxy(skillSet, Skill.SLAYER)
val Player.farming: SkillProxy get() = SkillProxy(skillSet, Skill.FARMING)
val Player.runecraft: SkillProxy get() = SkillProxy(skillSet, Skill.RUNECRAFT)
/**
* A proxy class to allow
*/
class SkillProxy(val skills: SkillSet, val skill: Int) {
/**
* The maximum level of this skill.
*/
val maximum = skills.getMaximumLevel(skill)
/**
* The current level of this skill.
*/
val current = skills.getCurrentLevel(skill)
val experience = ExperienceProxy()
/**
* A proxy class to make [experience] (effectively) write-only.
*/
inner class ExperienceProxy {
operator fun plusAssign(amount: Int) = skills.addExperience(skill, amount.toDouble())
operator fun plusAssign(amount: Double) = skills.addExperience(skill, amount)
}
/**
* Boosts the current level of this skill by [amount], if possible (i.e. if `current + amount <= maximum + amount`).
*/
fun boost(amount: Int) {
val new = Math.min(current + amount, maximum + amount)
skills.setCurrentLevel(skill, new)
}
/**
* Drains the current level of this skill by [amount], if possible (i.e. if `current - amount >= 0`).
*/
fun drain(amount: Int) {
val new = Math.max(current - amount, 0)
skills.setCurrentLevel(skill, new)
}
/**
* Restores the current level of this skill by [amount], if possible (i.e. if `current + amount < maximum`).
*/
fun restore(amount: Int) {
val new = Math.max(current + amount, maximum)
skills.setCurrentLevel(skill, new)
}
}
@@ -1,14 +1,13 @@
import Fishing_plugin.FishingAction
import org.apollo.game.action.ActionBlock
import org.apollo.game.action.AsyncDistancedAction
import org.apollo.game.message.impl.NpcActionMessage
import org.apollo.game.model.Position
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.Skill
import org.apollo.game.plugin.api.fishing
import org.apollo.game.plugin.skills.fishing.FishingSpot
import org.apollo.game.plugin.skills.fishing.FishingTool
import org.apollo.game.plugins.api.fishing
import org.apollo.game.plugins.api.skills
import java.util.Objects
import java.util.Random
@@ -62,7 +61,7 @@ class FishingAction(player: Player, position: Position, val option: FishingSpot.
mob.playAnimation(tool.animation)
wait(FISHING_DELAY)
val level = mob.skills.fishing.currentLevel
val level = mob.fishing.current
val fish = option.sample(level)
if (successfulCatch(level, fish.level)) {
@@ -72,7 +71,7 @@ class FishingAction(player: Player, position: Position, val option: FishingSpot.
mob.inventory.add(fish.id)
mob.sendMessage("You catch a ${fish.formattedName}.")
mob.skills.addExperience(Skill.FISHING, fish.experience)
mob.fishing.experience += fish.experience
if (mob.inventory.freeSlots() == 0) {
mob.inventory.forceCapacityExceeded()
@@ -91,7 +90,7 @@ class FishingAction(player: Player, position: Position, val option: FishingSpot.
* Verifies that the player can gather fish from the [FishingSpot] they clicked.
*/
private fun verify(): Boolean {
if (mob.skills.fishing.currentLevel < option.level) {
if (mob.fishing.current < option.level) {
mob.sendMessage("You need a fishing level of ${option.level} to fish at this spot.")
return false
} else if (!hasTool(mob, tool)) {
@@ -113,7 +112,6 @@ class FishingAction(player: Player, position: Position, val option: FishingSpot.
if (javaClass != other?.javaClass) return false
other as FishingAction
return option == other.option && position == other.position && mob == other.mob
}
+49 -45
View File
@@ -5,52 +5,47 @@ 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.Skill
import org.apollo.game.model.entity.obj.GameObject
import org.apollo.game.plugin.api.mining
import org.apollo.game.plugin.skills.mining.Ore
import org.apollo.game.plugin.skills.mining.PICKAXES
import org.apollo.game.plugin.skills.mining.Pickaxe
import org.apollo.game.plugin.skills.mining.lookupOreRock
import org.apollo.game.plugins.api.Definitions
import org.apollo.game.plugins.api.mining
import org.apollo.game.plugins.api.skills
import org.apollo.net.message.Message
import java.util.*
import java.util.Optional
class MiningTarget(val objectId: Int, val position: Position, val ore: Ore) {
fun getObject(world: World): Optional<GameObject> {
val region = world.regionRepository.fromPosition(position)
val obj = region.findObject(position, objectId)
return obj
return region.findObject(position, objectId)
}
fun isSuccessful(mob: Player): Boolean {
val offset = if (ore.chanceOffset) 1 else 0
val percent = (ore.chance * mob.skills.mining.currentLevel + offset) * 100
val percent = (ore.chance * mob.mining.current + offset) * 100
return rand(100) < percent;
return rand(100) < percent
}
}
class MiningAction(player: Player, val tool: Pickaxe, val target: MiningTarget) : AsyncDistancedAction<Player>(
PULSES,
true,
player,
target.position,
ORE_SIZE
) {
class MiningAction(
player: Player,
private val tool: Pickaxe,
private val target: MiningTarget
) : AsyncDistancedAction<Player>(PULSES, true, player, target.position, ORE_SIZE) {
companion object {
private val PULSES = 0
private val ORE_SIZE = 1;
private val ORE_SIZE = 1
fun pickaxeFor(player: Player): Pickaxe? {
return PICKAXES
.filter { it.level <= player.skills.mining.currentLevel }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level }
.firstOrNull()
.filter { it.level <= player.mining.current }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level }
.firstOrNull()
}
/**
@@ -69,10 +64,10 @@ class MiningAction(player: Player, val tool: Pickaxe, val target: MiningTarget)
}
}
override fun action() : ActionBlock = {
override fun action(): ActionBlock = {
mob.turnTo(position)
val level = mob.skills.mining.currentLevel
val level = mob.mining.current
if (level < target.ore.level) {
mob.sendMessage("You do not have the required level to mine this rock.")
stop()
@@ -98,7 +93,7 @@ class MiningAction(player: Player, val tool: Pickaxe, val target: MiningTarget)
val oreName = Definitions.item(target.ore.id)?.name?.toLowerCase()
mob.sendMessage("You manage to mine some $oreName")
mob.skills.addExperience(Skill.MINING, target.ore.exp)
mob.mining.experience += target.ore.exp
mob.world.expireObject(obj.get(), target.ore.objects[target.objectId]!!, target.ore.respawn)
stop()
}
@@ -106,25 +101,32 @@ class MiningAction(player: Player, val tool: Pickaxe, val target: MiningTarget)
}
}
class ExpiredProspectingAction : DistancedAction<Player> {
constructor(mob: Player, position: Position) : super(PROSPECT_PULSES, true, mob, position, ORE_SIZE)
class ExpiredProspectingAction(
mob: Player,
position: Position
) : DistancedAction<Player>(PROSPECT_PULSES, true, mob, position, ORE_SIZE) {
companion object {
private val PROSPECT_PULSES = 0
private val ORE_SIZE = 1;
private val ORE_SIZE = 1
}
override fun executeAction() {
mob.sendMessage("There is currently no ore available in this rock.")
stop();
stop()
}
}
class ProspectingAction(val m: Player, val p: Position, val ore: Ore) : AsyncDistancedAction<Player>(PROSPECT_PULSES, true, m, p, ORE_SIZE) {
class ProspectingAction(
player: Player,
position: Position,
private val ore: Ore
) : AsyncDistancedAction<Player>(PROSPECT_PULSES, true, player, position, ORE_SIZE) {
companion object {
private val PROSPECT_PULSES = 3
private val ORE_SIZE = 1;
private val ORE_SIZE = 1
/**
* Starts a [MiningAction] for the specified [Player], terminating the [Message] that triggered it.
@@ -135,9 +137,10 @@ class ProspectingAction(val m: Player, val p: Position, val ore: Ore) : AsyncDis
message.terminate()
}
}
override fun action() : ActionBlock = {
override fun action(): ActionBlock = {
mob.sendMessage("You examine the rock for ores...")
mob.turnTo(position)
@@ -148,22 +151,23 @@ class ProspectingAction(val m: Player, val p: Position, val ore: Ore) : AsyncDis
stop()
}
}
on { ObjectActionMessage::class }
.where { option == 1 }
.then {
val ore = lookupOreRock(id)
if (ore != null) {
MiningAction.start(this, it, ore)
}
.where { option == 1 }
.then {
val ore = lookupOreRock(id)
if (ore != null) {
MiningAction.start(this, it, ore)
}
}
on { ObjectActionMessage::class }
.where { option == 2 }
.then {
var ore = lookupOreRock(id)
if (ore != null) {
ProspectingAction.start(this, it, ore)
}
.where { option == 2 }
.then {
val ore = lookupOreRock(id)
if (ore != null) { // TODO send expired action if rock is expired
ProspectingAction.start(this, it, ore)
}
}
@@ -1,4 +1,3 @@
import org.apollo.cache.def.ItemDefinition
import org.apollo.game.GameConstants
import org.apollo.game.action.ActionBlock
import org.apollo.game.action.AsyncDistancedAction
@@ -6,14 +5,14 @@ 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.Skill
import org.apollo.game.model.entity.obj.GameObject
import org.apollo.game.plugin.skills.woodcutting.*
import org.apollo.game.plugins.api.*
import java.util.*
import org.apollo.game.plugin.api.woodcutting
import org.apollo.game.plugin.skills.woodcutting.Axe
import org.apollo.game.plugin.skills.woodcutting.Tree
import java.util.Optional
import java.util.concurrent.TimeUnit
class WoodcuttingTarget(val objectId: Int, val position: Position, val tree: Tree) {
class WoodcuttingTarget(private val objectId: Int, val position: Position, val tree: Tree) {
/**
* Get the tree object in the world
@@ -24,33 +23,37 @@ class WoodcuttingTarget(val objectId: Int, val position: Position, val tree: Tre
}
/**
* Check if the tree was cut down
* Returns whether or not the tree was cut down.
*/
fun isCutDown(mob: Player): Boolean {
return rand(100) <= tree.chance * 100
}
fun isCutDown(): Boolean = rand(100) <= tree.chance * 100
}
class WoodcuttingAction(val player: Player, val tool: Axe, val target: WoodcuttingTarget) : AsyncDistancedAction<Player>(DELAY, true, player, target.position, TREE_SIZE) {
class WoodcuttingAction(
player: Player,
private val tool: Axe,
private val target: WoodcuttingTarget
) : AsyncDistancedAction<Player>(DELAY, true, player, target.position, TREE_SIZE) {
companion object {
private val DELAY = 0
private val TREE_SIZE = 2
private val MINIMUM_RESPAWN_TIME = 30L //In seconds
private const val DELAY = 0
private const val TREE_SIZE = 2
private const val MINIMUM_RESPAWN_TIME = 30L // In seconds
/**
* Find the highest level axe the player has
*/
private fun axeFor(player: Player): Axe? {
return Axe.getAxes()
.filter { it.level <= player.skills.woodcutting.currentLevel }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level }
.firstOrNull()
.filter { it.level <= player.woodcutting.current }
.filter { player.equipment.contains(it.id) || player.inventory.contains(it.id) }
.sortedByDescending { it.level }
.firstOrNull()
}
/**
* Starts a [WoodcuttingAction] for the specified [Player], terminating the [Message] that triggered it.
* Starts a [WoodcuttingAction] for the specified [Player], terminating the [ObjectActionMessage] that triggered
* it.
*/
fun start(message: ObjectActionMessage, player: Player, wood: Tree) {
val axe = axeFor(player)
@@ -73,7 +76,7 @@ class WoodcuttingAction(val player: Player, val tool: Axe, val target: Woodcutti
override fun action(): ActionBlock = {
mob.turnTo(position)
val level = mob.skills.woodcutting.currentLevel
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()
@@ -92,12 +95,12 @@ class WoodcuttingAction(val player: Player, val tool: Axe, val target: Woodcutti
}
if (mob.inventory.add(target.tree.id)) {
val logName = Definitions.item(target.tree.id)?.name?.toLowerCase();
val logName = Definitions.item(target.tree.id)?.name?.toLowerCase()
mob.sendMessage("You managed to cut some $logName.")
mob.skills.addExperience(Skill.WOODCUTTING, target.tree.exp)
mob.woodcutting.experience += target.tree.exp
}
if (target.isCutDown(mob)) {
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.get(), target.tree.stump, respawn.toInt())