/**
* Copyright (C) 2011 Jacob Scott <jascottytechie@gmail.com> Description:
* provides methods for farming, using resources from a chest
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.jascotty2.chestharvester;
import java.util.HashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.inventory.ItemStack;
import me.jascotty2.libv01.bukkit.inventory.ChestManip;
import me.jascotty2.libv01.bukkit.inventory.ItemStackManip;
import me.jascotty2.libv01.util.Rand;
public class AutoHarvester implements Listener {
ChestHarvester plugin = null;
static final HashMap<Location, Long> farmTimes = new HashMap<Location, Long>();
static final HashMap<Location, Integer> redstoneAmount = new HashMap<Location, Integer>();
// where to look for chests relative to the redstone wire
static final BlockFace dirs[] = new BlockFace[]{
BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.UP};
enum DIRECTION {
NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST
}
public AutoHarvester(ChestHarvester plugin) {
this.plugin = plugin;
} // end default constructor
public void autoFarm(Chest chestBlock) {
Block bl = chestBlock.getBlock();
if (!farmTimes.containsKey(bl.getLocation())
|| System.currentTimeMillis() - farmTimes.get(bl.getLocation()) > plugin.config.chestScanInterval) {
farmTimes.put(bl.getLocation(), System.currentTimeMillis());
int x = bl.getLocation().getBlockX();
int y = bl.getLocation().getBlockY();
int z = bl.getLocation().getBlockZ();
//do {
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
}
}
}
//} while (ChestManip.containsItem(chestBlock, Material.INK_SACK, (short) 15));
}
}
public void autoFarm(Player player, Chest chestBlock) {
Block bl = chestBlock.getBlock();
if (!farmTimes.containsKey(bl.getLocation())
|| System.currentTimeMillis() - farmTimes.get(bl.getLocation()) > plugin.config.chestScanInterval) {
farmTimes.put(bl.getLocation(), System.currentTimeMillis());
// if (!canFarm(chestBlock)) {
// return;
// }
int x = bl.getLocation().getBlockX();
int y = bl.getLocation().getBlockY();
int z = bl.getLocation().getBlockZ();
// get the direction the player is facing
double rot = (player.getLocation().getYaw() - 90) % 360;
if (rot < 0) {
rot += 360;
}
DIRECTION harvestDir = DIRECTION.NORTH;
if (plugin.config.harvestCorners) {
if ((0 <= rot && rot < 22.5) || (337.5 <= rot && rot < 360.0)) { // North
harvestDir = DIRECTION.NORTH;
} else if (67.5 <= rot && rot < 112.5) { //East
harvestDir = DIRECTION.EAST;
} else if (157.5 <= rot && rot < 202.5) { //South
harvestDir = DIRECTION.SOUTH;
} else if (247.5 <= rot && rot < 292.5) { //West
harvestDir = DIRECTION.WEST;
} else if (22.5 <= rot && rot < 67.5) { //Northeast
harvestDir = DIRECTION.NORTHEAST;
} else if (112.5 <= rot && rot < 157.5) { //Southeast
harvestDir = DIRECTION.SOUTHEAST;
} else if (202.5 <= rot && rot < 247.5) { //Southwest
harvestDir = DIRECTION.SOUTHWEST;
} else if (292.5 <= rot && rot < 337.5) {//Northwest
harvestDir = DIRECTION.NORTHWEST;
}
} else {
if ((0 <= rot && rot < 45) || (315 <= rot && rot < 360.0)) { // North
harvestDir = DIRECTION.NORTH;
} else if (45 <= rot && rot < 135) { //East
harvestDir = DIRECTION.EAST;
} else if (135 <= rot && rot < 225) { //South
harvestDir = DIRECTION.SOUTH;
} else if (225 <= rot && rot < 315) { //West
harvestDir = DIRECTION.WEST;
}
}
// do {
if (harvestDir == DIRECTION.NORTH) { // North: ++x
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.EAST) { //East: --z
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.SOUTH) { //South: --x
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.WEST) { //West: ++z
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.NORTHEAST) { //Northeast
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
if (dx >= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
}
if (dx <= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
}
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.SOUTHEAST) { //Southeast
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
if (dx >= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
}
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
if (dx <= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
}
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.SOUTHWEST) { //Southwest
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
if (dx <= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
}
if (dx >= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
}
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
} else if (harvestDir == DIRECTION.NORTHWEST) { //Northwest
for (int dx = 0; dx <= plugin.config.autoFarmRange; ++dx) {
for (int dz = 0; dz <= plugin.config.autoFarmRange; ++dz) {
for (int dy = plugin.config.autoFarmHeight; dy >= -plugin.config.autoFarmHeight; --dy) {
if (dx <= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z + dz));
}
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z + dz));
//farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x + dx, y + dy, z - dz));
if (dx >= dz) {
farmBlock(chestBlock, chestBlock.getWorld().getBlockAt(x - dx, y + dy, z - dz));
}
// if (!canFarm(chestBlock)) {
// return;
// }
}
}
}
}
//} while (ChestManip.containsItem(chestBlock, Material.INK_SACK, (short) 15));
}
}
// boolean canFarm(Chest source) {
// return !(ChestManip.is_full(source, Material.WHEAT) || ChestManip.is_full(source, Material.SEEDS));
// }
void farmBlock(Chest source, Block toFarm) {
int id = toFarm.getTypeId();
if (id == Material.CROPS.getId()) {
if (plugin.config.harvestWheat) {
if (plugin.config.useBonemeal && toFarm.getData() != 0x7
&& ChestManip.containsItem(source, Material.INK_SACK, (short) 15)) {
toFarm.setData((byte) 7);
ChestManip.removeItem(source, Material.INK_SACK, (short) 15);
}
if (toFarm.getData() == 0x7 //fully grown
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.WHEAT, plugin.config.autoStack)
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.SEEDS, plugin.config.autoStack)) {
int w = Rand.RandomInt(1, 2);
int s = Rand.RandomInt(1, 3);
ChestManip.addContents(source, new ItemStack(Material.WHEAT, w));
if (s > 0) {
ChestManip.addContents(source, new ItemStack(Material.SEEDS, s));
}
toFarm.setTypeId(0);
// now replant
if (plugin.config.replant && ChestManip.containsItem(source, Material.SEEDS)) {
toFarm.setTypeId(Material.CROPS.getId());
ChestManip.removeItem(source, Material.SEEDS);
}
}
}
} else if (plugin.config.replant && plugin.config.autotill && plugin.config.harvestWheat
&& (id == 2 || id == 3 || id == 60)
&& toFarm.getRelative(BlockFace.UP).getTypeId() == 0
&& ChestManip.containsItem(source, Material.SEEDS)) {
if (id != 60 && plugin.config.useHoe) {
// search for a hoe
ItemStack[] chest = ChestManip.getContents(source);
int hoe = -1;
for (int i = 0; i < chest.length; ++i) {
if (chest[i] != null && (chest[i].getTypeId() >= 290 && chest[i].getTypeId() <= 294)) {
hoe = i;
break;
}
}
if (hoe >= 0) {
chest[hoe].setDurability((short) (chest[hoe].getDurability() + 1));
if (Material.getMaterial(chest[hoe].getTypeId()).getMaxDurability() <= chest[hoe].getDurability()) {
chest[hoe] = null;
ChestManip.setContents(source, chest);
}
} else {
return;
}
}
toFarm.setTypeId(60);
toFarm.getRelative(BlockFace.UP).setTypeId(Material.CROPS.getId());
ChestManip.removeItem(source, Material.SEEDS);
} else if (id == Material.SUGAR_CANE_BLOCK.getId()) {
if (plugin.config.harvestReeds
&& toFarm.getRelative(BlockFace.DOWN).getTypeId() == Material.SUGAR_CANE_BLOCK.getId()
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.SUGAR_CANE, plugin.config.autoStack)) {
ChestManip.addContents(source, new ItemStack(Material.SUGAR_CANE, 1));
toFarm.setTypeIdAndData(0, (byte) 0, false);//toFarm.setTypeId(0);
while (toFarm.getRelative(BlockFace.UP).getTypeId() == Material.SUGAR_CANE_BLOCK.getId()) {
toFarm = toFarm.getRelative(BlockFace.UP);
ChestManip.addContents(source, new ItemStack(Material.SUGAR_CANE, 1));
toFarm.setTypeIdAndData(0, (byte) 0, false);
}
}
} else if (id == Material.CACTUS.getId()) {
if (plugin.config.harvestCactus
&& toFarm.getRelative(BlockFace.DOWN).getTypeId() == Material.CACTUS.getId()
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.CACTUS, plugin.config.autoStack)) {
ChestManip.addContents(source, new ItemStack(Material.CACTUS, 1));
toFarm.setTypeIdAndData(0, (byte) 0, false);//toFarm.setTypeId(0);
while (toFarm.getRelative(BlockFace.UP).getTypeId() == Material.CACTUS.getId()) {
toFarm = toFarm.getRelative(BlockFace.UP);
ChestManip.addContents(source, new ItemStack(Material.CACTUS, 1));
toFarm.setTypeIdAndData(0, (byte) 0, false);
}
}
} else if (id == Material.PUMPKIN.getId()) {
if (plugin.config.harvestPumpkins
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.PUMPKIN, plugin.config.autoStack)) {
ChestManip.addContents(source, new ItemStack(Material.PUMPKIN, 1));
toFarm.setTypeIdAndData(0, (byte) 0, true);
}
} else if (id == Material.MELON_BLOCK.getId()) {
if (plugin.config.harvestMelons
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.MELON_BLOCK, plugin.config.autoStack)) {
ChestManip.addContents(source, new ItemStack(Material.MELON, Rand.RandomInt(3, 7)));
toFarm.setTypeId(0);
}
} else if (id == Material.NETHER_WARTS.getId()) {
if (plugin.config.harvestWarts
&& toFarm.getData() == 0x3
&& !ItemStackManip.is_full(ChestManip.getContents(source), Material.NETHER_WARTS, plugin.config.autoStack)) {
ChestManip.addContents(source, new ItemStack(372, Rand.RandomInt(1, 3)));
toFarm.setData((byte) 0);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onRedstoneEvent(BlockRedstoneEvent event) {
if (ChestHarvester.plugin.config.redstoneHarvest
&& event.getNewCurrent() > 0
&& event.getNewCurrent() != event.getOldCurrent()) {
for (BlockFace bf : dirs) {
Block b = event.getBlock().getRelative(bf);
if (b.getType() == Material.CHEST) {
if (!farmTimes.containsKey(b.getLocation())
|| (farmTimes.get(b.getLocation()) < System.currentTimeMillis()
&& System.currentTimeMillis() - farmTimes.get(b.getLocation()) > plugin.config.chestScanInterval)) {
redstoneAmount.remove(b.getLocation());
autoFarm((Chest) b.getState());
} else {
farmTimes.put(b.getLocation(), System.currentTimeMillis());
if(redstoneAmount.containsKey(b.getLocation())
&& redstoneAmount.get(b.getLocation()) + 1 > ChestHarvester.plugin.config.redstoneOverload) {
// overloaded
if(ChestHarvester.plugin.config.redstoneOverloadAction == CHConfig.OverloadAction.WAIT) {
farmTimes.put(b.getLocation(), System.currentTimeMillis() + plugin.config.chestScanInterval * 10);
} else /* if(ChestHarvester.plugin.config.redstoneOverloadAction == CHConfig.OverloadAction.EXPLODE) */ {
farmTimes.remove(b.getLocation());
b.getWorld().createExplosion(b.getLocation(), 4, true);
}
} else {
redstoneAmount.put(b.getLocation(),
redstoneAmount.containsKey(b.getLocation()) ? redstoneAmount.get(b.getLocation()) + 1 : 1);
}
}
}
}
}
}
}// end class AutoHarvester