forked from 2009Scape/Server
Merge 2009scape updates #19
8 changed files with 137 additions and 23 deletions
|
|
@ -15,7 +15,7 @@ import core.plugin.Plugin
|
|||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
val livesBased = arrayOf(PatchType.HERB_PATCH, PatchType.CACTUS_PATCH, PatchType.BELLADONNA_PATCH, PatchType.HOPS_PATCH, PatchType.ALLOTMENT, PatchType.EVIL_TURNIP_PATCH)
|
||||
val livesBased = arrayOf(PatchType.HERB_PATCH, PatchType.CACTUS_PATCH, PatchType.HOPS_PATCH, PatchType.ALLOTMENT)
|
||||
|
||||
@Initializable
|
||||
class CropHarvester : OptionHandler() {
|
||||
|
|
@ -43,14 +43,16 @@ class CropHarvester : OptionHandler() {
|
|||
override fun pulse(): Boolean {
|
||||
var reward = Item(crop)
|
||||
|
||||
val familiar = player.familiarManager.familiar
|
||||
if (familiar != null && familiar is GiantEntNPC) {
|
||||
familiar.modifyFarmingReward(fPatch, reward)
|
||||
}
|
||||
if (!hasSpaceFor(player, reward)) {
|
||||
sendMessage(player, "You have run out of inventory space.")
|
||||
return true
|
||||
}
|
||||
|
||||
val familiar = player.familiarManager.familiar
|
||||
if (familiar != null && familiar is GiantEntNPC) {
|
||||
familiar.modifyFarmingReward(fPatch, reward)
|
||||
}
|
||||
|
||||
var requiredItem = when (fPatch.type) {
|
||||
PatchType.TREE_PATCH -> Items.SECATEURS_5329
|
||||
else -> Items.SPADE_952
|
||||
|
|
@ -92,7 +94,7 @@ class CropHarvester : OptionHandler() {
|
|||
// TODO: If a flower patch is being harvested, delay the clearing of the
|
||||
// patch until after the animation has played - https://youtu.be/lg4GktlVNUY?t=75
|
||||
delay = 2
|
||||
addItem(player, reward.id)
|
||||
addItemOrDrop(player, reward.id,reward.amount)
|
||||
rewardXP(player, Skills.FARMING, plantable.harvestXP)
|
||||
if (patch.patch.type in livesBased) {
|
||||
patch.rollLivesDecrement(
|
||||
|
|
@ -104,6 +106,9 @@ class CropHarvester : OptionHandler() {
|
|||
if (patch.harvestAmt <= 0 && crop == plantable.harvestItem) {
|
||||
patch.clear()
|
||||
}
|
||||
else if (fPatch.type == PatchType.MUSHROOM_PATCH){
|
||||
patch.setCurrentState(patch.getCurrentState() + 1)
|
||||
}
|
||||
}
|
||||
if (sendHarvestMessages && (patch.cropLives <= 0 || patch.harvestAmt <= 0)) {
|
||||
sendMessage(player, "The $patchName is now empty.")
|
||||
|
|
|
|||
|
|
@ -30,6 +30,14 @@ class DigUpPatchDialogue(player: Player? = null) : DialoguePlugin(player) {
|
|||
return true
|
||||
}
|
||||
}
|
||||
if (patch?.patch?.type == PatchType.FRUIT_TREE_PATCH) {
|
||||
val isTreeStump = patch?.getCurrentState() == patch?.plantable!!.value + 25
|
||||
if (patch!!.isGrown() && !isTreeStump) {
|
||||
sendMessage(player, "You need to chop this tree down first.") // this message is not authentic
|
||||
stage = 1000
|
||||
return true
|
||||
}
|
||||
}
|
||||
sendDialogueOptions(player, "Are you sure you want to dig up this patch?", "Yes, I want to clear it for new crops.", "No, I want to leave it as it is.")
|
||||
stage = 0
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import core.game.interaction.OptionHandler
|
|||
import core.game.node.Node
|
||||
import content.global.skill.summoning.familiar.GiantEntNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.task.Pulse
|
||||
|
|
@ -86,6 +87,10 @@ class FruitAndBerryPicker : OptionHandler() {
|
|||
sendMessage(player, "You pick $determiner ${reward.name.lowercase()}.")
|
||||
}
|
||||
|
||||
if (plantable == Plantable.POISON_IVY_SEED && patch.patch == FarmingPatch.CHAMPIONS_GUILD_BUSH){
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 0)
|
||||
}
|
||||
|
||||
return patch.getFruitOrBerryCount() == 0
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package content.global.skill.farming
|
||||
|
||||
import content.data.skill.SkillingTool
|
||||
import core.api.*
|
||||
import core.cache.def.impl.SceneryDefinition
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.task.Pulse
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
@Initializable
|
||||
class FruitTreeChopper : OptionHandler() {
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
SceneryDefinition.setOptionHandler("chop-down",this)
|
||||
SceneryDefinition.setOptionHandler("chop down",this)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
|
||||
player ?: return false
|
||||
node ?: return false
|
||||
|
||||
val fPatch = FarmingPatch.forObject(node.asScenery())
|
||||
fPatch ?: return false
|
||||
|
||||
val patch = fPatch.getPatchFor(player)
|
||||
|
||||
val plantable = patch.plantable
|
||||
plantable ?: return false
|
||||
|
||||
val animation = SkillingTool.getHatchet(player).animation
|
||||
|
||||
submitIndividualPulse(player, object : Pulse(animation.duration) {
|
||||
override fun pulse(): Boolean {
|
||||
animate(player, animation)
|
||||
val soundIndex = RandomFunction.random(0, woodcuttingSounds.size)
|
||||
playAudio(player, woodcuttingSounds[soundIndex])
|
||||
patch.setCurrentState(patch.getCurrentState() + 19)
|
||||
sendMessage(player, "You chop down the ${plantable.displayName.lowercase().removeSuffix(" sapling")}.")
|
||||
return true
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
private val woodcuttingSounds = intArrayOf(
|
||||
Sounds.WOODCUTTING_HIT_3038,
|
||||
Sounds.WOODCUTTING_HIT_3039,
|
||||
Sounds.WOODCUTTING_HIT_3040,
|
||||
Sounds.WOODCUTTING_HIT_3041,
|
||||
Sounds.WOODCUTTING_HIT_3042
|
||||
)
|
||||
}
|
||||
|
|
@ -29,7 +29,11 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
Plantable.WILLOW_SAPLING -> 0
|
||||
else -> 1
|
||||
}
|
||||
if(plantable != null && plantable?.applicablePatch != PatchType.FLOWER_PATCH) {
|
||||
if(plantable != null
|
||||
&& plantable?.applicablePatch != PatchType.FLOWER_PATCH
|
||||
&& plantable?.applicablePatch != PatchType.BELLADONNA_PATCH
|
||||
&& plantable?.applicablePatch != PatchType.MUSHROOM_PATCH
|
||||
&& plantable?.applicablePatch != PatchType.EVIL_TURNIP_PATCH) {
|
||||
harvestAmt += compostMod
|
||||
}
|
||||
cropLives = 3 + compostMod
|
||||
|
|
@ -70,8 +74,6 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
var chance = when(patch.type){
|
||||
PatchType.ALLOTMENT -> 8 //average of 8 per life times 3 lives = average 24
|
||||
PatchType.HOPS_PATCH -> 6 //average of 6 per life times 3 lives = 18
|
||||
PatchType.BELLADONNA_PATCH -> 2 //average of 2 per life times 3 lives = 6
|
||||
PatchType.EVIL_TURNIP_PATCH -> 2 //average 2 per, same as BELLADONNA
|
||||
PatchType.CACTUS_PATCH -> 3 //average of 3 per life times 3 lives = 9
|
||||
else -> 0 // nothing should go here, but if it does, do not give extra crops amd decrement cropLives
|
||||
}
|
||||
|
|
@ -88,6 +90,11 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
return getCurrentState() in 0..2
|
||||
}
|
||||
|
||||
fun isChoppedFruitTree(): Boolean {
|
||||
return (patch.type == PatchType.FRUIT_TREE_PATCH)
|
||||
&& getCurrentState() == (plantable?.value ?: 0) + 25
|
||||
}
|
||||
|
||||
fun isEmptyAndWeeded(): Boolean {
|
||||
return getCurrentState() == 3
|
||||
}
|
||||
|
|
@ -198,6 +205,10 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
else if(isDiseased && !isDead) setVisualState(getHerbDiseaseValue())
|
||||
else setVisualState((plantable?.value ?: 0) + currentGrowthStage)
|
||||
}
|
||||
PatchType.MUSHROOM_PATCH -> {
|
||||
if(isDead) setVisualState(getMushroomDeathValue())
|
||||
else if(isDiseased && !isDead) setVisualState(getMushroomDiseaseValue())
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,16 +232,27 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
private fun getBushDiseaseValue(): Int{
|
||||
if(plantable == Plantable.POISON_IVY_SEED){
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 12
|
||||
} else {
|
||||
}
|
||||
else if (plantable == Plantable.REDBERRY_SEED
|
||||
|| plantable == Plantable.CADAVABERRY_SEED){
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 65
|
||||
}
|
||||
else {
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 64
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBushDeathValue(): Int{
|
||||
if(plantable == Plantable.POISON_IVY_SEED){
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 22
|
||||
} else {
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 126
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 20
|
||||
}
|
||||
else if (plantable == Plantable.REDBERRY_SEED
|
||||
|| plantable == Plantable.CADAVABERRY_SEED
|
||||
|| plantable == Plantable.WHITEBERRY_SEED){
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 129
|
||||
}
|
||||
else {
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 128
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,6 +280,14 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
return (plantable?.value ?: 0) + currentGrowthStage + 16
|
||||
}
|
||||
|
||||
private fun getMushroomDiseaseValue(): Int {
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 11
|
||||
}
|
||||
|
||||
private fun getMushroomDeathValue(): Int {
|
||||
return (plantable?.value ?: 0) + currentGrowthStage + 16
|
||||
}
|
||||
|
||||
private fun getHerbDiseaseValue(): Int {
|
||||
return if (plantable?.value ?: -1 <= 103) {
|
||||
128 + (((plantable?.ordinal ?: 0) - Plantable.GUAM_SEED.ordinal) * 3) + currentGrowthStage - 1
|
||||
|
|
@ -275,7 +305,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
}
|
||||
|
||||
private fun grow(){
|
||||
if((isWeedy() || isEmptyAndWeeded()) && getCurrentState() > 0) {
|
||||
if((isWeedy() || isEmptyAndWeeded() || (plantable == Plantable.SCARECROW && !isGrown())) && getCurrentState() > 0) {
|
||||
nextGrowth = System.currentTimeMillis() + 60000
|
||||
setCurrentState(getCurrentState() - 1)
|
||||
currentGrowthStage--
|
||||
|
|
@ -294,7 +324,14 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
CompostType.SUPERCOMPOST -> 13
|
||||
}
|
||||
|
||||
if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB && RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid && !isFlowerProtected() && patch.type != PatchType.EVIL_TURNIP_PATCH && currentGrowthStage != 0){
|
||||
if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB
|
||||
&& RandomFunction.random(128) <= (17 - diseaseMod)
|
||||
&& !isWatered && !isGrown()
|
||||
&& !protectionPaid
|
||||
&& !isFlowerProtected()
|
||||
&& patch.type != PatchType.EVIL_TURNIP_PATCH
|
||||
&& plantable != Plantable.POISON_IVY_SEED
|
||||
&& currentGrowthStage != 0){
|
||||
isDiseased = true
|
||||
// If we manually set disease mod reset it back to 0 so that crops can naturally grow after being treated/accidentally attempted to disease when they cannot be
|
||||
if (diseaseMod < 0) diseaseMod = 0
|
||||
|
|
@ -389,7 +426,9 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
else -> return false
|
||||
}.getPatchFor(player, false)
|
||||
|
||||
return (fpatch.plantable != null &&
|
||||
if (fpatch.plantable == Plantable.SCARECROW && fpatch.plantable == plantable?.protectionFlower){
|
||||
return true
|
||||
} else return (fpatch.plantable != null &&
|
||||
(fpatch.plantable == plantable?.protectionFlower || fpatch.plantable == Plantable.forItemID(Items.WHITE_LILY_SEED_14589))
|
||||
&& fpatch.isGrown())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ enum class Plantable(val itemID: Int, val displayName: String, val value: Int, v
|
|||
WHITE_LILY_SEED(Items.WHITE_LILY_SEED_14589,"white lily seed",37,4,42.0,250.0,0.0,52,PatchType.FLOWER_PATCH,Items.WHITE_LILY_14583),
|
||||
|
||||
// Flower (technically)
|
||||
SCARECROW(Items.SCARECROW_6059,"scarecrow",33,3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059),
|
||||
SCARECROW(Items.SCARECROW_6059,"scarecrow",36,-3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059),
|
||||
|
||||
// Allotments
|
||||
POTATO_SEED(Items.POTATO_SEED_5318, "potato seed", 6, 4, 8.0, 9.0, 0.0, 1, PatchType.ALLOTMENT, Items.POTATO_1942,Item(Items.COMPOST_6032,2),MARIGOLD_SEED),
|
||||
|
|
@ -53,9 +53,9 @@ enum class Plantable(val itemID: Int, val displayName: String, val value: Int, v
|
|||
// Bushes
|
||||
REDBERRY_SEED(Items.REDBERRY_SEED_5101,"redberry bush seed",5,5,11.5,4.5,64.0,10,PatchType.BUSH_PATCH,Items.REDBERRIES_1951,Item(Items.CABBAGES10_5478,4)),
|
||||
CADAVABERRY_SEED(Items.CADAVABERRY_SEED_5102,"cadavaberry bush seed",15,6,18.0,7.0,102.5,22,PatchType.BUSH_PATCH,Items.CADAVA_BERRIES_753,Item(Items.TOMATOES5_5968,3)),
|
||||
DWELLBERRY_SEED(Items.DWELLBERRY_SEED_5103,"dwellberry bush seed",26,27,31.5,12.0,177.5,36,PatchType.BUSH_PATCH,Items.DWELLBERRIES_2126,Item(Items.STRAWBERRIES5_5406,3)),
|
||||
DWELLBERRY_SEED(Items.DWELLBERRY_SEED_5103,"dwellberry bush seed",26,7,31.5,12.0,177.5,36,PatchType.BUSH_PATCH,Items.DWELLBERRIES_2126,Item(Items.STRAWBERRIES5_5406,3)),
|
||||
JANGERBERRY_SEED(Items.JANGERBERRY_SEED_5104,"jangerberry bush seed",38,8,50.5,19.0,284.5,48,PatchType.BUSH_PATCH,Items.JANGERBERRIES_247,Item(Items.WATERMELON_5982,6)),
|
||||
WHITEBERRY_SEED(Items.WHITEBERRY_SEED_5105,"whiteberry bush seed",51,8,78.0,29.0,437.5,59,PatchType.BUSH_PATCH,Items.WHITE_BERRIES_239,null),
|
||||
WHITEBERRY_SEED(Items.WHITEBERRY_SEED_5105,"whiteberry bush seed",51,8,78.0,29.0,437.5,59,PatchType.BUSH_PATCH,Items.WHITE_BERRIES_239,Item(Items.MUSHROOM_6004,8)),
|
||||
POISON_IVY_SEED(Items.POISON_IVY_SEED_5106,"poison ivy bush seed",197,8,120.0,45.0,675.0,70,PatchType.BUSH_PATCH,Items.POISON_IVY_BERRIES_6018,null),
|
||||
|
||||
// Herbs
|
||||
|
|
@ -78,7 +78,7 @@ enum class Plantable(val itemID: Int, val displayName: String, val value: Int, v
|
|||
|
||||
// Special
|
||||
BELLADONNA_SEED(Items.BELLADONNA_SEED_5281, "belladonna seed", 4, 4, 91.0, 128.0, 0.0, 63, PatchType.BELLADONNA_PATCH, Items.CAVE_NIGHTSHADE_2398),
|
||||
MUSHROOM_SPORE(Items.MUSHROOM_SPORE_5282, "mushroom spore", 6, 7, 61.5, 57.7, 0.0, 53, PatchType.MUSHROOM_PATCH, Items.MUSHROOM_6004),
|
||||
MUSHROOM_SPORE(Items.MUSHROOM_SPORE_5282, "mushroom spore", 4, 6, 61.5, 57.7, 0.0, 53, PatchType.MUSHROOM_PATCH, Items.MUSHROOM_6004),
|
||||
CACTUS_SEED(Items.CACTUS_SEED_5280, "cactus seed", 8, 7, 66.5, 25.0, 374.0, 55, PatchType.CACTUS_PATCH, Items.CACTUS_SPINE_6016),
|
||||
EVIL_TURNIP_SEED(Items.EVIL_TURNIP_SEED_12148, "evil turnip seed", 4, 1, 41.0, 46.0, 0.0, 42, PatchType.EVIL_TURNIP_PATCH, Items.EVIL_TURNIP_12134)
|
||||
;
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ class UseWithPatchHandler : InteractionListener {
|
|||
}
|
||||
|
||||
val p = patch.getPatchFor(player)
|
||||
if (p.getCurrentState() < 3 && p.isWeedy() && plantable != Plantable.SCARECROW) {
|
||||
if (p.getCurrentState() < 3 && p.isWeedy()) {
|
||||
sendMessage(player, "This patch needs weeding first.")
|
||||
return@onUseWith true
|
||||
} else if (p.getCurrentState() > 3) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) {
|
|||
//Another more extreme example is if you planted something at 10:31 that takes 5 minutes to grow. 10:35 comes around, it hasn't been 5 minutes, so it doesn't grow, meaning
|
||||
//it actually grows at 10:40, an extra 4 minutes.
|
||||
//this code makes it so crops planted both at 10:31 and 10:34 grow at 10:35 if they are supposed to take 5 minutes for each stage.
|
||||
if(patch.nextGrowth < (System.currentTimeMillis() + 240_000L) && !patch.isDead){
|
||||
if(patch.nextGrowth < (System.currentTimeMillis() + 240_000L) && !patch.isDead && !patch.isChoppedFruitTree()){
|
||||
patch.nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(patch.getStageGrowthMinutes().toLong())
|
||||
patch.update()
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) {
|
|||
for ((_, patch) in patchMap) {
|
||||
val type = patch.patch.type
|
||||
val shouldPlayCatchup = !patch.isGrown() || (type == PatchType.BUSH_PATCH && patch.getFruitOrBerryCount() < 4) || (type == PatchType.FRUIT_TREE_PATCH && patch.getFruitOrBerryCount() < 6)
|
||||
if (shouldPlayCatchup && !patch.isDead) {
|
||||
if (shouldPlayCatchup && !patch.isDead && !patch.isChoppedFruitTree()) {
|
||||
var stagesToSimulate = if (!patch.isGrown()) {
|
||||
if (patch.isWeedy() || patch.isEmptyAndWeeded()) patch.currentGrowthStage % 4
|
||||
else patch.plantable!!.stages - patch.currentGrowthStage
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue