mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-10 10:20:41 -07:00
Major farming improvements including (but not limited to):
Farming animation corrections Farming message updates and additions Gardeners will chop down fully grown trees for 200 gp Gardeners will give farming advice Compost bin debugging admin command ::finishbins restored (finishes any in-progress compost bins) Compost bin debugging admin command ::resetbins added (resets the player's compost bins to their initial states) Players can no longer pay gardeners to protect diseased or dead farming patches Can no longer water dead patches Weeds will now grow in farming patches as part of the offline catch-up Trees that are not fully grown can now be dug up
This commit is contained in:
parent
cc8dd4edb4
commit
218a040f8b
20 changed files with 515 additions and 363 deletions
|
|
@ -3,160 +3,227 @@ package content.global.dialogue
|
|||
import content.global.skill.farming.FarmerPayOptionDialogue
|
||||
import content.global.skill.farming.Farmers
|
||||
import content.global.skill.farming.FarmingPatch
|
||||
import core.game.node.entity.npc.NPC
|
||||
import content.global.skill.farming.PatchType
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.dialogue.IfTopic
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.START_DIALOGUE
|
||||
|
||||
@Initializable
|
||||
class GardenerDialoguePlugin(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) {
|
||||
override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin {
|
||||
return GardenerDialoguePlugin(player)
|
||||
}
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
npc = args[0] as NPC
|
||||
options("Would you look after my crops for me?","Can you sell me something?")
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when(stage){
|
||||
0 -> when(buttonId){
|
||||
1 -> player("Would you look after my crops for me?").also { stage = 10 }
|
||||
2 -> player("Can you sell me something?").also { stage = 30 }
|
||||
val patches = Farmers.forId(npc.id)!!.patches
|
||||
when (stage) {
|
||||
// TODO: Can fruit trees be chopped down by the gardener too?
|
||||
START_DIALOGUE -> {
|
||||
val patch = patches[0].getPatchFor(player)
|
||||
showTopics(
|
||||
IfTopic(
|
||||
FacialExpression.ASKING,
|
||||
"Would you chop my tree down for me?",
|
||||
1000,
|
||||
patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()
|
||||
),
|
||||
IfTopic(
|
||||
FacialExpression.ASKING,
|
||||
"Would you look after my crops for me?",
|
||||
10,
|
||||
!(patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown())
|
||||
),
|
||||
Topic(FacialExpression.ASKING, "Can you give me any farming advice?", 2000),
|
||||
Topic(FacialExpression.ASKING, "Can you sell me something?", 30),
|
||||
Topic(FacialExpression.NEUTRAL, "That's all, thanks.", END_DIALOGUE)
|
||||
)
|
||||
}
|
||||
|
||||
10 -> npc("I might. Which one were you thinking of?").also { stage++ }
|
||||
11 -> when(npc.id){
|
||||
Farmers.ELSTAN.id, Farmers.LYRA.id -> options("The north-western allotment.","The south-eastern allotment.").also { stage = 15 }
|
||||
Farmers.DANTAERA.id, Farmers.KRAGEN.id -> options("The north allotment.","The south allotment.").also { stage = 15 }
|
||||
else -> player("Uh, that one.").also { stage++ }
|
||||
10 -> {
|
||||
if (patches.size > 1) {
|
||||
npc("I might. Which one were you thinking of?").also { stage = 20 }
|
||||
} else {
|
||||
openPayGardenerDialogue(player, patches[0])
|
||||
}
|
||||
}
|
||||
|
||||
12 -> npc("Oh, right. My bad.").also { stage++ }
|
||||
13 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[0])
|
||||
20 -> when (npc.id) {
|
||||
Farmers.ELSTAN.id, Farmers.LYRA.id -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "The north-western allotment.", 21),
|
||||
Topic(FacialExpression.NEUTRAL, "The south-eastern allotment.", 22)
|
||||
)
|
||||
Farmers.DANTAERA.id, Farmers.KRAGEN.id -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "The northern allotment.", 21),
|
||||
Topic(FacialExpression.NEUTRAL, "The southern allotment.", 22)
|
||||
)
|
||||
}
|
||||
21 -> openPayGardenerDialogue(player, patches[0])
|
||||
22 -> openPayGardenerDialogue(player, patches[1])
|
||||
|
||||
15 -> when(buttonId){
|
||||
1 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[0])
|
||||
2 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[1])
|
||||
30 -> npc(FacialExpression.NEUTRAL, "That depends on whether I have it to sell. What is it", "that you're looking for?").also { stage++ }
|
||||
31 -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Some plant cure.", 100),
|
||||
Topic(FacialExpression.NEUTRAL, "A bucket of compost.", 200),
|
||||
Topic(FacialExpression.NEUTRAL, "A rake.", 300),
|
||||
Topic("(See more items)", 32, true)
|
||||
)
|
||||
32 -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "A watering can.", 400),
|
||||
Topic(FacialExpression.NEUTRAL, "A gardening trowel.", 500),
|
||||
Topic(FacialExpression.NEUTRAL, "A seed dibber.", 600),
|
||||
Topic("(See previous items)", 31, true),
|
||||
Topic(FacialExpression.NEUTRAL, "Forget it.", 40, true)
|
||||
)
|
||||
|
||||
40 -> player("Forget it, you don't have anything I need.").also { stage = END_DIALOGUE }
|
||||
|
||||
100 -> npc("Plant cure, eh? I might have some put aside for myself.", "Tell you what. I'll sell you some plant cure for 25 gp if", "you like.").also { stage++ }
|
||||
101 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
102 -> when (buttonId) {
|
||||
1 -> {
|
||||
player(FacialExpression.HAPPY, "Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if (removeItem(player, Item(Items.COINS_995, 25))) {
|
||||
addItemOrDrop(player, Items.PLANT_CURE_6036)
|
||||
} else {
|
||||
sendMessage(player, "You need 25 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
30 -> npc("That depends on whether I have it to sell.","What is it that you're looking for?").also { stage++ }
|
||||
31 -> options("Some plant cure.","A bucket of compost.","A rake.","(See more items)").also { stage = 32 }
|
||||
32 -> when(buttonId){
|
||||
1 -> player("Some plant cure.").also { stage = 100 }
|
||||
2 -> player("A bucket of compost.").also { stage = 200 }
|
||||
3 -> player("A rake.").also { stage = 300 }
|
||||
4 -> options("A watering can.","A gardening trowel.","A seed dibber.","(See previous items)").also { stage++ }
|
||||
}
|
||||
33 -> when(buttonId){
|
||||
1 -> player("A watering can.").also { stage = 400 }
|
||||
2 -> player("A gardening trowel.").also { stage = 500 }
|
||||
3 -> player("A seed dibber.").also { stage = 600 }
|
||||
4 -> options("Some plant cure.","A bucket of compost.","A rake.","(See more items)").also { stage = 32 }
|
||||
}
|
||||
|
||||
100 -> npc("Plant cure, eh? I might have some put aside for myself.","Tell you what, I'll sell you some plant cure","for 25 gp if you like.").also { stage++ }
|
||||
101 -> options("Yes, that sounds like a fair price.","No thanks, I can get that much cheaper.").also { stage++ }
|
||||
102 -> when(buttonId){
|
||||
200 -> npc("A bucket of compost, eh? I might have one spare...", "tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ }
|
||||
201 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
202 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,25))){
|
||||
player.inventory.add(Item(Items.PLANT_CURE_6036))
|
||||
if (removeItem(player, Item(Items.COINS_995, 35))) {
|
||||
addItemOrDrop(player, Items.COMPOST_6032)
|
||||
} else {
|
||||
player.sendMessage("You need 25 gp to pay for that.")
|
||||
sendMessage(player, "You need 35 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
200 -> npc("A bucket of compost, eh? I might have one spare...","tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ }
|
||||
201 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
202 -> when(buttonId){
|
||||
300 -> npc("A rake, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
301 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
302 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,35))){
|
||||
player.inventory.add(Item(Items.COMPOST_6032))
|
||||
if (removeItem(player, Item(Items.COINS_995, 15))) {
|
||||
addItemOrDrop(player, Items.RAKE_5341)
|
||||
} else {
|
||||
player.sendMessage("You need 35 gp to pay for that.")
|
||||
sendMessage(player, "You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
300 -> npc("A rake, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
301 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
302 -> when(buttonId){
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,15))){
|
||||
player.inventory.add(Item(Items.RAKE_5341))
|
||||
} else {
|
||||
player.sendMessage("You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
}
|
||||
|
||||
400 -> npc("A watering can, eh? I might have one spare...","tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ }
|
||||
401 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
400 -> npc("A watering can, eh? I might have one spare...", "tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ }
|
||||
401 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
402 -> when(buttonId){
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,25))){
|
||||
player.inventory.add(Item(Items.WATERING_CAN8_5340))
|
||||
if (removeItem(player, Item(Items.COINS_995, 25))) {
|
||||
addItemOrDrop(player, Items.WATERING_CAN8_5340)
|
||||
} else {
|
||||
player.sendMessage("You need 25 gp to pay for that.")
|
||||
sendMessage(player, "You need 25 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
500 -> npc("A gardening trowel, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
501 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
502 -> when(buttonId){
|
||||
500 -> npc("A gardening trowel, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
501 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
502 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,15))){
|
||||
player.inventory.add(Item(Items.GARDENING_TROWEL_5325))
|
||||
if (removeItem(player, Item(Items.COINS_995, 15))) {
|
||||
addItemOrDrop(player, Items.GARDENING_TROWEL_5325)
|
||||
} else {
|
||||
player.sendMessage("You need 15 gp to pay for that.")
|
||||
sendMessage(player, "You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
600 -> npc("A seed dibber, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
601 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
602 -> when(buttonId){
|
||||
600 -> npc("A seed dibber, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
601 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
602 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,15))){
|
||||
player.inventory.add(Item(Items.SEED_DIBBER_5343))
|
||||
if (removeItem(player, Item(Items.COINS_995, 15))) {
|
||||
addItemOrDrop(player, Items.SEED_DIBBER_5343)
|
||||
} else {
|
||||
player.sendMessage("You need 15 gp to pay for that.")
|
||||
sendMessage(player, "You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
// Note: This dialogue changes slightly in April 2009, and significantly in December 2009
|
||||
1000 -> npc(FacialExpression.THINKING, "Why? You look like you could chop it down yourself!").also { stage++ }
|
||||
1001 -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Yes, you're right - I'll do it myself.", END_DIALOGUE),
|
||||
Topic(FacialExpression.NEUTRAL, "I can't be bothered - I'd rather pay you to do it.", 1020)
|
||||
)
|
||||
|
||||
1020 -> npc(FacialExpression.NEUTRAL, "Well, it's a lot of hard work - if you pay me 200 GP", "I'll chop it down for you.").also { stage++ }
|
||||
1021 -> {
|
||||
if (inInventory(player, Items.COINS_995, 200)) {
|
||||
showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Here's 200GP - chop my tree down please.", 1022),
|
||||
Topic(FacialExpression.NEUTRAL, "I don't want to pay that much, sorry.", END_DIALOGUE)
|
||||
)
|
||||
} else {
|
||||
player("I don't have that much money on me.").also { stage = END_DIALOGUE } // not authentic
|
||||
}
|
||||
}
|
||||
1022 -> {
|
||||
end()
|
||||
if (removeItem(player, Item(Items.COINS_995, 200))) {
|
||||
patches[0].getPatchFor(player).clear()
|
||||
}
|
||||
}
|
||||
|
||||
2000 -> {
|
||||
val advice = arrayOf(
|
||||
"There are four main Farming areas - Elstan looks after an area south of Falador, Dantaera has one to the north of Catherby, Kragen has one near Ardougne, and Lyra looks after a place in north Morytania.",
|
||||
"If you want to grow fruit trees you could try a few places: Catherby and Brimhaven have a couple of fruit tree patches, and I hear that the gnomes are big on that sort of thing.",
|
||||
"Bittercap mushrooms can only be grown in a special patch in Morytania, near the Mort Myre swamp. There the ground is especially dank and suited to growing poisonous fungi.",
|
||||
"There is a special patch for growing Belladonna - I believe it's somewhere near Draynor Manor, where the ground is a tad 'unblessed'.",
|
||||
|
||||
"Don't just throw away your weeds after you've raked a patch - put them in a compost bin and make some compost.",
|
||||
"Applying compost to a patch will not only reduce the chance that your crops will get diseased, but you will also grow more crops to harvest.",
|
||||
"Supercompost is far better than normal compost, but more expensive to make. You need to rot the right type of item; show me an item, and I'll tell you if it's super-compostable or not.",
|
||||
|
||||
"Tree seeds must be grown in a plantpot of soil into a sapling, and then transferred to a tree patch to continue growing to adulthood.",
|
||||
"You don't have to buy all your plantpots you know, you can make them yourself on a pottery wheel. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.",
|
||||
"You can fill plantpots with soil from Farming patches, if you have a gardening trowel.",
|
||||
|
||||
"Vegetables, hops and flowers are far more likely to grow healthily if you water them periodically.",
|
||||
"The only way to cure a bush or tree of disease is to prune away the diseased leaves with a pair of secateurs. For all other crops I would just apply some plant-cure.",
|
||||
"If you need to be rid of your fruit trees for any reason, all you have to do is chop them down and then dig up the stump.",
|
||||
|
||||
"You can put up to ten potatoes, cabbages or onions in vegetable sacks, although you can't have a mix in the same sack.",
|
||||
"You can put up to five tomatoes, strawberries, apples, bananas or oranges into a fruit basket, although you can't have a mix in the same basket.",
|
||||
"If you want to make your own sacks and baskets you'll need to use the loom that's near the Farming shop in Falador. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.",
|
||||
"You can buy all the farming tools from farming shops, which can be found close to the allotments.",
|
||||
|
||||
"Hops are good for brewing ales. I believe there's a brewery up in Keldagrim somewhere, and I've heard rumours that a place called Phasmatys used to be good for that type of thing. 'Fore they all died, of course.",
|
||||
)
|
||||
npcl(FacialExpression.NEUTRAL, advice.random()).also { stage = START_DIALOGUE }
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun checkPatch(player: Player,fPatch: FarmingPatch){
|
||||
if(fPatch.getPatchFor(player).isWeedy()){
|
||||
npc("You don't have anything planted in that patch.","Plant something and I might agree to look after it for you.").also { stage = END_DIALOGUE }
|
||||
} else if(fPatch.getPatchFor(player).isGrown()){
|
||||
npc("That patch is already fully grown!","I don't know what you want me to do with it!").also { stage = END_DIALOGUE }
|
||||
} else if(fPatch.getPatchFor(player).protectionPaid) {
|
||||
npc("Are you alright? You've already", "paid me for that.").also { stage = END_DIALOGUE }
|
||||
} else {
|
||||
fun openPayGardenerDialogue(player: Player, fPatch: FarmingPatch) {
|
||||
end()
|
||||
player.dialogueInterpreter.open(FarmerPayOptionDialogue(fPatch.getPatchFor(player)),npc)
|
||||
}
|
||||
openDialogue(player, FarmerPayOptionDialogue(fPatch.getPatchFor(player)), npc)
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,19 @@ class CompostBin(val player: Player, val bin: CompostBins) {
|
|||
var finishedTime = 0L
|
||||
var isFinished = false
|
||||
|
||||
/**
|
||||
* Resets the compost bin to its initial state.
|
||||
*/
|
||||
fun reset() {
|
||||
items.clear()
|
||||
isSuperCompost = true
|
||||
isTomatoes = true
|
||||
isClosed = false
|
||||
finishedTime = 0L
|
||||
isFinished = false
|
||||
updateBit()
|
||||
}
|
||||
|
||||
fun isFull() : Boolean {
|
||||
return items.size == 15
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,13 @@ class CropHarvester : OptionHandler() {
|
|||
}
|
||||
}
|
||||
val anim = when (requiredItem) {
|
||||
Items.SPADE_952 -> if (fPatch.type == PatchType.HERB_PATCH) Animation(2282) else Animation(830)
|
||||
Items.SPADE_952 -> {
|
||||
when (fPatch.type) {
|
||||
PatchType.HERB_PATCH -> Animation(2282)
|
||||
PatchType.FLOWER_PATCH -> Animation(2292)
|
||||
else -> Animation(830)
|
||||
}
|
||||
}
|
||||
Items.SECATEURS_5329 -> if (fPatch.type == PatchType.TREE_PATCH) Animation(2277) else Animation(7227)
|
||||
Items.MAGIC_SECATEURS_7409 -> if (fPatch.type == PatchType.TREE_PATCH) Animation(3340) else Animation(7228)
|
||||
else -> Animation(0)
|
||||
|
|
@ -76,12 +82,15 @@ class CropHarvester : OptionHandler() {
|
|||
sendMessage(player, "You lack the needed tool to harvest these crops.")
|
||||
return true
|
||||
}
|
||||
if (firstHarvest) {
|
||||
val sendHarvestMessages = if (fPatch.type == PatchType.FLOWER_PATCH) false else true
|
||||
if (sendHarvestMessages && firstHarvest) {
|
||||
sendMessage(player, "You begin to harvest the $patchName.")
|
||||
firstHarvest = false
|
||||
}
|
||||
animate(player, anim)
|
||||
playAudio(player, sound)
|
||||
// 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)
|
||||
rewardXP(player, Skills.FARMING, plantable.harvestXP)
|
||||
|
|
@ -96,7 +105,7 @@ class CropHarvester : OptionHandler() {
|
|||
patch.clear()
|
||||
}
|
||||
}
|
||||
if (patch.cropLives <= 0 || patch.harvestAmt <= 0) {
|
||||
if (sendHarvestMessages && (patch.cropLives <= 0 || patch.harvestAmt <= 0)) {
|
||||
sendMessage(player, "The $patchName is now empty.")
|
||||
}
|
||||
return patch.cropLives <= 0 || patch.harvestAmt <= 0
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class DigUpPatchDialogue(player: Player? = null) : DialoguePlugin(player) {
|
|||
}
|
||||
if (patch?.patch?.type == PatchType.TREE_PATCH) {
|
||||
val isTreeStump = patch?.getCurrentState() == patch?.plantable!!.value + patch?.plantable!!.stages + 2
|
||||
if (!isTreeStump) {
|
||||
if (patch!!.isGrown() && !isTreeStump) {
|
||||
sendMessage(player, "You need to chop this tree down first.") // this message is not authentic
|
||||
stage = 1000
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -1,66 +1,111 @@
|
|||
package content.global.skill.farming
|
||||
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import core.api.*
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.item.Item
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.START_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class FarmerPayOptionDialogue(val patch: Patch): DialogueFile() {
|
||||
class FarmerPayOptionDialogue(val patch: Patch, val quickPay: Boolean = false): DialogueFile() {
|
||||
var item: Item? = null
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when(stage){
|
||||
when (stage) {
|
||||
START_DIALOGUE -> {
|
||||
if (patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()) {
|
||||
// This is for the right-click "Pay" option; full dialogue is in GardenerDialoguePlugin
|
||||
showTopics(
|
||||
Topic("Yes, get rid of the tree.", 300, true),
|
||||
Topic("No thanks.", END_DIALOGUE, true),
|
||||
title = "Pay 200 gp to have the tree chopped down?"
|
||||
)
|
||||
} else if (patch.protectionPaid) {
|
||||
npc("I don't know what you're talking about - I'm already", "looking after that patch for you.").also { stage = 100 }
|
||||
} else if (patch.isDead) {
|
||||
npc("That patch is dead - it's too late for me to do", "anything about it now.").also { stage = END_DIALOGUE }
|
||||
} else if (patch.isDiseased) {
|
||||
npc("That patch is diseased - I can't look after it", "until it has been cured.").also { stage = END_DIALOGUE } // this dialogue is not authentic
|
||||
} else if (patch.isWeedy() || patch.isEmptyAndWeeded()) {
|
||||
npc(FacialExpression.NEUTRAL, "You don't have anything planted in that patch. Plant", "something and I might agree to look after it for you.").also { stage = END_DIALOGUE }
|
||||
} else if (patch.isGrown()) {
|
||||
npc("That patch is already fully grown!", "I don't know what you want me to do with it!").also { stage = END_DIALOGUE }
|
||||
} else {
|
||||
item = patch.plantable?.protectionItem
|
||||
val protectionText = when(item?.id){
|
||||
Items.COMPOST_6032 -> if(item?.amount == 1) "bucket of compost" else "buckets of compost"
|
||||
Items.POTATOES10_5438 -> if(item?.amount == 1) "sack of potatoes" else "sacks of potatoes"
|
||||
Items.ONIONS10_5458 -> if(item?.amount == 1) "sack of onions" else "sacks of onions"
|
||||
Items.CABBAGES10_5478 -> if(item?.amount == 1) "sack of cabbages" else "sacks of cabbages"
|
||||
val protectionText = when (item?.id) {
|
||||
Items.COMPOST_6032 -> if (item?.amount == 1) "bucket of compost" else "buckets of compost"
|
||||
Items.POTATOES10_5438 -> if (item?.amount == 1) "sack of potatoes" else "sacks of potatoes"
|
||||
Items.ONIONS10_5458 -> if (item?.amount == 1) "sack of onions" else "sacks of onions"
|
||||
Items.CABBAGES10_5478 -> if (item?.amount == 1) "sack of cabbages" else "sacks of cabbages"
|
||||
Items.JUTE_FIBRE_5931 -> "jute fibres"
|
||||
Items.APPLES5_5386 -> if(item?.amount == 1) "basket of apples" else "baskets of apples"
|
||||
Items.APPLES5_5386 -> if (item?.amount == 1) "basket of apples" else "baskets of apples"
|
||||
Items.MARIGOLDS_6010 -> "harvest of marigold"
|
||||
Items.TOMATOES5_5968 -> if(item?.amount == 1) "basket of tomatoes" else "baskets of tomatoes"
|
||||
Items.ORANGES5_5396 -> if(item?.amount == 1) "basket of oranges" else "baskets of oranges"
|
||||
Items.TOMATOES5_5968 -> if (item?.amount == 1) "basket of tomatoes" else "baskets of tomatoes"
|
||||
Items.ORANGES5_5396 -> if (item?.amount == 1) "basket of oranges" else "baskets of oranges"
|
||||
Items.COCONUT_5974 -> "coconuts"
|
||||
Items.CACTUS_SPINE_6016 -> "cactus spines"
|
||||
Items.STRAWBERRIES5_5406 -> if(item?.amount == 1) "basket of strawberries" else "baskets of strawberries"
|
||||
Items.BANANAS5_5416 -> if(item?.amount == 1) "basket of bananas" else "baskets of bananas"
|
||||
else -> item?.name?.toLowerCase()
|
||||
Items.STRAWBERRIES5_5406 -> if (item?.amount == 1) "basket of strawberries" else "baskets of strawberries"
|
||||
Items.BANANAS5_5416 -> if (item?.amount == 1) "basket of bananas" else "baskets of bananas"
|
||||
else -> item?.name?.lowercase()
|
||||
}
|
||||
if(item == null) npc("Sorry, I won't protect that.").also { stage = END_DIALOGUE }
|
||||
else{
|
||||
npc("I would like ${item?.amount} $protectionText","to protect that patch.")
|
||||
if (item == null) {
|
||||
npc("Sorry, I won't protect that.").also { stage = END_DIALOGUE }
|
||||
} else if (quickPay && !(inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount))) {
|
||||
val amount = if (item?.amount == 1) "one" else item?.amount
|
||||
npc(FacialExpression.HAPPY, "I want $amount $protectionText for that.")
|
||||
stage = 200
|
||||
} else if (quickPay) {
|
||||
val amount = if (item?.amount == 1) "one" else item?.amount
|
||||
showTopics(
|
||||
Topic("Yes", 20, true),
|
||||
Topic("No", END_DIALOGUE, true),
|
||||
title = "Pay $amount $protectionText?"
|
||||
)
|
||||
} else {
|
||||
val amount = if (item?.amount == 1) "one" else item?.amount
|
||||
npc("If you like, but I want $amount $protectionText for that.")
|
||||
stage++
|
||||
}
|
||||
}
|
||||
|
||||
1 -> options("Sure!","No, thanks.").also { stage++ }
|
||||
2 -> {
|
||||
if(player!!.inventory.containsItem(item)){
|
||||
player("Here you go.").also { stage = 10 }
|
||||
} else {
|
||||
item = Item(item!!.noteChange,item!!.amount)
|
||||
if(player!!.inventory.containsItem(item)){
|
||||
player("Here you go.").also { stage = 10 }
|
||||
} else {
|
||||
player("I don't have that to give.").also { stage = 20 }
|
||||
}
|
||||
|
||||
1 -> {
|
||||
if (!(inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount))) {
|
||||
player("I'm afraid I don't have any of those at the moment.").also { stage = 10 }
|
||||
} else {
|
||||
showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Okay, it's a deal.", 20),
|
||||
Topic(FacialExpression.NEUTRAL, "No, that's too much.", 10)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
10 -> {
|
||||
if(player!!.inventory.remove(item)){
|
||||
npc("Thank you! I'll keep an eye on this patch.").also { stage = END_DIALOGUE }
|
||||
patch?.protectionPaid = true
|
||||
} else {
|
||||
npc("That stuff just... vanished....").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
10 -> npc("Well, I'm not wasting my time for free.").also { stage = END_DIALOGUE }
|
||||
|
||||
20 -> {
|
||||
npc("Come back when you do.")
|
||||
stage = END_DIALOGUE
|
||||
if (removeItem(player!!, item) || removeItem(player!!, note(item!!))) {
|
||||
patch.protectionPaid = true
|
||||
// Note: A slight change in this dialogue was seen in a December 2009 video - https://youtu.be/7gVh42ylQ48?t=138
|
||||
npc("That'll do nicely, ${if (player!!.isMale) "sir" else "madam"}. Leave it with me - I'll make sure", "those crops grow for you.").also { stage = END_DIALOGUE }
|
||||
} else {
|
||||
npc("This shouldn't be happening. Please report this.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
|
||||
100 -> player("Oh sorry, I forgot.").also { stage = END_DIALOGUE }
|
||||
|
||||
// Right-click "Pay" - protect patch - player doesn't have payment
|
||||
200 -> player(FacialExpression.NEUTRAL, "Thanks, maybe another time.").also { stage = END_DIALOGUE }
|
||||
|
||||
// Right-click "Pay" - chop down tree
|
||||
300 -> {
|
||||
if (removeItem(player!!, Item(Items.COINS_995, 200))) {
|
||||
patch.clear()
|
||||
dialogue("The gardener obligingly removes your tree.").also { stage = END_DIALOGUE }
|
||||
} else {
|
||||
dialogue("You need 200 gp to pay for that.").also { stage = END_DIALOGUE } // not authentic
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.skill.farming
|
||||
|
||||
import core.api.openDialogue
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.interaction.InteractionListener
|
||||
|
|
@ -8,35 +9,20 @@ import core.game.interaction.IntType
|
|||
class FarmerPayOptionHandler : InteractionListener {
|
||||
|
||||
override fun defineListeners() {
|
||||
on(IntType.NPC,"pay","pay (north)","pay (north-west)"){ player, node ->
|
||||
on(IntType.NPC,"pay","pay (north)","pay (north-west)") { player, node ->
|
||||
return@on attemptPay(player,node,0)
|
||||
}
|
||||
|
||||
on(IntType.NPC,"pay (south)","pay (south-east)"){ player, node ->
|
||||
on(IntType.NPC,"pay (south)","pay (south-east)") { player, node ->
|
||||
return@on attemptPay(player,node,1)
|
||||
}
|
||||
}
|
||||
|
||||
fun attemptPay(player: Player, node: Node, index: Int): Boolean{
|
||||
fun attemptPay(player: Player, node: Node, index: Int): Boolean {
|
||||
val farmer = Farmers.forId(node.id) ?: return false
|
||||
val patch = farmer.patches[index].getPatchFor(player)
|
||||
|
||||
if(patch.plantable == null){
|
||||
player.dialogueInterpreter.sendDialogue("I have nothing to protect in that patch.")
|
||||
return true
|
||||
}
|
||||
|
||||
if(patch.protectionPaid){
|
||||
player.dialogueInterpreter.sendDialogue("I have already paid to protect that patch.")
|
||||
return true
|
||||
}
|
||||
|
||||
if(patch.isGrown()){
|
||||
player.dialogueInterpreter.sendDialogue("This patch is already fully grown!")
|
||||
return true
|
||||
}
|
||||
|
||||
player.dialogueInterpreter.open(FarmerPayOptionDialogue(patch),node.asNpc())
|
||||
openDialogue(player, FarmerPayOptionDialogue(patch, true), node.asNpc())
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -117,8 +117,8 @@ enum class FarmingPatch(val varbit: Int, val type: PatchType) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getPatchFor(player: Player): Patch{
|
||||
var crops = getOrStartTimer <CropGrowth> (player)!!
|
||||
return crops.getPatch(this)
|
||||
fun getPatchFor(player: Player, addPatch : Boolean = true): Patch{
|
||||
val crops = getOrStartTimer <CropGrowth> (player)
|
||||
return crops.getPatch(this, addPatch)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
package content.global.skill.farming
|
||||
|
||||
import core.api.*
|
||||
import core.Util.clamp
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.task.Pulse
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.simple.JSONArray
|
||||
import org.json.simple.JSONObject
|
||||
import core.game.node.entity.state.PlayerState
|
||||
import core.game.node.entity.state.State
|
||||
import core.tools.SystemLogger
|
||||
import java.util.concurrent.TimeUnit
|
||||
import content.global.skill.farming.timers.*
|
||||
|
||||
@PlayerState("farming")
|
||||
/**
|
||||
* Kept around solely for the purpose of porting save data from this old system to the new one.
|
||||
* //TODO REMOVE BY END OF 2023
|
||||
**/
|
||||
class FarmingState(player: Player? = null) : State(player) {
|
||||
override fun save(root: JSONObject) {}
|
||||
override fun parse(_data: JSONObject) {
|
||||
player ?: return
|
||||
if(_data.containsKey("farming-bins")){
|
||||
_data["bins"] = _data["farming-bins"]
|
||||
val timer = getOrStartTimer <Compost> (player)
|
||||
timer.parse (_data, player)
|
||||
}
|
||||
if(_data.containsKey("farming-patches")){
|
||||
_data["patches"] = _data["farming-patches"]
|
||||
val timer = getOrStartTimer <CropGrowth> (player)
|
||||
timer.parse(_data, player)
|
||||
}
|
||||
}
|
||||
|
||||
override fun newInstance(player: Player?): State {
|
||||
return FarmingState(player)
|
||||
}
|
||||
|
||||
override fun createPulse() {}
|
||||
}
|
||||
|
|
@ -36,13 +36,22 @@ class HealthChecker : OptionHandler() {
|
|||
rewardXP(player, Skills.FARMING, patch.plantable?.checkHealthXP ?: 0.0)
|
||||
patch.isCheckHealth = false
|
||||
when (type) {
|
||||
PatchType.TREE_PATCH -> patch.setCurrentState(patch.getCurrentState() + 1)
|
||||
PatchType.FRUIT_TREE_PATCH -> patch.setCurrentState(patch.getCurrentState() - 14)
|
||||
PatchType.BUSH_PATCH -> {
|
||||
sendMessage(player, "You examine the bush for signs of disease and find that it's in perfect health.")
|
||||
patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 4)
|
||||
PatchType.TREE_PATCH -> {
|
||||
patch.setCurrentState(patch.getCurrentState() + 1)
|
||||
sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.")
|
||||
}
|
||||
PatchType.FRUIT_TREE_PATCH -> {
|
||||
patch.setCurrentState(patch.getCurrentState() - 14)
|
||||
sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.")
|
||||
}
|
||||
PatchType.BUSH_PATCH -> {
|
||||
patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 4)
|
||||
sendMessage(player, "You examine the bush for signs of disease and find that it's in perfect health.")
|
||||
}
|
||||
PatchType.CACTUS_PATCH -> {
|
||||
patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 3)
|
||||
sendMessage(player, "You examine the cactus for signs of disease and find that it is in perfect health.")
|
||||
}
|
||||
PatchType.CACTUS_PATCH -> patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 3)
|
||||
else -> log(this::class.java, Log.ERR, "Unreachable patch type from when(type) switch in HealthChecker.kt")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
log(this::class.java, Log.DEBUG, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to diseased at stage $currentGrowthStage, which isn't valid.")
|
||||
return (state and (0x80.inv()))
|
||||
}
|
||||
else if (state in listOf(0, 1, 2, 3)){
|
||||
// we're weedy (or an empty plot) as normal just continue
|
||||
}
|
||||
else {
|
||||
log (this::class.java, Log.ERR, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to state $state at growth stage $currentGrowthStage, which isn't valid. We're not sure why this is happening.")
|
||||
}
|
||||
|
|
@ -134,6 +137,13 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
return compost != CompostType.NONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the patch is fully grown.
|
||||
*
|
||||
* Note: This returns true if the patch is fully weedy.
|
||||
* Use `plantable == null` to check if a patch does
|
||||
* not have anything planted.
|
||||
*/
|
||||
fun isGrown(): Boolean{
|
||||
return currentGrowthStage == (plantable?.stages ?: 0)
|
||||
}
|
||||
|
|
@ -276,19 +286,19 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
return
|
||||
}
|
||||
|
||||
diseaseMod = when(compost){
|
||||
// This is so a cheat can force disease
|
||||
diseaseMod = if (diseaseMod < 0) -128 else when(compost){
|
||||
CompostType.NONE -> 0
|
||||
CompostType.COMPOST -> 8
|
||||
CompostType.SUPERCOMPOST -> 13
|
||||
}
|
||||
|
||||
if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB && RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid && !isFlowerProtected() && patch.type != PatchType.EVIL_TURNIP_PATCH ){
|
||||
//bush, tree, fruit tree, herb and cactus can not disease on stage 1(0) of growth.
|
||||
if(!((patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.CACTUS_PATCH || patch.type == PatchType.HERB_PATCH) && currentGrowthStage == 0)) {
|
||||
if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB && RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid && !isFlowerProtected() && patch.type != PatchType.EVIL_TURNIP_PATCH && 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
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if((patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.TREE_PATCH || patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.CACTUS_PATCH) && plantable != null && plantable?.stages == currentGrowthStage + 1){
|
||||
isCheckHealth = true
|
||||
|
|
@ -376,7 +386,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
FarmingPatch.CATHERBY_ALLOTMENT_S,FarmingPatch.CATHERBY_ALLOTMENT_N -> FarmingPatch.CATHERBY_FLOWER_C
|
||||
FarmingPatch.PORT_PHAS_ALLOTMENT_SE,FarmingPatch.PORT_PHAS_ALLOTMENT_NW -> FarmingPatch.PORT_PHAS_FLOWER_C
|
||||
else -> return false
|
||||
}.getPatchFor(player)
|
||||
}.getPatchFor(player, false)
|
||||
|
||||
return (fpatch.plantable != null &&
|
||||
(fpatch.plantable == plantable?.protectionFlower || fpatch.plantable == Plantable.forItemID(Items.WHITE_LILY_SEED_14589))
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ object PatchRaker {
|
|||
val p = patch.getPatchFor(player)
|
||||
val patchName = p.patch.type.displayName()
|
||||
var firstRake = true
|
||||
if (p.isEmptyAndWeeded()) {
|
||||
if (!p.isWeedy()) {
|
||||
sendMessage(player, "This $patchName doesn't need weeding right now.")
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,88 +3,88 @@ package content.global.skill.farming
|
|||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
|
||||
enum class Plantable(val itemID: Int, val value: Int, val stages: Int, val plantingXP: Double, val harvestXP: Double, val checkHealthXP: Double, val requiredLevel: Int, val applicablePatch: PatchType, val harvestItem: Int, val protectionItem: Item? = null,val protectionFlower: Plantable? = null) {
|
||||
enum class Plantable(val itemID: Int, val displayName: String, val value: Int, val stages: Int, val plantingXP: Double, val harvestXP: Double, val checkHealthXP: Double, val requiredLevel: Int, val applicablePatch: PatchType, val harvestItem: Int, val protectionItem: Item? = null, val protectionFlower: Plantable? = null) {
|
||||
|
||||
//Flowers
|
||||
MARIGOLD_SEED(5096,8,4,8.5,47.0,0.0,2,PatchType.FLOWER_PATCH,Items.MARIGOLDS_6010),
|
||||
ROSEMARY_SEED(5097,13,4,12.0,66.5,0.0,11,PatchType.FLOWER_PATCH, Items.ROSEMARY_6014),
|
||||
NASTURTIUM_SEED(5098,18,4,19.5,111.0,0.0,24,PatchType.FLOWER_PATCH,Items.NASTURTIUMS_6012),
|
||||
WOAD_SEED(5099,23,4,20.5,115.5,0.0,25,PatchType.FLOWER_PATCH,Items.WOAD_LEAF_1793),
|
||||
LIMPWURT_SEED(5100,28,4,21.5,120.0,0.0,26,PatchType.FLOWER_PATCH,Items.LIMPWURT_ROOT_225),
|
||||
WHITE_LILY_SEED(14589,37,4,42.0,250.0,0.0,52,PatchType.FLOWER_PATCH,Items.WHITE_LILY_14583),
|
||||
// Flowers
|
||||
MARIGOLD_SEED(Items.MARIGOLD_SEED_5096,"marigold seed",8,4,8.5,47.0,0.0,2,PatchType.FLOWER_PATCH,Items.MARIGOLDS_6010),
|
||||
ROSEMARY_SEED(Items.ROSEMARY_SEED_5097,"rosemary seed",13,4,12.0,66.5,0.0,11,PatchType.FLOWER_PATCH, Items.ROSEMARY_6014),
|
||||
NASTURTIUM_SEED(Items.NASTURTIUM_SEED_5098,"nasturtium seed",18,4,19.5,111.0,0.0,24,PatchType.FLOWER_PATCH,Items.NASTURTIUMS_6012),
|
||||
WOAD_SEED(Items.WOAD_SEED_5099,"woad seed",23,4,20.5,115.5,0.0,25,PatchType.FLOWER_PATCH,Items.WOAD_LEAF_1793),
|
||||
LIMPWURT_SEED(Items.LIMPWURT_SEED_5100,"limpwurt seed",28,4,21.5,120.0,0.0,26,PatchType.FLOWER_PATCH,Items.LIMPWURT_ROOT_225),
|
||||
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(6059,33,3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059),
|
||||
// Flower (technically)
|
||||
SCARECROW(Items.SCARECROW_6059,"scarecrow",33,3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059),
|
||||
|
||||
//Allotments
|
||||
POTATO_SEED(5318, 6, 4, 8.0, 9.0, 0.0, 1, PatchType.ALLOTMENT, Items.POTATO_1942,Item(Items.COMPOST_6032,2),MARIGOLD_SEED),
|
||||
ONION_SEED(5319, 13, 4, 9.5, 10.5,0.0, 5, PatchType.ALLOTMENT,Items.ONION_1957,Item(Items.POTATOES10_5438),MARIGOLD_SEED),
|
||||
CABBAGE_SEED(5324, 20, 4, 10.0, 11.5, 0.0,7, PatchType.ALLOTMENT,Items.CABBAGE_1965,Item(Items.ONIONS10_5458),ROSEMARY_SEED),
|
||||
TOMATO_SEED(5322,27,4,12.5,14.0,0.0,12,PatchType.ALLOTMENT,Items.TOMATO_1982,Item(Items.CABBAGES10_5478,2),MARIGOLD_SEED),
|
||||
SWEETCORN_SEED(5320,34,6,17.0,19.0,0.0,20,PatchType.ALLOTMENT,Items.SWEETCORN_5986,Item(Items.JUTE_FIBRE_5931,10),SCARECROW),
|
||||
STRAWBERRY_SEED(5323,43,6,26.0,29.0,0.0,31,PatchType.ALLOTMENT,Items.STRAWBERRY_5504,Item(Items.APPLES5_5386)),
|
||||
WATERMELON_SEED(5321,52,8,48.5,54.5,0.0,47,PatchType.ALLOTMENT,Items.WATERMELON_5982,Item(Items.CURRY_LEAF_5970,10),NASTURTIUM_SEED),
|
||||
// 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),
|
||||
ONION_SEED(Items.ONION_SEED_5319, "onion seed", 13, 4, 9.5, 10.5,0.0, 5, PatchType.ALLOTMENT,Items.ONION_1957,Item(Items.POTATOES10_5438),MARIGOLD_SEED),
|
||||
CABBAGE_SEED(Items.CABBAGE_SEED_5324, "cabbage seed", 20, 4, 10.0, 11.5, 0.0,7, PatchType.ALLOTMENT,Items.CABBAGE_1965,Item(Items.ONIONS10_5458),ROSEMARY_SEED),
|
||||
TOMATO_SEED(Items.TOMATO_SEED_5322,"tomato seed",27,4,12.5,14.0,0.0,12,PatchType.ALLOTMENT,Items.TOMATO_1982,Item(Items.CABBAGES10_5478,2),MARIGOLD_SEED),
|
||||
SWEETCORN_SEED(Items.SWEETCORN_SEED_5320,"sweetcorn seed",34,6,17.0,19.0,0.0,20,PatchType.ALLOTMENT,Items.SWEETCORN_5986,Item(Items.JUTE_FIBRE_5931,10),SCARECROW),
|
||||
STRAWBERRY_SEED(Items.STRAWBERRY_SEED_5323,"strawberry seed",43,6,26.0,29.0,0.0,31,PatchType.ALLOTMENT,Items.STRAWBERRY_5504,Item(Items.APPLES5_5386)),
|
||||
WATERMELON_SEED(Items.WATERMELON_SEED_5321,"watermelon seed",52,8,48.5,54.5,0.0,47,PatchType.ALLOTMENT,Items.WATERMELON_5982,Item(Items.CURRY_LEAF_5970,10),NASTURTIUM_SEED),
|
||||
|
||||
//Hops
|
||||
BARLEY_SEED(5305,49,4,8.5,9.5,0.0,3,PatchType.HOPS_PATCH,Items.BARLEY_6006,Item(Items.COMPOST_6032,3)),
|
||||
HAMMERSTONE_SEED(5307,4,4,9.0,10.0,0.0,4,PatchType.HOPS_PATCH,Items.HAMMERSTONE_HOPS_5994,Item(Items.MARIGOLDS_6010)),
|
||||
ASGARNIAN_SEED(5308,11,5,10.9,12.0,0.0,8,PatchType.HOPS_PATCH,Items.ASGARNIAN_HOPS_5996,Item(Items.ONIONS10_5458)),
|
||||
JUTE_SEED(5306,56,5,13.0,14.5,0.0,13,PatchType.HOPS_PATCH,Items.JUTE_FIBRE_5931,Item(Items.BARLEY_MALT_6008,6)),
|
||||
YANILLIAN_SEED(5309,19,6,14.5,16.0,0.0,16,PatchType.HOPS_PATCH,Items.YANILLIAN_HOPS_5998,Item(Items.TOMATOES5_5968)),
|
||||
KRANDORIAN_SEED(5310,28,7,17.5,19.5,0.0,21,PatchType.HOPS_PATCH,Items.KRANDORIAN_HOPS_6000,Item(Items.CABBAGES10_5478,3)),
|
||||
WILDBLOOD_SEED(5311,38,8,23.0,26.0,0.0,28,PatchType.HOPS_PATCH,Items.WILDBLOOD_HOPS_6002,Item(Items.NASTURTIUMS_6012)),
|
||||
// Hops
|
||||
BARLEY_SEED(Items.BARLEY_SEED_5305,"barley seed",49,4,8.5,9.5,0.0,3,PatchType.HOPS_PATCH,Items.BARLEY_6006,Item(Items.COMPOST_6032,3)),
|
||||
HAMMERSTONE_SEED(Items.HAMMERSTONE_SEED_5307,"Hammerstone hop seed",4,4,9.0,10.0,0.0,4,PatchType.HOPS_PATCH,Items.HAMMERSTONE_HOPS_5994,Item(Items.MARIGOLDS_6010)),
|
||||
ASGARNIAN_SEED(Items.ASGARNIAN_SEED_5308,"Asgarnian hop seed",11,5,10.9,12.0,0.0,8,PatchType.HOPS_PATCH,Items.ASGARNIAN_HOPS_5996,Item(Items.ONIONS10_5458)),
|
||||
JUTE_SEED(Items.JUTE_SEED_5306,"jute plant seed",56,5,13.0,14.5,0.0,13,PatchType.HOPS_PATCH,Items.JUTE_FIBRE_5931,Item(Items.BARLEY_MALT_6008,6)),
|
||||
YANILLIAN_SEED(Items.YANILLIAN_SEED_5309,"Yanillian hop seed",19,6,14.5,16.0,0.0,16,PatchType.HOPS_PATCH,Items.YANILLIAN_HOPS_5998,Item(Items.TOMATOES5_5968)),
|
||||
KRANDORIAN_SEED(Items.KRANDORIAN_SEED_5310,"Krandorian hop seed",28,7,17.5,19.5,0.0,21,PatchType.HOPS_PATCH,Items.KRANDORIAN_HOPS_6000,Item(Items.CABBAGES10_5478,3)),
|
||||
WILDBLOOD_SEED(Items.WILDBLOOD_SEED_5311,"Wildblood hop seed",38,8,23.0,26.0,0.0,28,PatchType.HOPS_PATCH,Items.WILDBLOOD_HOPS_6002,Item(Items.NASTURTIUMS_6012)),
|
||||
|
||||
//Trees
|
||||
OAK_SAPLING(5370,8,4,14.0,0.0,467.3,15,PatchType.TREE_PATCH,Items.OAK_ROOTS_6043,Item(Items.TOMATOES5_5968)),
|
||||
WILLOW_SAPLING(5371,15,6,25.0,0.0,1456.5,30,PatchType.TREE_PATCH,Items.WILLOW_ROOTS_6045,Item(Items.APPLES5_5386)),
|
||||
MAPLE_SAPLING(5372,24,8,45.0,0.0,3403.4,45,PatchType.TREE_PATCH,Items.MAPLE_ROOTS_6047,Item(Items.ORANGES5_5396)),
|
||||
YEW_SAPLING(5373,35,10,81.0,0.0,7069.9,60,PatchType.TREE_PATCH,Items.YEW_ROOTS_6049,Item(Items.CACTUS_SPINE_6016,10)),
|
||||
MAGIC_SAPLING(5374,48,12,145.5,0.0,13768.3,75,PatchType.TREE_PATCH,Items.MAGIC_ROOTS_6051,Item(Items.COCONUT_5974,25)),
|
||||
// Trees
|
||||
OAK_SAPLING(Items.OAK_SAPLING_5370,"oak sapling",8,4,14.0,0.0,467.3,15,PatchType.TREE_PATCH,Items.OAK_ROOTS_6043,Item(Items.TOMATOES5_5968)),
|
||||
WILLOW_SAPLING(Items.WILLOW_SAPLING_5371,"willow sapling",15,6,25.0,0.0,1456.5,30,PatchType.TREE_PATCH,Items.WILLOW_ROOTS_6045,Item(Items.APPLES5_5386)),
|
||||
MAPLE_SAPLING(Items.MAPLE_SAPLING_5372,"maple sapling",24,8,45.0,0.0,3403.4,45,PatchType.TREE_PATCH,Items.MAPLE_ROOTS_6047,Item(Items.ORANGES5_5396)),
|
||||
YEW_SAPLING(Items.YEW_SAPLING_5373,"yew sapling",35,10,81.0,0.0,7069.9,60,PatchType.TREE_PATCH,Items.YEW_ROOTS_6049,Item(Items.CACTUS_SPINE_6016,10)),
|
||||
MAGIC_SAPLING(Items.MAGIC_SAPLING_5374,"magic Tree sapling",48,12,145.5,0.0,13768.3,75,PatchType.TREE_PATCH,Items.MAGIC_ROOTS_6051,Item(Items.COCONUT_5974,25)),
|
||||
|
||||
//Fruit Trees
|
||||
APPLE_SAPLING(5496,8,6,22.0,8.5,1199.5,27,PatchType.FRUIT_TREE_PATCH,Items.COOKING_APPLE_1955,Item(Items.SWEETCORN_5986,9)),
|
||||
BANANA_SAPLING(5497,35,6,28.0,10.5,1750.5,33,PatchType.FRUIT_TREE_PATCH,Items.BANANA_1963,Item(Items.APPLES5_5386,4)),
|
||||
ORANGE_SAPLING(5498,72,6,35.5,13.5,2470.2,39,PatchType.FRUIT_TREE_PATCH,Items.ORANGE_2108,Item(Items.STRAWBERRIES5_5406,3)),
|
||||
CURRY_SAPLING(5499,99,6,40.0,15.0,2906.9,42,PatchType.FRUIT_TREE_PATCH,Items.CURRY_LEAF_5970,Item(Items.BANANAS5_5416,5)),
|
||||
PINEAPPLE_SAPLING(5500,136,6,57.0,21.5,4605.7,51,PatchType.FRUIT_TREE_PATCH,Items.PINEAPPLE_2114,Item(Items.WATERMELON_5982,10)),
|
||||
PAPAYA_SAPLING(5501,163,6,72.0,27.0,6146.4,57,PatchType.FRUIT_TREE_PATCH,Items.PAPAYA_FRUIT_5972,Item(Items.PINEAPPLE_2114,10)),
|
||||
PALM_SAPLING(5502,200,6,110.5,41.5,10150.1,68,PatchType.FRUIT_TREE_PATCH,Items.COCONUT_5974,Item(Items.PAPAYA_FRUIT_5972,15)),
|
||||
// Fruit Trees
|
||||
APPLE_SAPLING(Items.APPLE_SAPLING_5496,"apple tree sapling",8,6,22.0,8.5,1199.5,27,PatchType.FRUIT_TREE_PATCH,Items.COOKING_APPLE_1955,Item(Items.SWEETCORN_5986,9)),
|
||||
BANANA_SAPLING(Items.BANANA_SAPLING_5497,"banana tree sapling",35,6,28.0,10.5,1750.5,33,PatchType.FRUIT_TREE_PATCH,Items.BANANA_1963,Item(Items.APPLES5_5386,4)),
|
||||
ORANGE_SAPLING(Items.ORANGE_SAPLING_5498,"orange tree sapling",72,6,35.5,13.5,2470.2,39,PatchType.FRUIT_TREE_PATCH,Items.ORANGE_2108,Item(Items.STRAWBERRIES5_5406,3)),
|
||||
CURRY_SAPLING(Items.CURRY_SAPLING_5499,"curry tree sapling",99,6,40.0,15.0,2906.9,42,PatchType.FRUIT_TREE_PATCH,Items.CURRY_LEAF_5970,Item(Items.BANANAS5_5416,5)),
|
||||
PINEAPPLE_SAPLING(Items.PINEAPPLE_SAPLING_5500,"pineapple plant",136,6,57.0,21.5,4605.7,51,PatchType.FRUIT_TREE_PATCH,Items.PINEAPPLE_2114,Item(Items.WATERMELON_5982,10)),
|
||||
PAPAYA_SAPLING(Items.PAPAYA_SAPLING_5501,"papaya tree sapling",163,6,72.0,27.0,6146.4,57,PatchType.FRUIT_TREE_PATCH,Items.PAPAYA_FRUIT_5972,Item(Items.PINEAPPLE_2114,10)),
|
||||
PALM_SAPLING(Items.PALM_SAPLING_5502,"palm tree sapling",200,6,110.5,41.5,10150.1,68,PatchType.FRUIT_TREE_PATCH,Items.COCONUT_5974,Item(Items.PAPAYA_FRUIT_5972,15)),
|
||||
|
||||
//Bushes
|
||||
REDBERRY_SEED(5101,5,5,11.5,4.5,64.0,10,PatchType.BUSH_PATCH,Items.REDBERRIES_1951,Item(Items.CABBAGES10_5478,4)),
|
||||
CADAVABERRY_SEED(5102,15,6,18.0,7.0,102.5,22,PatchType.BUSH_PATCH,Items.CADAVA_BERRIES_753,Item(Items.TOMATOES5_5968,3)),
|
||||
DWELLBERRY_SEED(5103,26,27,31.5,12.0,177.5,36,PatchType.BUSH_PATCH,Items.DWELLBERRIES_2126,Item(Items.STRAWBERRIES5_5406,3)),
|
||||
JANGERBERRY_SEED(5104,38,8,50.5,19.0,284.5,48,PatchType.BUSH_PATCH,Items.JANGERBERRIES_247,Item(Items.WATERMELON_5982,6)),
|
||||
WHITEBERRY_SEED(5105,51,8,78.0,29.0,437.5,59,PatchType.BUSH_PATCH,Items.WHITE_BERRIES_239,null),
|
||||
POISON_IVY_SEED(5106,197,8,120.0,45.0,675.0,70,PatchType.BUSH_PATCH,Items.POISON_IVY_BERRIES_6018,null),
|
||||
// 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)),
|
||||
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),
|
||||
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
|
||||
GUAM_SEED(5291,4,4,11.0,12.5,0.0,9,PatchType.HERB_PATCH,Items.GRIMY_GUAM_199),
|
||||
MARRENTILL_SEED(5292,11,4,13.5,15.0,0.0,14,PatchType.HERB_PATCH,Items.GRIMY_MARRENTILL_201),
|
||||
TARROMIN_SEED(5293,18,4,16.0,18.0,0.0,19,PatchType.HERB_PATCH,Items.GRIMY_TARROMIN_203),
|
||||
HARRALANDER_SEED(5294,25,4,21.5,24.0,0.0,26,PatchType.HERB_PATCH,Items.GRIMY_HARRALANDER_205),
|
||||
RANARR_SEED(5295,32,4,27.0,30.5,0.0,32,PatchType.HERB_PATCH,Items.GRIMY_RANARR_207),
|
||||
AVANTOE_SEED(5298,39,4,54.5,61.5,0.0,50,PatchType.HERB_PATCH,Items.GRIMY_AVANTOE_211),
|
||||
TOADFLAX_SEED(5296,46,4,34.0,38.5,0.0,38,PatchType.HERB_PATCH,Items.GRIMY_TOADFLAX_3049),
|
||||
IRIT_SEED(5297,53,4,43.0,48.5,0.0,44,PatchType.HERB_PATCH,Items.GRIMY_IRIT_209),
|
||||
KWUARM_SEED(5299,68,4,69.0,78.0,0.0,56,PatchType.HERB_PATCH,Items.GRIMY_KWUARM_213),
|
||||
SNAPDRAGON_SEED(5300,75,4,87.5,98.5,0.0,62,PatchType.HERB_PATCH,Items.GRIMY_SNAPDRAGON_3051),
|
||||
CADANTINE_SEED(5301,82,4,106.5,120.0,0.0,67,PatchType.HERB_PATCH,Items.GRIMY_CADANTINE_215),
|
||||
LANTADYME_SEED(5302,89,4,134.5,151.5,0.0,73,PatchType.HERB_PATCH,Items.GRIMY_LANTADYME_2485),
|
||||
DWARF_WEED_SEED(5303,96,4,170.5,192.0,0.0,79,PatchType.HERB_PATCH,Items.GRIMY_DWARF_WEED_217),
|
||||
TORSTOL_SEED(5304,103,4,199.5,224.5,0.0,85,PatchType.HERB_PATCH,Items.GRIMY_TORSTOL_219),
|
||||
GOUT_TUBER(6311,192,4,105.0,45.0,0.0,29,PatchType.HERB_PATCH,Items.GOUTWEED_3261),
|
||||
SPIRIT_WEED_SEED(12176, 204, 4, 32.0, 36.0, 0.0, 36, PatchType.HERB_PATCH, Items.GRIMY_SPIRIT_WEED_12174),
|
||||
// Herbs
|
||||
GUAM_SEED(Items.GUAM_SEED_5291,"guam seed",4,4,11.0,12.5,0.0,9,PatchType.HERB_PATCH,Items.GRIMY_GUAM_199),
|
||||
MARRENTILL_SEED(Items.MARRENTILL_SEED_5292,"marrentill seed",11,4,13.5,15.0,0.0,14,PatchType.HERB_PATCH,Items.GRIMY_MARRENTILL_201),
|
||||
TARROMIN_SEED(Items.TARROMIN_SEED_5293,"tarromin seed",18,4,16.0,18.0,0.0,19,PatchType.HERB_PATCH,Items.GRIMY_TARROMIN_203),
|
||||
HARRALANDER_SEED(Items.HARRALANDER_SEED_5294,"harralander seed",25,4,21.5,24.0,0.0,26,PatchType.HERB_PATCH,Items.GRIMY_HARRALANDER_205),
|
||||
RANARR_SEED(Items.RANARR_SEED_5295,"ranarr seed",32,4,27.0,30.5,0.0,32,PatchType.HERB_PATCH,Items.GRIMY_RANARR_207),
|
||||
AVANTOE_SEED(Items.AVANTOE_SEED_5298,"avantoe seed",39,4,54.5,61.5,0.0,50,PatchType.HERB_PATCH,Items.GRIMY_AVANTOE_211),
|
||||
TOADFLAX_SEED(Items.TOADFLAX_SEED_5296,"toadflax seed",46,4,34.0,38.5,0.0,38,PatchType.HERB_PATCH,Items.GRIMY_TOADFLAX_3049),
|
||||
IRIT_SEED(Items.IRIT_SEED_5297,"irit seed",53,4,43.0,48.5,0.0,44,PatchType.HERB_PATCH,Items.GRIMY_IRIT_209),
|
||||
KWUARM_SEED(Items.KWUARM_SEED_5299,"kwuarm seed",68,4,69.0,78.0,0.0,56,PatchType.HERB_PATCH,Items.GRIMY_KWUARM_213),
|
||||
SNAPDRAGON_SEED(Items.SNAPDRAGON_SEED_5300,"snapdragon seed",75,4,87.5,98.5,0.0,62,PatchType.HERB_PATCH,Items.GRIMY_SNAPDRAGON_3051),
|
||||
CADANTINE_SEED(Items.CADANTINE_SEED_5301,"cadantine seed",82,4,106.5,120.0,0.0,67,PatchType.HERB_PATCH,Items.GRIMY_CADANTINE_215),
|
||||
LANTADYME_SEED(Items.LANTADYME_SEED_5302,"lantadyme seed",89,4,134.5,151.5,0.0,73,PatchType.HERB_PATCH,Items.GRIMY_LANTADYME_2485),
|
||||
DWARF_WEED_SEED(Items.DWARF_WEED_SEED_5303,"dwarf weed seed",96,4,170.5,192.0,0.0,79,PatchType.HERB_PATCH,Items.GRIMY_DWARF_WEED_217),
|
||||
TORSTOL_SEED(Items.TORSTOL_SEED_5304,"torstol seed",103,4,199.5,224.5,0.0,85,PatchType.HERB_PATCH,Items.GRIMY_TORSTOL_219),
|
||||
GOUT_TUBER(Items.GOUT_TUBER_6311,"gout tuber",192,4,105.0,45.0,0.0,29,PatchType.HERB_PATCH,Items.GOUTWEED_3261),
|
||||
SPIRIT_WEED_SEED(Items.SPIRIT_WEED_SEED_12176,"spirit weed seed", 204, 4, 32.0, 36.0, 0.0, 36, PatchType.HERB_PATCH, Items.GRIMY_SPIRIT_WEED_12174),
|
||||
|
||||
//Other
|
||||
BELLADONNA_SEED(5281, 4, 4, 91.0, 128.0, 0.0, 63, PatchType.BELLADONNA_PATCH, Items.CAVE_NIGHTSHADE_2398),
|
||||
MUSHROOM_SPORE(Items.MUSHROOM_SPORE_5282, 6, 7, 61.5, 57.7, 0.0, 53, PatchType.MUSHROOM_PATCH, Items.MUSHROOM_6004),
|
||||
CACTUS_SEED(Items.CACTUS_SEED_5280, 8, 7, 66.5, 25.0, 374.0, 55, PatchType.CACTUS_PATCH, Items.CACTUS_SPINE_6016),
|
||||
EVIL_TURNIP_SEED(Items.EVIL_TURNIP_SEED_12148, 4, 1, 41.0, 46.0, 0.0, 42, PatchType.EVIL_TURNIP_PATCH, Items.EVIL_TURNIP_12134)
|
||||
// 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),
|
||||
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)
|
||||
;
|
||||
|
||||
constructor(itemID: Int, value: Int, stages: Int, plantingXP: Double, harvestXP: Double, checkHealthXP: Double, requiredLevel: Int, applicablePatch: PatchType, harvestItem: Int, protectionFlower: Plantable)
|
||||
: this(itemID,value,stages,plantingXP,harvestXP,checkHealthXP,requiredLevel,applicablePatch,harvestItem,null,protectionFlower)
|
||||
constructor(itemID: Int, displayName: String, value: Int, stages: Int, plantingXP: Double, harvestXP: Double, checkHealthXP: Double, requiredLevel: Int, applicablePatch: PatchType, harvestItem: Int, protectionFlower: Plantable)
|
||||
: this(itemID,displayName,value,stages,plantingXP,harvestXP,checkHealthXP,requiredLevel,applicablePatch,harvestItem,null,protectionFlower)
|
||||
companion object {
|
||||
@JvmField
|
||||
val plantables = values().map { it.itemID to it }.toMap()
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class ToolLeprechaunInterface : InterfaceListener {
|
|||
setHasMagicSecateurs(player,false)
|
||||
}
|
||||
} else {
|
||||
sendMessage(player, "You already have one of those stored.")
|
||||
sendMessage(player, "You cannot store more than one pair of secateurs in here.")
|
||||
}
|
||||
}
|
||||
22 -> {
|
||||
|
|
@ -80,7 +80,7 @@ class ToolLeprechaunInterface : InterfaceListener {
|
|||
removeItem(player, can)
|
||||
setWateringCan(player,can)
|
||||
} else {
|
||||
sendMessage(player, "You already have one of those stored.")
|
||||
sendMessage(player, "You cannot store more than one watering can in here.")
|
||||
}
|
||||
}
|
||||
23 -> doDeposit(player, Items.GARDENING_TROWEL_5325, ::setHasGardeningTrowel, ::hasGardeningTrowel)
|
||||
|
|
@ -119,7 +119,15 @@ class ToolLeprechaunInterface : InterfaceListener {
|
|||
depositMethod.invoke(player, true)
|
||||
removeItem(player, item)
|
||||
} else {
|
||||
sendMessage(player, "You already have one of those stored.")
|
||||
val itemName = when (item) {
|
||||
// secateurs and watering cans are handled separately
|
||||
Items.RAKE_5341 -> "rake"
|
||||
Items.SEED_DIBBER_5343 -> "dibber"
|
||||
Items.SPADE_952 -> "spade"
|
||||
Items.GARDENING_TROWEL_5325 -> "trowel"
|
||||
else -> getItemName(item).lowercase()
|
||||
}
|
||||
sendMessage(player, "You cannot store more than one $itemName in here.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ 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
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Items
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
|
|
@ -21,11 +20,14 @@ class UseWithPatchHandler : InteractionListener {
|
|||
val SECATEURS = Items.SECATEURS_5329
|
||||
val MAGIC_SECATEURS = Items.MAGIC_SECATEURS_7409
|
||||
val TROWEL = Items.GARDENING_TROWEL_5325
|
||||
val pourBucketAnim = Animation(2283)
|
||||
val wateringCanAnim = Animation(2293)
|
||||
val plantCureAnim = Animation(2288)
|
||||
val secateursTreeAnim = Animation(2277)
|
||||
val magicSecateursTreeAnim = Animation(3340)
|
||||
val spadeDigAnim = getAnimation(830)
|
||||
val trowelDigAnim = getAnimation(2272)
|
||||
val pourBucketAnim = getAnimation(2283)
|
||||
val seedDibberAnim = getAnimation(2291)
|
||||
val wateringCanAnim = getAnimation(2293)
|
||||
val plantCureAnim = getAnimation(2288)
|
||||
val secateursTreeAnim = getAnimation(2277)
|
||||
val magicSecateursTreeAnim = getAnimation(3340)
|
||||
|
||||
@JvmField
|
||||
val allowedNodes = ArrayList<Int>()
|
||||
|
|
@ -46,7 +48,7 @@ class UseWithPatchHandler : InteractionListener {
|
|||
RAKE -> PatchRaker.rake(player,patch)
|
||||
SEED_DIBBER -> sendMessage(player, "I should plant a seed, not the seed dibber.")
|
||||
SPADE -> {
|
||||
val anim = getAnimation(830)
|
||||
val anim = spadeDigAnim
|
||||
val p = patch.getPatchFor(player)
|
||||
if (p.isDead) {
|
||||
sendMessage(player, "You start digging the farming patch...")
|
||||
|
|
@ -112,7 +114,7 @@ class UseWithPatchHandler : InteractionListener {
|
|||
return@onUseWith true
|
||||
}
|
||||
|
||||
val anim = Animation(2272)
|
||||
val anim = trowelDigAnim
|
||||
|
||||
submitIndividualPulse(player, object : Pulse(anim.duration) {
|
||||
override fun pulse(): Boolean {
|
||||
|
|
@ -156,15 +158,21 @@ class UseWithPatchHandler : InteractionListener {
|
|||
Items.WATERING_CAN_5331,Items.WATERING_CAN1_5333,Items.WATERING_CAN2_5334,Items.WATERING_CAN3_5335,Items.WATERING_CAN4_5336,Items.WATERING_CAN5_5337,Items.WATERING_CAN6_5338,Items.WATERING_CAN7_5339,Items.WATERING_CAN8_5340 -> {
|
||||
val p = patch.getPatchFor(player)
|
||||
val t = p.patch.type
|
||||
if (p.isWatered || p.isEmptyAndWeeded() || p.isGrown() || p.plantable == Plantable.SCARECROW) {
|
||||
sendMessage(player, "This patch doesn't need watering.")
|
||||
} else if (t == PatchType.ALLOTMENT || t == PatchType.FLOWER_PATCH || t == PatchType.HOPS_PATCH) {
|
||||
if (t == PatchType.ALLOTMENT || t == PatchType.FLOWER_PATCH || t == PatchType.HOPS_PATCH) {
|
||||
submitIndividualPulse(player, object : Pulse() {
|
||||
override fun pulse(): Boolean {
|
||||
if (p.isWeedy()) {
|
||||
if (p.isWeedy() || p.isEmptyAndWeeded()) {
|
||||
sendMessage(player, "You should grow something first.")
|
||||
return true
|
||||
}
|
||||
if (p.isWatered || p.isGrown() || p.plantable == Plantable.SCARECROW) {
|
||||
sendMessage(player, "This patch doesn't need watering.")
|
||||
return true
|
||||
}
|
||||
if (p.isDiseased || p.isDead) {
|
||||
sendMessage(player, "Water isn't going to cure that!")
|
||||
return true
|
||||
}
|
||||
if (usedItem.id == Items.WATERING_CAN_5331) {
|
||||
sendMessage(player, "You need to fill the watering can first.")
|
||||
return true
|
||||
|
|
@ -178,6 +186,8 @@ class UseWithPatchHandler : InteractionListener {
|
|||
return true
|
||||
}
|
||||
})
|
||||
} else {
|
||||
sendMessage(player, "This patch doesn't need watering.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,9 +222,9 @@ class UseWithPatchHandler : InteractionListener {
|
|||
val plantable = Plantable.forItemID(usedItem.id) ?: return@onUseWith false
|
||||
|
||||
if (plantable.applicablePatch != patch.type) {
|
||||
val seedNamePlural = StringUtils.plusS(plantable.name.replace("_", " ").lowercase())
|
||||
val plantableNamePlural = StringUtils.plusS(plantable.displayName)
|
||||
val patchType = if (plantable.applicablePatch == PatchType.ALLOTMENT) "a vegetable patch" else prependArticle(plantable.applicablePatch.displayName())
|
||||
sendMessage(player, "You can only plant $seedNamePlural in $patchType.")
|
||||
sendMessage(player, "You can only plant $plantableNamePlural in $patchType.")
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
|
|
@ -232,37 +242,40 @@ class UseWithPatchHandler : InteractionListener {
|
|||
return@onUseWith true
|
||||
}
|
||||
|
||||
val plantItem =
|
||||
if (patch.type == PatchType.ALLOTMENT) Item(plantable.itemID,3) else if (patch.type == PatchType.HOPS_PATCH) {
|
||||
if (plantable == Plantable.JUTE_SEED) Item(plantable.itemID,3) else Item(plantable.itemID,4)
|
||||
} else {
|
||||
Item(plantable.itemID,1)
|
||||
val plantItem = when (patch.type) {
|
||||
PatchType.ALLOTMENT -> Item(plantable.itemID, 3)
|
||||
PatchType.HOPS_PATCH -> if (plantable == Plantable.JUTE_SEED) Item(plantable.itemID, 3) else Item(plantable.itemID, 4)
|
||||
else -> Item(plantable.itemID,1)
|
||||
}
|
||||
|
||||
if (patch.type == PatchType.ALLOTMENT) {
|
||||
if (!player.inventory.containsItem(plantItem)) {
|
||||
sendMessage(player, "You need 3 seeds to plant an allotment patch.")
|
||||
val seedPlural = if (plantItem.amount == 1) "seed" else "seeds"
|
||||
sendMessage(player, "You need ${plantItem.amount} $seedPlural to plant ${prependArticle(patch.type.displayName())}.")
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
val requiredItem = when (patch.type) {
|
||||
PatchType.TREE_PATCH, PatchType.FRUIT_TREE_PATCH -> Items.SPADE_952
|
||||
PatchType.FLOWER_PATCH -> if (plantable == Plantable.SCARECROW) null else Items.SEED_DIBBER_5343
|
||||
else -> Items.SEED_DIBBER_5343
|
||||
}
|
||||
if (patch.type != PatchType.FRUIT_TREE_PATCH && patch.type != PatchType.TREE_PATCH) {
|
||||
if (!inInventory(player, Items.SEED_DIBBER_5343)) {
|
||||
sendMessage(player, "You need a seed dibber to plant that.")
|
||||
if (requiredItem != null && !inInventory(player, requiredItem)) {
|
||||
sendMessage(player, "You need ${prependArticle(requiredItem.asItem().name.lowercase())} to plant that.")
|
||||
return@onUseWith true
|
||||
}
|
||||
} else {
|
||||
if (!inInventory(player, Items.SPADE_952) && plantable != Plantable.SCARECROW) {
|
||||
sendMessage(player, "You need a spade to plant that.")
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
player.lock()
|
||||
if (removeItem(player, plantItem)) {
|
||||
if (plantable != Plantable.SCARECROW) {
|
||||
animate(player, 2291)
|
||||
when (requiredItem) {
|
||||
Items.SPADE_952 -> {
|
||||
animate(player, spadeDigAnim)
|
||||
playAudio(player, Sounds.DIGSPADE_1470)
|
||||
}
|
||||
Items.SEED_DIBBER_5343 -> {
|
||||
animate(player, seedDibberAnim)
|
||||
playAudio(player, Sounds.FARMING_DIBBING_2432)
|
||||
}
|
||||
val delay = if (plantable == Plantable.SCARECROW) 0 else 3
|
||||
}
|
||||
val delay = if (patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || plantable == Plantable.SCARECROW) 0 else 3
|
||||
submitIndividualPulse(player, object : Pulse(delay) {
|
||||
override fun pulse(): Boolean {
|
||||
if (plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 0, 7)) {
|
||||
|
|
@ -275,8 +288,11 @@ class UseWithPatchHandler : InteractionListener {
|
|||
addItem(player, Items.PLANT_POT_5350)
|
||||
}
|
||||
|
||||
val itemAmount = if (plantItem.amount == 1) "a" else plantItem.amount
|
||||
val itemName = if (plantItem.amount == 1) getItemName(plantItem.id).lowercase() else StringUtils.plusS(getItemName(plantItem.id).lowercase())
|
||||
val itemAmount =
|
||||
if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) "the"
|
||||
else if (plantItem.amount == 1) "a"
|
||||
else plantItem.amount
|
||||
val itemName = if (plantItem.amount == 1) plantable.displayName else StringUtils.plusS(plantable.displayName)
|
||||
val patchName = p.patch.type.displayName()
|
||||
if (plantable == Plantable.SCARECROW) {
|
||||
sendMessage(player, "You place the scarecrow in the $patchName.")
|
||||
|
|
|
|||
|
|
@ -58,12 +58,18 @@ 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.plantable != null && !patch.isDead){
|
||||
var stagesToSimulate = if (!patch.isGrown()) patch.plantable!!.stages - patch.currentGrowthStage else 0
|
||||
if (shouldPlayCatchup && !patch.isDead) {
|
||||
var stagesToSimulate = if (!patch.isGrown()) {
|
||||
if (patch.isWeedy() || patch.isEmptyAndWeeded()) patch.currentGrowthStage % 4
|
||||
else patch.plantable!!.stages - patch.currentGrowthStage
|
||||
} else 0
|
||||
|
||||
if (patch.plantable != null) {
|
||||
if (type == PatchType.BUSH_PATCH)
|
||||
stagesToSimulate += Math.min(4, 4 - patch.getFruitOrBerryCount())
|
||||
if (type == PatchType.FRUIT_TREE_PATCH)
|
||||
stagesToSimulate += Math.min(6, 6 - patch.getFruitOrBerryCount())
|
||||
}
|
||||
|
||||
val nowTime = System.currentTimeMillis()
|
||||
var simulatedTime = patch.nextGrowth
|
||||
|
|
@ -77,8 +83,8 @@ class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) {
|
|||
}
|
||||
}
|
||||
|
||||
fun getPatch(patch: FarmingPatch): Patch {
|
||||
return patchMap[patch] ?: (Patch(player,patch).also { patchMap[patch] = it })
|
||||
fun getPatch(patch: FarmingPatch, addPatch: Boolean ): Patch {
|
||||
return patchMap[patch] ?: (Patch(player,patch).also { if (addPatch) patchMap[patch] = it })
|
||||
}
|
||||
|
||||
fun getPatches(): MutableCollection<Patch>{
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ public class WoodcuttingSkillPulse extends Pulse {
|
|||
if (resource.isFarming()) {
|
||||
FarmingPatch fPatch = FarmingPatch.forObject(node.asScenery());
|
||||
if(fPatch != null) {
|
||||
Patch patch = fPatch.getPatchFor(player);
|
||||
Patch patch = fPatch.getPatchFor(player, true);
|
||||
patch.setCurrentState(patch.getCurrentState() + 1);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -320,30 +320,38 @@ class LunarListeners : SpellListener("lunar"), Commands {
|
|||
}
|
||||
|
||||
// Level 66
|
||||
fun curePlant(player: Player, obj: Scenery){
|
||||
fun curePlant(player: Player, obj: Scenery) {
|
||||
if (CompostBins.forObject(obj) != null) {
|
||||
sendMessage(player, "Bins don't often get diseased.")
|
||||
return
|
||||
}
|
||||
val fPatch = FarmingPatch.forObject(obj)
|
||||
if(fPatch == null){
|
||||
sendMessage(player, "You attempt to cast Cure Plant on ${obj.definition.name}!")
|
||||
sendMessage(player, "Nothing interesting happens.")
|
||||
if (fPatch == null) {
|
||||
sendMessage(player, "Umm... this spell won't cure that!")
|
||||
return
|
||||
}
|
||||
val patch = fPatch.getPatchFor(player)
|
||||
if(!patch.isDiseased && !patch.isWeedy() && !patch.isEmptyAndWeeded()){
|
||||
sendMessage(player, "It is growing just fine.")
|
||||
return
|
||||
}
|
||||
if(patch.isWeedy()){
|
||||
if (patch.isWeedy()) {
|
||||
sendMessage(player, "The weeds are healthy enough already.")
|
||||
return
|
||||
}
|
||||
if(patch.isDead){
|
||||
sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.")
|
||||
if (patch.isEmptyAndWeeded()) {
|
||||
sendMessage(player, "There's nothing there to cure.")
|
||||
return
|
||||
}
|
||||
if(patch.isGrown()){
|
||||
if (patch.isGrown()) {
|
||||
sendMessage(player, "That's not diseased.")
|
||||
return
|
||||
}
|
||||
if (patch.isDead) {
|
||||
sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.")
|
||||
return
|
||||
}
|
||||
if (!patch.isDiseased) {
|
||||
sendMessage(player, "It is growing just fine.")
|
||||
return
|
||||
}
|
||||
|
||||
patch.cureDisease()
|
||||
removeRunes(player)
|
||||
addXP(player,60.0)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class HydraNPC extends Familiar {
|
|||
Scenery scenery = (Scenery)node;
|
||||
FarmingPatch farmingPatch = FarmingPatch.forObject(scenery);
|
||||
if(farmingPatch != null) {
|
||||
Patch patch = farmingPatch.getPatchFor(owner);
|
||||
Patch patch = farmingPatch.getPatchFor(owner, true);
|
||||
patch.regrowIfTreeStump();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,8 +108,8 @@ abstract class DialogueFile {
|
|||
interpreter!!.sendDialogues(entity, expression, *messages)
|
||||
}
|
||||
|
||||
open fun options(vararg options: String?) {
|
||||
interpreter!!.sendOptions("Select an Option", *options)
|
||||
open fun options(vararg options: String?, title: String = "Select an Option") {
|
||||
interpreter!!.sendOptions(title, *options)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -151,7 +151,7 @@ abstract class DialogueFile {
|
|||
player?.dialogueInterpreter?.sendDialogue(*messages)
|
||||
}
|
||||
|
||||
fun showTopics(vararg topics: Topic<*>): Boolean {
|
||||
fun showTopics(vararg topics: Topic<*>, title: String = "Select an Option"): Boolean {
|
||||
val validTopics = ArrayList<String>()
|
||||
topics.filter { if(it is IfTopic) it.showCondition else true }.forEach {
|
||||
topic -> interpreter!!.activeTopics.add(topic)
|
||||
|
|
@ -172,7 +172,7 @@ abstract class DialogueFile {
|
|||
interpreter!!.activeTopics.clear()
|
||||
return false
|
||||
}
|
||||
else { options(*validTopics.toTypedArray())
|
||||
else { options(*validTopics.toTypedArray(), title = title)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -532,6 +532,24 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
|
|||
}
|
||||
|
||||
define("finishbins", Privilege.ADMIN, "", "Finishes any in-progress compost bins."){ player, _ ->
|
||||
val bins = getOrStartTimer<Compost>(player).getBins()
|
||||
for (bin in bins) {
|
||||
if (!bin.isFinished && bin.isClosed) bin.finish()
|
||||
}
|
||||
}
|
||||
|
||||
define("resetbins", Privilege.ADMIN, "", "Resets the player's compost bins to their initial states."){ player, _ ->
|
||||
val bins = getOrStartTimer<Compost>(player).getBins()
|
||||
for (bin in bins) bin.reset()
|
||||
}
|
||||
|
||||
define("diseasecrops", Privilege.ADMIN, "", "Disease all crops"){ player, _ ->
|
||||
val state = getOrStartTimer<CropGrowth>(player)
|
||||
for (patch in state.getPatches()){
|
||||
patch.diseaseMod = -128
|
||||
patch.nextGrowth = System.currentTimeMillis() + 1
|
||||
}
|
||||
state.run(player)
|
||||
}
|
||||
|
||||
define("addcredits", Privilege.ADMIN){ player, _ ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue