Improve farming trees:
- Trees regrow from their stumps over time, or from Hydra's regrowth scrolls. - Diseased trees can be cured with secateurs. - Willow branches can be harvested from willow trees. - Giant ent improves yields of certain patch types by 50%.
This commit is contained in:
@@ -4,6 +4,7 @@ import api.ContentAPI
|
||||
import core.cache.def.impl.SceneryDefinition
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.npc.familiar.GiantEntNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
@@ -11,21 +12,85 @@ import core.game.system.task.Pulse
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
|
||||
val livesBased = arrayOf(PatchType.HERB, PatchType.CACTUS, PatchType.BELLADONNA, PatchType.HOPS, PatchType.ALLOTMENT,PatchType.EVIL_TURNIP)
|
||||
|
||||
val spadeAnim = Animation(830)
|
||||
|
||||
@Initializable
|
||||
class CropHarvester : OptionHandler() {
|
||||
|
||||
val livesBased = arrayOf(PatchType.HERB, PatchType.CACTUS, PatchType.BELLADONNA, PatchType.HOPS, PatchType.ALLOTMENT,PatchType.EVIL_TURNIP)
|
||||
|
||||
val spadeAnim = Animation(830)
|
||||
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
SceneryDefinition.setOptionHandler("harvest",this)
|
||||
SceneryDefinition.setOptionHandler("pick",this)
|
||||
return this
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun harvestPulse(player: Player?, node: Node?, crop: Int): Pulse? {
|
||||
player ?: return null
|
||||
node ?: return null
|
||||
val fPatch = FarmingPatch.forObject(node.asScenery())
|
||||
fPatch ?: return null
|
||||
val patch = fPatch.getPatchFor(player)
|
||||
val plantable = patch.plantable
|
||||
plantable ?: return null
|
||||
|
||||
return object : Pulse(0) {
|
||||
override fun pulse(): Boolean {
|
||||
var reward = Item(crop, 1)
|
||||
|
||||
val familiar = player.familiarManager.familiar
|
||||
if(familiar != null && familiar is GiantEntNPC) {
|
||||
familiar.modifyFarmingReward(fPatch, reward)
|
||||
}
|
||||
if(!player.inventory.hasSpaceFor(reward)){
|
||||
player.sendMessage("You don't have enough inventory space for that.")
|
||||
return true
|
||||
}
|
||||
var requiredItem = when(fPatch.type){
|
||||
PatchType.HERB -> Items.SECATEURS_5329
|
||||
else -> Items.SPADE_952
|
||||
}
|
||||
if(requiredItem == Items.SECATEURS_5329){
|
||||
if(player.inventory.contains(Items.MAGIC_SECATEURS_7409,1)){
|
||||
requiredItem = Items.MAGIC_SECATEURS_7409
|
||||
}
|
||||
}
|
||||
val anim = when(requiredItem){
|
||||
Items.SPADE_952 -> Animation(830)
|
||||
Items.SECATEURS_5329 -> Animation(7227)
|
||||
Items.MAGIC_SECATEURS_7409 -> Animation(7228)
|
||||
else -> Animation(0)
|
||||
}
|
||||
if(!player.inventory.containsItem(Item(requiredItem))){
|
||||
player.sendMessage("You lack the needed tool to harvest these crops.")
|
||||
return true
|
||||
}
|
||||
player.animator.animate(anim)
|
||||
delay = 2
|
||||
player.inventory.add(reward)
|
||||
player.skills.addExperience(Skills.FARMING,plantable.harvestXP)
|
||||
if(patch.patch.type in livesBased){
|
||||
patch.rollLivesDecrement(
|
||||
ContentAPI.getDynLevel(player, Skills.FARMING),
|
||||
requiredItem == Items.MAGIC_SECATEURS_7409
|
||||
)
|
||||
} else {
|
||||
patch.harvestAmt--
|
||||
if(patch.harvestAmt <= 0 && crop == plantable.harvestItem){
|
||||
patch.clear()
|
||||
}
|
||||
}
|
||||
return patch.cropLives <= 0 || patch.harvestAmt <= 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
|
||||
player ?: return false
|
||||
node ?: return false
|
||||
@@ -40,51 +105,10 @@ class CropHarvester : OptionHandler() {
|
||||
return true
|
||||
}
|
||||
|
||||
player.pulseManager.run(object : Pulse(0){
|
||||
override fun pulse(): Boolean {
|
||||
if(!player.inventory.hasSpaceFor(Item(plantable.harvestItem,1))){
|
||||
player.sendMessage("You don't have enough inventory space for that.")
|
||||
return true
|
||||
}
|
||||
var requiredItem = when(fPatch.type){
|
||||
PatchType.HERB -> Items.SECATEURS_5329
|
||||
else -> Items.SPADE_952
|
||||
}
|
||||
if(requiredItem == Items.SECATEURS_5329){
|
||||
if(player.inventory.contains(Items.MAGIC_SECATEURS_7409,1)){
|
||||
requiredItem = Items.MAGIC_SECATEURS_7409
|
||||
}
|
||||
}
|
||||
val anim = when(requiredItem){
|
||||
Items.SPADE_952 -> Animation(830)
|
||||
Items.SECATEURS_5329 -> Animation(7227)
|
||||
Items.MAGIC_SECATEURS_7409 -> Animation(7228)
|
||||
else -> Animation(0)
|
||||
}
|
||||
if(!player.inventory.containsItem(Item(requiredItem))){
|
||||
player.sendMessage("You lack the needed tool to harvest these crops.")
|
||||
return true
|
||||
}
|
||||
player.animator.animate(anim)
|
||||
delay = 2
|
||||
player.inventory.add(Item(plantable.harvestItem,1))
|
||||
player.skills.addExperience(Skills.FARMING,plantable.harvestXP)
|
||||
if(patch.patch.type in livesBased){
|
||||
patch.rollLivesDecrement(
|
||||
ContentAPI.getDynLevel(player, Skills.FARMING),
|
||||
requiredItem == Items.MAGIC_SECATEURS_7409
|
||||
)
|
||||
} else {
|
||||
patch.harvestAmt--
|
||||
if(patch.harvestAmt <= 0){
|
||||
patch.clear()
|
||||
}
|
||||
}
|
||||
return patch.cropLives <= 0 || patch.harvestAmt <= 0
|
||||
}
|
||||
})
|
||||
val pulse = harvestPulse(player, node, plantable.harvestItem) ?: return false
|
||||
player.pulseManager.run(pulse)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import api.ContentAPI
|
||||
import core.cache.def.impl.SceneryDefinition
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.npc.familiar.GiantEntNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
@@ -42,7 +43,6 @@ class FruitAndBerryPicker : OptionHandler() {
|
||||
plantable ?: return false
|
||||
|
||||
val animation = Animation(2281)
|
||||
val reward = Item(plantable.harvestItem)
|
||||
|
||||
if(patch.getFruitOrBerryCount() <= 0){
|
||||
player.sendMessage("This shouldn't be happening. Please report this.")
|
||||
@@ -60,6 +60,13 @@ class FruitAndBerryPicker : OptionHandler() {
|
||||
|
||||
player.pulseManager.run(object : Pulse(animation.duration){
|
||||
override fun pulse(): Boolean {
|
||||
val reward = Item(plantable.harvestItem, 1)
|
||||
|
||||
val familiar = player.familiarManager.familiar
|
||||
if(familiar != null && familiar is GiantEntNPC) {
|
||||
familiar.modifyFarmingReward(fPatch, reward)
|
||||
}
|
||||
|
||||
player.animator.animate(animation)
|
||||
ContentAPI.addItemOrDrop(player,reward.id,reward.amount)
|
||||
player.skills.addExperience(Skills.FARMING,plantable.harvestXP)
|
||||
@@ -72,4 +79,4 @@ class FruitAndBerryPicker : OptionHandler() {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
||||
harvestAmt = when (plantable) {
|
||||
Plantable.LIMPWURT_SEED, Plantable.WOAD_SEED -> 3
|
||||
Plantable.MUSHROOM_SPORE -> 6
|
||||
Plantable.WILLOW_SAPLING -> 0
|
||||
else -> 1
|
||||
}
|
||||
if(plantable != null && plantable?.applicablePatch != PatchType.FLOWER) {
|
||||
@@ -254,12 +255,30 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
||||
setCurrentState(getCurrentState() + 1)
|
||||
}
|
||||
}
|
||||
if(patch.type == PatchType.TREE) {
|
||||
// Willow branches
|
||||
if(harvestAmt < 6) {
|
||||
harvestAmt++;
|
||||
}
|
||||
}
|
||||
|
||||
if(plantable?.stages ?: 0 > currentGrowthStage && !isGrown()){
|
||||
currentGrowthStage++
|
||||
setCurrentState(getCurrentState() + 1)
|
||||
isWatered = false
|
||||
}
|
||||
|
||||
regrowIfTreeStump()
|
||||
}
|
||||
|
||||
fun regrowIfTreeStump() {
|
||||
if(patch.type == PatchType.TREE && plantable != null) {
|
||||
// plantable.value + plantable.stages is the check-health stage, so +1 is the choppable tree, and +2 is the stump
|
||||
if(getCurrentState() == plantable!!.value + plantable!!.stages + 2) {
|
||||
setCurrentState(getCurrentState() - 1)
|
||||
isWatered = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun update(){
|
||||
|
||||
@@ -7,6 +7,7 @@ import core.game.node.item.Item
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Items
|
||||
import rs09.game.node.entity.skill.farming.CropHarvester
|
||||
|
||||
object UseWithPatchHandler{
|
||||
val RAKE = Items.RAKE_5341
|
||||
@@ -17,6 +18,7 @@ object UseWithPatchHandler{
|
||||
val pourBucketAnim = Animation(2283)
|
||||
val wateringCanAnim = Animation(2293)
|
||||
val plantCureAnim = Animation(2288)
|
||||
val secateursAnim = Animation(7227)
|
||||
|
||||
@JvmField
|
||||
val allowedNodes = ArrayList<Int>()
|
||||
@@ -46,7 +48,23 @@ object UseWithPatchHandler{
|
||||
RAKE -> PatchRaker.rake(player,patch)
|
||||
SEED_DIBBER -> player.sendMessage("I should plant a seed, not the seed dibber.")
|
||||
SPADE -> player.dialogueInterpreter.open(67984003,patch.getPatchFor(player)) //DigUpPatchDialogue.kt
|
||||
SECATEURS -> {}
|
||||
SECATEURS -> {
|
||||
val p = patch.getPatchFor(player)
|
||||
if(patch.type == PatchType.TREE) {
|
||||
if(p.isDiseased && !p.isDead) {
|
||||
player.pulseManager.run(object: Pulse(){
|
||||
override fun pulse(): Boolean {
|
||||
player.animator.animate(secateursAnim)
|
||||
p.cureDisease()
|
||||
return true
|
||||
}
|
||||
})
|
||||
} else if(p.plantable == Plantable.WILLOW_SAPLING && p.harvestAmt > 0) {
|
||||
val pulse = CropHarvester.harvestPulse(player, event.usedWith, Items.WILLOW_BRANCH_5933) ?: return false
|
||||
player.pulseManager.run(pulse)
|
||||
}
|
||||
}
|
||||
}
|
||||
TROWEL -> {
|
||||
val p = patch.getPatchFor(player)
|
||||
if(!p.isWeedy()){
|
||||
|
||||
@@ -148,7 +148,13 @@ class FarmingState(player: Player? = null) : State(player) {
|
||||
|
||||
if(patch.nextGrowth < System.currentTimeMillis() && !patch.isDead){
|
||||
patch.update()
|
||||
patch.nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(patch.patch.type.stageGrowthTime.toLong())
|
||||
var minutes = patch.patch.type.stageGrowthTime.toLong()
|
||||
if(patch.patch.type == PatchType.FRUIT_TREE && patch.isGrown()) {
|
||||
// Fruit trees take 160 minutes per stage to grow, but
|
||||
// restocking their fruit should take 40 minutes per fruit
|
||||
minutes = 40
|
||||
}
|
||||
patch.nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(minutes)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -164,4 +170,4 @@ class FarmingState(player: Player? = null) : State(player) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user