Jump to content
Sign in to follow this  
kizz

[Matrix] Farming Improvements

Recommended Posts

Greetings!

For the last week or two, in my free time, I have been developing my servers farming based off of a few tutorials I have found.

[B][U][COLOR="#FF8C00"][URL="http://www.rune-server.org/runescape-development/rs-503-client-server/snippets/559347-718-farming.html"]This tutorial[/URL] is the original code I used. If you wish to use my code, you will need to follow this tutorial first in order to use my code.[/COLOR][/U][/B]

[URL="http://www.rune-server.org/runescape-development/rs-503-client-server/snippets/492567-718-farming-release.html"]This tutorial [/URL]has helped me to finish off the various config ID's for herbs, flowers and allotments.

I have vastly improved and fixed hundreds of issues with my farming code, and hope to share so that others can use my code and improve it.

I am by no means a master of convention but I am learning quickly.


[COLOR="#FF0000"][B][U]Again, the original code here was not my creation!
[/U][/B][/COLOR]

My farming consists of 3 main files:

FarmingSystem.java

[CODE]package com.rs.game.player.content.farming;

import java.util.Iterator;

import com.rs.game.Animation;
import com.rs.game.WorldObject;
import com.rs.game.item.Item;
import com.rs.game.player.Player;
import com.rs.game.player.Inventory;
import com.rs.game.player.Skills;
import com.rs.game.player.content.farming.Seeds.Seed;
import com.rs.game.player.content.farming.Seeds;
import com.rs.game.tasks.WorldTask;
import com.rs.game.tasks.WorldTasksManager;

