/*
* Copyright (C) 2011-2012 Joshua Reetz
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 Tux2.ClayGen;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.PluginManager;
/**
* ClayGen for Bukkit
*
* @author Tux2
*/
public class ClayGen extends JavaPlugin implements Runnable {
//private final ClayGenPlayerListener playerListener = new ClayGenPlayerListener(this);
//private final ClayGenBlockListener blockListener = new ClayGenBlockListener(this);
private final HashMap<Player, Boolean> debugees = new HashMap<Player, Boolean>();
final HashMap<String, ClayDelay> clayblocks = new HashMap<String, ClayDelay>();
final HashMap<String, Integer> claychunks = new HashMap<String, Integer>();
private String blockSaveFile = "plugins/ClayGen/claygen.blocks";
private String claySaveFile = "plugins/ClayGen/claygen.clay";
private Thread dispatchThread;
private Material activateblock = Material.BRICK;
private boolean slowserver = false;
public static final Material CLAY = Material.CLAY;
public static final Material GRAVEL = Material.GRAVEL;
public static final Material WATER = Material.STATIONARY_WATER;
public static final Material FLOWINGWATER = Material.WATER;
public static final Material LAVA = Material.STATIONARY_LAVA;
public static final Material FLOWINGLAVA = Material.LAVA;
LinkedList<Block> doneblocks = new LinkedList<Block>();
boolean debug = false;
boolean mcmmomode = false;
boolean lavaenabled = true;
boolean waterenabled = true;
boolean clayfarm = false;
boolean savefarm = false;
boolean customdrops = false;
double graveltoclaychance = 100.0;
int maxclay = 6;
int minclay = 1;
int defaultclaydrop = 4;
//Set delay for the max amount of clay to 2 minutes.
long timeformaxclay = 2*60*1000;
int farmdelay = 5;
int maxfarmdelay = 12;
String version = "1.7";
ConcurrentHashMap<String, ClayDelay> newgravellist = new ConcurrentHashMap<String, ClayDelay>();
Random generator = new Random();
BlockFace[] waterblocks = {BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH,
BlockFace.EAST, BlockFace.WEST};
private boolean loadchunks = false;
public ClayGen(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) {
super();
loadconfig();
// NOTE: Event registration should be done in onEnable not here as all events are unregistered when a plugin is disabled
}
public ClayGen() {
super();
loadconfig();
}
public synchronized void onEnable() {
// Register our events
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new ClayFromTo(this), this);
//Only initialize this if the clay farm is enabled... otherwise we generate a lot
//of unnesecary events.
if(clayfarm) {
pm.registerEvents(new ClayPlace(this), this);
loadBlocks();
if(slowserver) {
getServer().getScheduler().scheduleSyncRepeatingTask(this, new ClayUpdate(this), 50L, 25L);
}else {
getServer().getScheduler().scheduleSyncRepeatingTask(this, new ClayUpdate(this), 200L, 100L);
}
dispatchThread = new Thread(this);
dispatchThread.start();
}
//only initialize the following two if custom amount of drops is enabled...
if(customdrops) {
loadClayBlocks();
pm.registerEvents(new ClayBreak(this), this);
pm.registerEvents(new ClayPhysics(this), this);
}else if(defaultclaydrop != 4 && defaultclaydrop > 0) {
//let's activate this if we are changing the clay drop amount
pm.registerEvents(new ClayBreak(this), this);
}
if(loadchunks) {
ClaygenWorldListener cu = new ClaygenWorldListener(this);
pm.registerEvents(cu, this);
}
// EXAMPLE: Custom code, here we just output some info so we can check all is well
PluginDescriptionFile pdfFile = this.getDescription();
System.out.println( pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!" );
}
public synchronized void onDisable() {
if(savefarm && clayfarm) {
saveBlocks();
}
// NOTE: All registered events are automatically unregistered when a plugin is disabled
// EXAMPLE: Custom code, here we just output some info so we can check all is well
System.out.println("ClayGen is disabled!");
}
public synchronized boolean isDebugging(final Player player) {
if (debugees.containsKey(player)) {
return debugees.get(player);
} else {
return false;
}
}
public void setDebugging(final Player player, final boolean value) {
debugees.put(player, value);
}
public synchronized Material getActivationBlock() {
return activateblock;
}
private void loadconfig() {
File folder = new File("plugins/ClayGen");
// check for existing file
File configFile = new File("plugins/ClayGen/claygen.ini");
//if it exists, let's read it, if it doesn't, let's create it.
if (configFile.exists()) {
try {
Properties reminderSettings = new Properties();
reminderSettings.load(new FileInputStream(new File("plugins/ClayGen/claygen.ini")));
String activatorblock = reminderSettings.getProperty("activatorblock", "87");
String needactivator = reminderSettings.getProperty("needactivator", "true");
String wateractivator = reminderSettings.getProperty("wateractivated", "true");
String lavaactivator = reminderSettings.getProperty("lavaactivated", "true");
String defaultamount = reminderSettings.getProperty("defaultdropamount", "4");
String afarm = reminderSettings.getProperty("clayfarm", "false");
String fdelay = reminderSettings.getProperty("farmdelay", "5");
String mfdelay = reminderSettings.getProperty("maxdelay", "12");
String sfarm = reminderSettings.getProperty("savefarm", "false");
String cdrops = reminderSettings.getProperty("customdrops", "false");
String smaxclay = reminderSettings.getProperty("maxclay", "6");
String sminclay = reminderSettings.getProperty("minclay", "1");
String sclaytime = reminderSettings.getProperty("timeformaxclay", "12");
String scloaded = reminderSettings.getProperty("keepchunksloaded", "12");
String sclaychance = reminderSettings.getProperty("graveltoclaychance", "100.0");
String sslowserver = reminderSettings.getProperty("slowserver", "false");
//If the version isn't set, the file must be at 0.2
String theversion = reminderSettings.getProperty("version", "0.2");
try {
farmdelay = Integer.parseInt(fdelay.trim());
} catch (Exception ex) {
}
mcmmomode = !stringToBool(needactivator);
slowserver = stringToBool(sslowserver);
waterenabled = stringToBool(wateractivator);
lavaenabled = stringToBool(lavaactivator);
clayfarm = stringToBool(afarm);
savefarm = stringToBool(sfarm);
customdrops = stringToBool(cdrops);
loadchunks = stringToBool(scloaded);
try {
Material tempactivateblock = Material.getMaterial(activatorblock.trim().toUpperCase());
if(tempactivateblock != null) {
activateblock = tempactivateblock;
}
if(!mcmmomode) {
System.out.println("ClayGen: Setting activation block to: " + activatorblock.trim());
}
} catch (Exception ex) {
}
//Let's see if we need to upgrade the config file
double dbversion = 0.2;
try {
dbversion = Double.parseDouble(theversion.trim());
} catch (Exception ex) {
}
try {
graveltoclaychance = Double.parseDouble(sclaychance.trim());
} catch (Exception ex) {
}
try {
defaultclaydrop = Integer.parseInt(defaultamount.trim());
} catch (Exception ex) {
}
try {
maxclay = Integer.parseInt(smaxclay.trim());
} catch (Exception ex) {
}
try {
minclay = Integer.parseInt(sminclay.trim());
} catch (Exception ex) {
}
try {
timeformaxclay = Integer.parseInt(sclaytime.trim())*10*1000;
} catch (Exception ex) {
}
try {
maxfarmdelay = Integer.parseInt(mfdelay.trim());
} catch (Exception ex) {
}
if(dbversion < 1.7) {
updateIni();
}
} catch (IOException e) {
}
}else {
System.out.println("ClayGen: Configuration file not found");
System.out.println("ClayGen: + creating folder plugins/ClayGen");
folder.mkdir();
System.out.println("ClayGen: - creating file claygen.ini");
updateIni();
}
}
private void updateIni() {
try {
BufferedWriter outChannel = new BufferedWriter(new FileWriter("plugins/ClayGen/claygen.ini"));
outChannel.write("# This is the main claygen config file\n" +
"# The ActivatorBlock is the Material name of the block needed\n" +
"# under the gravel to make it into clay. Default is a Brick Block\n" +
"# If needactivator is set to false, then any gravel\n" +
"# block that comes in contact with flowing water\n" +
"# gets converted into clay.\n" +
"activatorblock = " + activateblock.toString() + "\n" +
"needactivator = " + !mcmmomode + "\n" +
"# Set whether water flow will trigger the change\n" +
"wateractivated = " + waterenabled + "\n" +
"# Set whether lava flow will trigger the change\n" +
"lavaactivated = " + lavaenabled + "\n\n" +
"# defaultdropamount changes the default amount of clay dropped when a block is broken\n" +
"defaultdropamount = " + defaultclaydrop + "\n\n" +
"# Clayfarm sets it so that the gravel turns into clay after a delay\n" +
"clayfarm = " + clayfarm + "\n" +
"# farmdelay sets the minimum delay in 10 second intervals. 5 = 50 seconds.\n" +
"farmdelay = " + farmdelay + "\n" +
"# maxdelay sets the max delay in 10 second intervals. 12 = 120 seconds.\n" +
"maxdelay = " + maxfarmdelay + "\n" +
"# slowserver Set this to true if your server has less than 10 ticks per second\n" +
"# (This is only used in farming mode)\n" +
"slowserver = " + slowserver + "\n" +
"# keepchunksloaded keeps all the chunks loaded into memory where gravel is turning into clay.\n" +
"keepchunksloaded = " + loadchunks + "\n" +
"# savefarm saves all the blocks currently being farmed for clay. (Otherwise\n" +
"# you will have to replace the gravel blocks or re-run the water after server reboot.)\n" +
"# Only useful if you have a large (20min+) delay for the gravel turning into clay.\n" +
"savefarm = " + savefarm + "\n" +
"\n" +
"# The following lines let you set a custom number of clay drops based on the amount\n" +
"# of time that water has been running over them.\n" +
"# customdrops, if true, enables the custom drops\n" +
"customdrops = " + customdrops + "\n" +
"# maxclay sets the maximum amount of clay a block can give\n" +
"maxclay = " + maxclay + "\n" +
"# minclay, sets the minimum amount of clay a block can give (must be more than 0!)\n" +
"minclay = " + minclay + "\n" +
"# timeformaxclay, sets how long the player must wait for the max amount of clay\n" +
"# in 10 second intervals. 12 = 120 seconds.\n" +
"timeformaxclay = " + (timeformaxclay/10/1000) + "\n" +
"\n" +
"# graveltoclaychance sets the chance from 0.0% to 100.0% of the gravel turning into clay\n" +
"graveltoclaychance = " + graveltoclaychance + "\n" +
"# Do not change anything below this line unless you know what you are doing!\n" +
"version = " + version);
outChannel.close();
} catch (Exception e) {
System.out.println("ClayGen: - file creation failed, using defaults.");
}
}
public synchronized void convertBlocks(Block thewaterblock) {
Material waterid = thewaterblock.getType();
if((waterenabled && (waterid == Material.STATIONARY_WATER || waterid == Material.WATER)) || (lavaenabled && (waterid == Material.STATIONARY_LAVA || waterid == Material.LAVA))) {
Block thegravelblocks[] = {thewaterblock.getRelative(BlockFace.DOWN),
thewaterblock.getRelative(BlockFace.NORTH),
thewaterblock.getRelative(BlockFace.SOUTH),
thewaterblock.getRelative(BlockFace.EAST),
thewaterblock.getRelative(BlockFace.WEST)};
if(debug) {
System.out.println("Water is flowing...");
}
for(int i = 0; i < thegravelblocks.length; i++) {
if(thegravelblocks[i].getType() == GRAVEL) {
if(debug) {
System.out.println("We have a gravel block here!");
}
if(mcmmomode || getActivationBlock() == thegravelblocks[i].getRelative(BlockFace.DOWN).getType()) {
if(debug) {
System.out.println("Found the right activator, converting to clay.");
}
//If we have clayfarm mode enabled, let's add the blocks to the queue.
if (clayfarm) {
if(!newgravellist.containsKey(getBlockString(thegravelblocks[i]))) {
if(loadchunks) {
addBlockToChunk(thegravelblocks[i]);
}
newgravellist.put(getBlockString(thegravelblocks[i]), new ClayDelay(thegravelblocks[i]));
//Only start the thread if nothing is waiting...
//otherwise gravel placed really fast will trigger it
//to update too fast.
if(newgravellist.size() <= 1) {
dispatchThread.interrupt();
}
}
//Otherwise, let's convert!
}else {
//Is this block going to convert?
int rand = generator.nextInt(10000);
if(graveltoclaychance == 100.0) {
thegravelblocks[i].setType(CLAY);
//if custom amount of drops is enabled, let's add them to the queue
if(customdrops) {
clayblocks.put(compileBlockString(thegravelblocks[i]), new ClayDelay(thegravelblocks[i]));
saveClayBlocks();
}
//Each block gets iterated over multiple times... let's reduce the percentage.
}else if ( rand >= (10000.0 - (graveltoclaychance * 25.0))) {
if(waterenabled && lavaenabled) {
thegravelblocks[i].setType(CLAY);
//if custom amount of drops is enabled, let's add them to the queue
if(customdrops) {
clayblocks.put(compileBlockString(thegravelblocks[i]), new ClayDelay(thegravelblocks[i]));
saveClayBlocks();
}
}else if(waterenabled) {
thegravelblocks[i].setType(CLAY);
//if custom amount of drops is enabled, let's add them to the queue
if(customdrops) {
clayblocks.put(compileBlockString(thegravelblocks[i]), new ClayDelay(thegravelblocks[i]));
saveClayBlocks();
}
//don't want it to happen twice as fast when there is lava...
}else if(lavaenabled) {
thegravelblocks[i].setType(CLAY);
//if custom amount of drops is enabled, let's add them to the queue
if(customdrops) {
clayblocks.put(compileBlockString(thegravelblocks[i]), new ClayDelay(thegravelblocks[i]));
saveClayBlocks();
}
}
}
}
}
}
}
}
}
private synchronized boolean stringToBool(String thebool) {
boolean result;
if (thebool.trim().equalsIgnoreCase("true") || thebool.trim().equalsIgnoreCase("yes")) {
result = true;
} else {
result = false;
}
return result;
}
@Override
public synchronized void run() {
boolean running = true;
int savedelay = 0;
while (running) {
// If the list is empty, wait until something gets added.
if (newgravellist.size() == 0) {
if(debug) {
System.out.println("Claygen: No more gravel to process!");
}
//Let's update the list if there is no more gravel to process.
if(savefarm) {
saveBlocks();
savedelay = 0;
}
try {
wait();
}
catch (InterruptedException e) {
// Do nothing.
}
}
//Wait 10 seconds between each iteration.
try {
wait(10000);
} catch (InterruptedException e) {
}
Iterator<Entry<String, ClayDelay>> listing = newgravellist.entrySet().iterator();
if(debug) {
System.out.println("[ClayGen] Iterating over gravel. Have " + newgravellist.size() + "gravel to process.");
}
while(listing.hasNext()) {
ClayDelay blockupdate = (ClayDelay) listing.next().getValue();
//make sure the chunk is loaded...
boolean isloaded = blockupdate.getBlock().getWorld().isChunkLoaded(blockupdate.getBlock().getChunk());
if(isloaded) {
//If they took away the gravel, or activator, let's not keep it in here...
if(blockupdate.getBlock().getType() == GRAVEL &&
(mcmmomode || blockupdate.getBlock().getRelative(BlockFace.DOWN).getType() == activateblock)) {
//let's see if water farming is enabled.
boolean alreadyupdated = false;
if(waterenabled && lavaenabled) {
//See if there is a water block next to it...
if(hasBlockNextTo(blockupdate.getBlock(), FLOWINGWATER, WATER, FLOWINGLAVA, LAVA)) {
blockupdate.upDelay(generator.nextInt(2));
if(debug) {
System.out.println("upped the int to: " + blockupdate.getDelay());
}
alreadyupdated = true;
}
}else if(waterenabled) {
//See if there is a water block next to it...
if(hasBlockNextTo(blockupdate.getBlock(), FLOWINGWATER, WATER)) {
blockupdate.upDelay(generator.nextInt(2));
if(debug) {
System.out.println("upped the int to: " + blockupdate.getDelay());
}
alreadyupdated = true;
}
//don't want it to happen twice as fast when there is lava...
}else if(lavaenabled) {
//See if there is a lava block next to it...
if(hasBlockNextTo(blockupdate.getBlock(), FLOWINGLAVA, LAVA)) {
blockupdate.upDelay(generator.nextInt(2));
if(debug) {
System.out.println("upped the int to: " + blockupdate.getDelay());
}
alreadyupdated = true;
}
}
if(alreadyupdated == false) {
if(debug) {
System.out.println("Whoops! no more flow! Removing...");
}
//Remove the block, it's been updated!
if(loadchunks) {
removeBlockFromChunk(blockupdate.getBlock());
}
listing.remove();
}else if(blockupdate.getDelay() >= farmdelay || (blockupdate.getInTime()+(10000*maxfarmdelay)) <= System.currentTimeMillis()) {
//Remove the block, it's been updated!
if(loadchunks) {
removeBlockFromChunk(blockupdate.getBlock());
}
listing.remove();
int rand = generator.nextInt(10000);
if(graveltoclaychance == 100.0) {
doneblocks.add(blockupdate.getBlock());
//blockupdate.getBlock().setTypeId(CLAY);
if(customdrops) {
blockupdate.resetTimeIn();
clayblocks.put(compileBlockString(blockupdate.getBlock()), blockupdate);
saveClayBlocks();
}
}else if(rand >= (10000.0 - (graveltoclaychance * 100.0))) {
doneblocks.add(blockupdate.getBlock());
//blockupdate.getBlock().setTypeId(CLAY);
if(customdrops) {
blockupdate.resetTimeIn();
clayblocks.put(compileBlockString(blockupdate.getBlock()), blockupdate);
saveClayBlocks();
}
}
if(debug) {
System.out.println("We now have " + newgravellist.size() + " in the queue");
}
}
//Remove that non-gravel block
}else {
if(loadchunks) {
removeBlockFromChunk(blockupdate.getBlock());
}
listing.remove();
if(debug) {
System.out.println("We now have " + newgravellist.size() + " in the queue");
}
}
}else if(loadchunks) {
blockupdate.getBlock().getWorld().loadChunk(blockupdate.getBlock().getChunk());
}
}
savedelay++;
if(savefarm && savedelay >= 10) {
saveBlocks();
savedelay = 0;
}
}
}
public synchronized boolean hasBlockNextTo(Block theblock, Material blockid) {
for (int i = 0; i < waterblocks.length; i++) {
if(theblock.getRelative(waterblocks[i]).getType() == blockid) {
return true;
}
}
return false;
}
public synchronized boolean hasBlockNextTo(Block theblock, Material blockid, Material blockid2) {
for (int i = 0; i < waterblocks.length; i++) {
Material id = theblock.getRelative(waterblocks[i]).getType();
if(id == blockid || id == blockid2) {
return true;
}
}
return false;
}
public synchronized boolean hasBlockNextTo(Block theblock, Material blockid, Material blockid2, Material blockid3, Material blockid4) {
for (int i = 0; i < waterblocks.length; i++) {
Material id = theblock.getRelative(waterblocks[i]).getType();
if(id == blockid || id == blockid2 || id == blockid3 || id == blockid4) {
return true;
}
}
return false;
}
public synchronized void gravelPlaced(Block thegravelblock) {
if(debug){
System.out.println("[ClayGen] Gravel Placed!");
}
if(thegravelblock.getType() == GRAVEL && (mcmmomode || thegravelblock.getRelative(BlockFace.DOWN).getType() == activateblock)) {
//let's make sure we aren't adding duplicates...
if(!newgravellist.containsKey(getBlockString(thegravelblock))) {
//let's see if water farming is enabled.
boolean alreadyupdated = false;
if(waterenabled) {
//See if there is a water block next to it...
if(hasBlockNextTo(thegravelblock, WATER, FLOWINGWATER)) {
if(loadchunks) {
addBlockToChunk(thegravelblock);
}
newgravellist.put(getBlockString(thegravelblock), new ClayDelay(thegravelblock));
//Only start the thread if nothing is waiting...
//otherwise gravel placed really fast will trigger it
//to update too fast.
if(newgravellist.size() <= 1) {
dispatchThread.interrupt();
}
alreadyupdated = true;
}
//don't want it to add it twice when there is lava...
}if(lavaenabled && !alreadyupdated) {
//See if there is a lava block next to it...
if(hasBlockNextTo(thegravelblock, LAVA, FLOWINGLAVA)) {
if(loadchunks) {
addBlockToChunk(thegravelblock);
}
newgravellist.put(getBlockString(thegravelblock), new ClayDelay(thegravelblock));
//Only start the thread if nothing is waiting...
//otherwise gravel placed really fast will trigger it
//to update too fast.
if(newgravellist.size() <= 1) {
dispatchThread.interrupt();
}
}
}
}
}
}
private void saveBlocks() {
if(debug) {
System.out.println("[ClayGen] Saving blocks");
}
LinkedList<SaveBlock> glocations = new LinkedList<SaveBlock>();
Enumeration<ClayDelay> gravellist = newgravellist.elements();
while(gravellist.hasMoreElements()) {
glocations.add(new SaveBlock(gravellist.nextElement()));
}
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File(blockSaveFile)));
out.writeObject(glocations);
out.flush();
out.close();
}
catch (Exception e) {
if(debug) {
System.out.println("Couldn't write blocks!");
System.out.println(e);
}
}
}
@SuppressWarnings("unchecked")
private void loadBlocks() {
try {
ObjectInputStream out = new ObjectInputStream(new FileInputStream(new File(blockSaveFile)));
if(debug) {
System.out.println("ClayGen: Reading file.");
}
LinkedList<SaveBlock> glocations = (LinkedList<SaveBlock>) out.readObject();
if(debug) {
System.out.println("ClayGen: Turning locations into Blocks");
}
newgravellist.clear();
for(SaveBlock blocklocation : glocations) {
org.bukkit.World theworld = getServer().getWorld(blocklocation.getWorld());
Location lblock = new Location(theworld, blocklocation.getX(),
blocklocation.getY(), blocklocation.getZ());
Block theblock = lblock.getBlock();
if(loadchunks) {
addBlockToChunk(theblock);
}
newgravellist.put(getBlockString(theblock), new ClayDelay(theblock, blocklocation.getDelayvalue(), blocklocation.getIntime()));
}
if(debug) {
System.out.println("ClayGen: Finished reading file!");
}
out.close();
}
catch (Exception e) {
// If it doesn't work, no great loss!
if(debug) {
System.out.println("Couldn't read save file!");
System.out.println(e);
}
}
}
void saveClayBlocks() {
LinkedList<SaveBlock> glocations = new LinkedList<SaveBlock>();
Collection<ClayDelay> cblock = clayblocks.values();
for(ClayDelay theblock : cblock) {
glocations.add(new SaveBlock(theblock));
}
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File(claySaveFile)));
out.writeObject(glocations);
out.flush();
out.close();
}
catch (Exception e) {
if(true) {
System.out.println("Couldn't write blocks!");
System.out.println(e);
}
}
}
@SuppressWarnings("unchecked")
private void loadClayBlocks() {
try {
ObjectInputStream out = new ObjectInputStream(new FileInputStream(new File(claySaveFile)));
if(debug) {
System.out.println("ClayGen: Reading clay file.");
}
LinkedList<SaveBlock> glocations = (LinkedList<SaveBlock>) out.readObject();
if(debug) {
System.out.println("ClayGen: Turning locations into clay Blocks");
}
clayblocks.clear();
for(SaveBlock blocklocation : glocations) {
org.bukkit.World theworld = getServer().getWorld(blocklocation.getWorld());
Location lblock = new Location(theworld, blocklocation.getX(),
blocklocation.getY(), blocklocation.getZ());
Block theblock = lblock.getBlock();
clayblocks.put(compileBlockString(theblock), new ClayDelay(theblock, blocklocation.getDelayvalue(), blocklocation.getIntime()));
if(debug) {
System.out.println("ClayGen: Reading block at: " + compileBlockString(theblock));
}
}
if(debug) {
System.out.println("ClayGen: Finished reading clay file!");
}
out.close();
}
catch (Exception e) {
// If it doesn't work, no great loss!
if(debug) {
System.out.println("Couldn't read clay save file!");
System.out.println(e);
}
}
}
public void clayWaterRemoved(Block block) {
// Let's see if it's one of the clay blocks we are tracking...
if(clayblocks.containsKey(compileBlockString(block))) {
ClayDelay theblock = clayblocks.get(compileBlockString(block));
try {
clayblocks.remove(compileBlockString(block));
block.setMetadata("ClayDrops", new FixedMetadataValue(this, (byte) getNumberOfDrops(theblock)));
}catch (StackOverflowError e) {
}
saveClayBlocks();
}
}
public String compileBlockString(Block block) {
return block.getWorld().getName() + "." + block.getX() + "." + block.getY() + "." + block.getZ();
}
int getNumberOfDrops(ClayDelay theblock) {
long timeelapsed = System.currentTimeMillis() - theblock.getInTime();
long timefor1drop = timeformaxclay/(maxclay-minclay);
long numberofdrops = (timeelapsed/timefor1drop) + minclay;
if(numberofdrops > maxclay) {
numberofdrops = maxclay;
}
return (int) numberofdrops;
}
public String getBlockString(Block block) {
return block.getWorld().getName() + "." + block.getX() + "." + block.getY() + "." + block.getZ();
}
public String getChunkString(Chunk chunk) {
return chunk.getWorld().getName() + "." + chunk.getX() + "." + chunk.getZ();
}
public boolean canUnloadChunk(Chunk chunk) {
return !claychunks.containsKey(getChunkString(chunk));
}
public void addBlockToChunk(Block block) {
if(claychunks.containsKey(getChunkString(block.getChunk()))) {
int theint = claychunks.get(getChunkString(block.getChunk())).intValue();
theint++;
claychunks.put(getChunkString(block.getChunk()), new Integer(theint));
}else {
claychunks.put(getChunkString(block.getChunk()), new Integer(1));
}
}
public void removeBlockFromChunk(Block block) {
if(claychunks.containsKey(getChunkString(block.getChunk()))) {
int theint = claychunks.get(getChunkString(block.getChunk())).intValue();
theint--;
if(theint < 1) {
claychunks.remove(getChunkString(block.getChunk()));
}else {
claychunks.put(getChunkString(block.getChunk()), new Integer(theint));
}
}
}
}