public class FarmingSystem {

/**
* @author Jake | Santa Hat [MENTION=77]Rune[/MENTION]-Server
*/


/**
* A list of all the Farming Allotments / Patches
*/
public static int[] farmingPatches = { 8552, 8553, 7848, 8151, 8550, 8551, 7847, 8150, 8554, 8555, 7849, 8152 };

/**
* Handles the seeds on patch
*/
public static void handleSeeds(Player player, int seedId, WorldObject object) {
if ((!canPlantSeeds(player, object) && (seedId == 952)) || (canPlantSeeds(player, object) && (seedId == 952))) {
for (PatchStatus patch : player.farmingPatch) {
if (patch.getObjectId() == object.getId()) {
player.setNextAnimation(new Animation(2273));
player.getPackets().sendConfigByFile(object.getDefinitions().configFileId, 0);
player.farmingPatch.remove(patch);
}
}
player.getPackets().sendGameMessage("You remove the growing plants with your shovel.");
return;
}
if (!canPlantSeeds(player, object)) {
player.getPackets().sendGameMessage("You must clear the weeds before you may plant some seeds here.");
return;
}
for (PatchStatus patch : player.farmingPatch) {
if ((patch.getObjectId() == object.getId()) && (seedId != 952)) {
player.getPackets().sendGameMessage("There is already something growing here.");
return;
}
}
for (Seeds.Seed seed : Seeds.Seed.values()) {
if (seedId == seed.getItem().getId()) {
if (player.getSkills().getLevel(Skills.FARMING) < seed.getLevel()) {
player.getPackets().sendGameMessage("You need at least "+seed.getLevel()+" Farming in order to plant this.");
return;
}
if (!player.getInventory().containsItem(seed.getItem().getId(), seed.getItem().getAmount())) {
player.getPackets().sendGameMessage("You need at least "+seed.getItem().getAmount()+" "+new Item(seedId, 1).getDefinitions().getName()+"'s.");
return;
}
for (int i = 0; i < seed.getSuitablePatch().length; i++) {
if (seed.getSuitablePatch()[i] == object.getId()) {
player.getPackets().sendGameMessage("You plant some "+new Item(seedId, 1).getDefinitions().getName()+"'s.");
player.getInventory().deleteItem(seed.getItem());
player.setNextAnimation(new Animation(2291));
player.farmingPatch.add(new PatchStatus(object.getId(), object.getDefinitions().configFileId, seed.getConfigValues()[0], seed.getConfigValues()[seed.getConfigValues().length-1], "Some "+new Item(seedId, 1).getDefinitions().getName()+"'s have been planted here.", seed.getTime()));
startGrowth(player, object, seed.getTime() / 2);
}
}
}
}
}

/**
* Is the Patch Raked? Can the Player plant seeds?
*/
private static boolean canPlantSeeds(Player player, WorldObject object) {
for (WorldObject o : player.rakedPatch) {
if (object.getId() == o.getId())
return true;
}
return false;
}


/**
* Starts the growth
* 5 Stages of Growth
*/
private static void startGrowth(final Player player, final WorldObject object, int time) {
WorldTasksManager.schedule(new WorldTask() {
[MENTION=15855]Over[/MENTION]ride
public void run() {
if (player.farmingPatch.size() == 0) { stop();
return;
}
PatchStatus status = null;
for (PatchStatus patch : player.farmingPatch) {
if (patch.getConfigId() == object.getDefinitions().configFileId) {
status = patch;
}
}
if (status == null) { stop();
return;
}
if ((status.getConfigValue() + 1) == status.getMaxConfigValue()) {
player.getPackets().sendConfigByFile(status.getConfigId(), status.getMaxConfigValue());
player.getPackets().sendGameMessage("<col=ff0000>[Farming] Your crops have fully grown.");
stop();
} else {
player.farmingPatch.add(new PatchStatus(object.getId(), object.getDefinitions().configFileId, status.getConfigValue() + 1, status.getMaxConfigValue(), status.getInspectText(),status.getPatchTime()));
player.farmingPatch.remove(status);
player.getPackets().sendConfigByFile(status.getConfigId(), status.getConfigValue() + 1);
}
}
}, 0, time);
}


/**
* Should the Player Rake or Harvest?
*/
public static void executeAction(Player player, WorldObject object) {
if (canHarvest(player, object))
harvestCrops(player, object);
else
rake(player, object);
}

/**
* Harvest's The Crops
*/
private static void harvestCrops(Player player, WorldObject object) {
if (canHarvest(player, object) && (player.getInventory().getFreeSlots() >= 4)) {

sendItems(player, object);
for (Iterator<PatchStatus> patches = player.farmingPatch.iterator(); patches.hasNext();) {
PatchStatus patch = patches.next();
if (patch.getConfigId() == object.getDefinitions().configFileId)
patches.remove(); //Removes the Crops
}
for (Iterator<WorldObject> rakedPatches = player.rakedPatch.iterator(); rakedPatches.hasNext();) {
WorldObject rakedPatch = rakedPatches.next();
if (rakedPatch.getId() == object.getId())
rakedPatches.remove(); //Removes the Raked Patch
}
} else if (canHarvest(player, object) && (player.getInventory().getFreeSlots() < 4)) {
player.getPackets().sendGameMessage("You need more inventory space!");
}
}

/**
* Sends the Farming crops to the Players Inventory
*/
private static boolean harvestGood = false;
private static boolean harvesting = false;

private static void sendItems(Player player, WorldObject object) {
for (PatchStatus patch : player.farmingPatch) {
if (patch.getObjectId() == object.getId()) {
for (Seeds.Seed seed : Seed.values()) {
for (int i = 0; i < seed.getSuitablePatch().length; i++) {
if (seed.getSuitablePatch()[i] == object.getId()) {
if ((seed.getConfigValues()[seed.getConfigValues().length-1] == patch.getMaxConfigValue()) && (patch.getObjectId() == object.getId())) {
player.lock();
player.getSkills().addXp(Skills.FARMING, seed.getSeedExp());
player.setNextAnimation(new Animation(2286));
player.getInventory().addItem(seed.getProduce());
player.getPackets().sendGameMessage("You harvest the "+new Item(seed.getProduce().getId(), 1).getDefinitions().getName()+"'s.");
clearPatch(player, object);
player.farmingPatch.remove(patch);
player.unlock();
return;
}
}
}
}
}
}
}

private static void clearPatch(Player player, WorldObject object) {
player.getPackets().sendConfigByFile(object.getDefinitions().configFileId, 0);
}


/**
* Can the Player Harvest?
*/
public static boolean canHarvest(Player player, WorldObject object) {
for (PatchStatus patch : player.farmingPatch) {
if (patch.getConfigId() == object.getDefinitions().configFileId) {
if ((patch.getConfigValue() + 1) == patch.getMaxConfigValue()) {
return true;
}
}
}
return false;
}

/**
* Sends the Configs Upon Login
*/
public static void sendPatchOnLogin(Player player) {
player.rakedPatch.clear();
for (PatchStatus patch : player.farmingPatch) {
int growTime = patch.getPatchTime() / 2;
WorldTasksManager.schedule(new WorldTask() {
[MENTION=15855]Over[/MENTION]ride
public void run() {

if (player.farmingPatch.size() == 0) { stop();
return;
}
//for (PatchStatus patch : player.farmingPatch) {

if ((patch.getConfigValue() + 1) == patch.getMaxConfigValue()) {
player.getPackets().sendConfigByFile(patch.getConfigId(), patch.getMaxConfigValue());
player.getPackets().sendGameMessage("[Farming] Your crops have fully grown.");
stop();
} else {
player.farmingPatch.add(new PatchStatus(patch.getObjectId(), patch.getConfigId(), patch.getConfigValue() + 1, patch.getMaxConfigValue(), patch.getInspectText(),patch.getPatchTime()));
player.getPackets().sendConfigByFile(patch.getConfigId(), patch.getConfigValue() + 1);
player.farmingPatch.remove(patch);

}
//}
}
}, 0, growTime);
//continueGrowth(player);
}
}
/**
* Continues the Growth of the crops when the player logs back in.
*/
// private static int pTime;
/* public static void continueGrowth(final Player player) {
WorldTasksManager.schedule(new WorldTask() {
[MENTION=15855]Over[/MENTION]ride
public void run() {
if (player.farmingPatch.size() == 0) { stop();
return;
}
for (PatchStatus patch : player.farmingPatch) {
pTime = patch.getPatchTime() / 2;
if ((patch.getConfigValue() + 1) == patch.getMaxConfigValue()) {
player.getPackets().sendConfigByFile(patch.getConfigId(), patch.getMaxConfigValue());
player.getPackets().sendGameMessage("[Farming] Your crops have fully grown.");
stop();
} else {
player.farmingPatch.add(new PatchStatus(patch.getObjectId(), patch.getConfigId(), patch.getConfigValue() + 1, patch.getMaxConfigValue(), patch.getInspectText(),patch.getPatchTime()));
player.getPackets().sendConfigByFile(patch.getConfigId(), patch.getConfigValue() + 1);
player.farmingPatch.remove(patch);
}
}
}
}, 0, pTime);
}
*/
/**
* Rakes the patch
*/
private static void rake(final Player player, final WorldObject object) {
if (!player.getInventory().containsItem(5341, 1)) {
player.getPackets().sendGameMessage("You'll need a rake to get rid of the weeds.");
return;
}
if (player.getInventory().getFreeSlots() >= 3) {
WorldTasksManager.schedule(new WorldTask() {
int loop;
int configValue;
[MENTION=15855]Over[/MENTION]ride
public void run() {
player.lock();
if (loop == 0 || loop == 3 || loop == 6) {
configValue++;
player.setNextAnimation(new Animation(2273));
player.getPackets().sendConfigByFile(object.getDefinitions().configFileId, configValue);
player.getInventory().addItem(6055, 1);
player.getSkills().addXp(Skills.FARMING, 25);
player.rakedPatch.add(object);
} else if (loop >= 7) {
player.unlock();
stop();
}

loop++;
}
}, 0, 1);
player.getPackets().sendGameMessage("You successfully clear all the weeds.");
} else if (player.getInventory().getFreeSlots() < 3) {
player.getPackets().sendGameMessage("You need more inventory space to rake here.");
}
}

/**
* Right Click Patch - Inspect Option - Call this in ObjectHandler - Option2
*/
public static void inspectPatch(Player player, WorldObject object) {
if (player.farmingPatch.size() == 0) {
player.getDialogueManager().startDialogue("SimpleMessage", "There is currently nothing growing here.");
return;
}
for (PatchStatus patch : player.farmingPatch) {
if (object.getId() == patch.getObjectId()) {
player.getDialogueManager().startDialogue("SimpleMessage", ""+patch.getInspectText()+" ; Configid: "+patch.getConfigValue());
} else {
player.getDialogueManager().startDialogue("SimpleMessage", "There is currently nothing growing here.");
}
}
}

}[/CODE]


Next, my PatchStatus.java object:

[CODE]package com.rs.game.player.content.farming;

import java.io.Serializable;

public class PatchStatus implements Serializable {

/**
* @author Jake | Santa Hat [MENTION=77]Rune[/MENTION]-Server
*/

private static final long serialVersionUID = 4641462661859309514L;

private int objectId;
private int configId;
private int configValue;
private int maxConfigValue;
private String inspect;
private int patchTime;

public PatchStatus(int objectId, int configId, int configValue, int maxConfigValue, String inspect, int patchTime) {
this.objectId = objectId;
this.configId = configId;
this.configValue = configValue;
this.maxConfigValue = maxConfigValue;
this.inspect = inspect;
this.patchTime = patchTime;
}

public int getObjectId() {
return objectId;
}

public int getConfigId() {
return configId;
}

public int getConfigValue() {
return configValue;
}

public int getMaxConfigValue() {
return maxConfigValue;
}

public String getInspectText() {
return inspect;
}

public int getPatchTime() {
return patchTime;
}
}[/CODE]

And finally, my Seeds.java:

[CODE]package com.rs.game.player.content.farming;

import com.rs.game.item.Item;

public class Seeds {

/**
* @author Jake | Santa Hat [MENTION=77]Rune[/MENTION]-Server
*/

public enum Seed {

/**
* Allotments
*/
POTATO(new Item(5318, 4), new int[] { 6, 7, 8, 9, 10 }, 1, new Item(1942, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 300, 25),
ONION(new Item(5319, 4), new int[] { 13, 14, 15, 16, 17 }, 5, new Item(1957, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 330, 55),
CABBAGE(new Item(5324, 4), new int[] { 20, 21, 22, 23, 24 }, 7, new Item(1965, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 360, 85),
TOMATO(new Item(5322, 4), new int[] { 27, 28, 29, 30, 31 }, 12, new Item(1982, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 420, 110),
SWEETCORN(new Item(5320, 4), new int[] { 34, 35, 37, 39, 40 }, 20, new Item(5986, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 480, 200),
STRAWBERRY(new Item(5323, 4), new int[] { 43, 45, 46, 48, 49 }, 31, new Item(5504, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 540, 301),
WATERMELON(new Item(5321, 4), new int[] { 52, 53, 55, 59, 60 }, 47, new Item(5982, 4), new int[] { 8553, 8552, 8550, 8551, 8554, 8555 }, 600, 550),


/**
* Flower Patches
*/
MARIGOLD(new Item(5096, 1), new int[] { 8, 9, 10, 11, 12 }, 2, new Item(6010, 1), new int[] { 7848, 7847, 7849 }, 310, 30),
ROSEMARY(new Item(5097, 1), new int[] { 13, 14, 15, 16, 17 }, 11, new Item(6014, 1), new int[] { 7848, 7847, 7849 }, 400, 45),
NASTURTIUM(new Item(5098, 1), new int[] { 18, 19, 20, 21, 22 }, 24, new Item(6012, 1), new int[] { 7848, 7847, 7849 }, 480, 110),
WOAD(new Item(5099, 1), new int[] { 23, 24, 25, 26, 27 }, 25, new Item(1793, 1), new int[] { 7848, 7847, 7849 }, 490, 120),
LIMPWURT(new Item(5100, 1), new int[] { 28, 29, 30, 31, 32 }, 26, new Item(225, 1), new int[] { 7848, 7847, 7849 }, 500, 130),
LILY(new Item(14589, 1), new int[] { 37, 38, 39, 40, 41 }, 52, new Item(14583, 1), new int[] { 7848, 7847, 7849 }, 700, 450),

/**
* Herb Patches
*/
GUAM(new Item(5291, 1), new int[] { 4, 5, 6, 7, 8 }, 9, new Item(199, 4), new int[] { 8151, 8150, 8152 }, 360, 50),
MARRENTILL(new Item(5292, 1), new int[] { 11, 12, 13, 14, 15 }, 14, new Item(201, 4), new int[] { 8151, 8150, 8152 }, 420, 80),
TARROMIN(new Item(5293, 1), new int[] { 18, 19, 20, 21, 22 }, 19, new Item(203, 4), new int[] { 8151, 8150, 8152 }, 480, 110),
HARRALANDER(new Item(5294, 1), new int[] { 25, 26, 27, 28, 29 }, 26, new Item(205, 4), new int[] { 8151, 8150, 8152 }, 540, 150),
RANARR(new Item(5295, 1), new int[] { 32, 33, 34, 35, 36 }, 32, new Item(207, 4), new int[] { 8151, 8150, 8152 }, 600, 190),
TOADFLAX(new Item(5296, 1), new int[] { 39, 40, 41, 42, 43 }, 38, new Item(3049, 4), new int[] { 8151, 8150, 8152 }, 660, 225),
IRIT(new Item(5297, 1), new int[] { 46, 47, 48, 49, 50 }, 44, new Item(209, 4), new int[] { 8151, 8150, 8152 }, 720, 270),
AVANTOE(new Item(5298, 1), new int[] { 53, 54, 55, 56, 57 }, 50, new Item(211, 4), new int[] { 8151, 8150, 8152 }, 780, 300),
WERGALI(new Item(14870, 1), new int[] { 60, 61, 62, 63, 64 }, 46, new Item(14836, 4), new int[] { 8151, 8150, 8152 }, 750, 285),
KWUARM(new Item(5299, 1), new int[] { 69, 70, 71, 72, 73 }, 56, new Item(213, 4), new int[] { 8151, 8150, 8152 }, 820, 325),
SNAPDRAGON(new Item(5300, 1), new int[] { 75, 76, 77, 78, 79 }, 62, new Item(3051, 4), new int[] { 8151, 8150, 8152 }, 880, 360),
CADANTINE(new Item(5301, 1), new int[] { 82, 83, 84, 85, 86 }, 67, new Item(215, 4), new int[] { 8151, 8150, 8152 }, 920, 390),
LANTADYME(new Item(5302, 1), new int[] { 89, 90, 91, 92, 93 }, 73, new Item(2485, 4), new int[] { 8151, 8150, 8152 }, 980, 420),
DWARF_WEED(new Item(5303, 1), new int[] { 96, 97, 98, 99, 100 }, 79, new Item(217, 4), new int[] { 8151, 8150, 8152 }, 1020, 480),
TORSTOL(new Item(5304, 1), new int[] { 103, 104, 105, 106, 107 }, 85, new Item(219, 4), new int[] { 8151, 8150, 8152 }, 1080, 520),
FELLSTALK(new Item(21621, 1), new int[] { 106, 107, 108, 109, 110 }, 91, new Item(21626, 4), new int[] { 8151, 8150, 8152 }, 1120, 670);

private Item item;
private int[] configValues;
private int level;
private Item produce;
private int[] suitablePatches;
private int time; //Time to grow (In Seconds)
private int exp;

Seed(Item item, int[] configValues, int level, Item produce, int[] suitablePatches, int time, int exp) {
this.item = item;
this.configValues = configValues;
this.level = level;
this.produce = produce;
this.suitablePatches = suitablePatches;
this.time = time;
this.exp = exp;
}

public Item getItem() {
return item;
}

public int[] getConfigValues() {
return configValues;
}

public int getLevel() {
return level;
}

public int getSeedExp() {
return exp;
}

public Item getProduce() {
return produce;
}

public int[] getSuitablePatch() {
return suitablePatches;
}

public int getTime() {
return time;
}
}

}[/CODE]

These 3 files contain the majority of my farming system.

As well, if you follow the tutorial for the original code, then update to mine, you should have a very functional farming system.

I also added if statements to my Objecthandler.java to prevent the "Nothing interesting happens" message when interacting with the patches.

You will have to add one statement in the HandleOption1 method, and one in the ItemonObject method.

Features:
-Fully supported Allotments
-All Flowers
-All Herbs
-Raking
-Planting, growth, harvesting
-Proper rewards
-Experience rates and growth times are set high, these can be easily changed in Seeds.java
-Logout/Server restart does not hinder growth
-Shovel will clear growing/grown/bugged plants
-Player animations should be set to prevent glitched positioning
-Improved indexing and the harvesting to prevent concurrentmodification exceptions, as well as Invalid array exceptions
-Expanded the PatchStatus object to include growth time and help improve the farming experience

As well, since this is still in development, I have left my commented out code in the classes. This may be clutter but it may provide useful when debugging, so I have left it for other users. Edited by kizz

Share this post


Link to post
Share on other sites
Nice contribution, won't use as I have my own 100% working farm but this will be great for those who don't have or can't make themselves. :gg:

Share this post


Link to post
Share on other sites
Thanks :) Has been very helpful in teaching me the more advanced aspects of iteration and object oriented languages. So used to C and lightweight stuff like Lua and PHP that I never have really had the opportunity to push myself with an OOP like Java. It has been beneficial both in learning and work where I use a lot of ladder logic.

Share this post


Link to post
Share on other sites
[quote name='kizz']Thanks :) Has been very helpful in teaching me the more advanced aspects of iteration and object oriented languages. So used to C and lightweight stuff like Lua and PHP that I never have really had the opportunity to push myself with an OOP like Java. It has been beneficial both in learning and work where I use a lot of ladder logic.[/QUOTE]

That's good man and glad someone else is actually helping releasing full snippets instead of half of it lol. This is a real snippet. You make me want to release cosmetics lol.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×