Anonymous avatar Anonymous committed 0aa9b1a

added configuration (chest duplicator is disabled by default), added furnace duplicator to make players consume cobblestones as fuel for duplication

Comments (0)

Files changed (4)

src/info/daybreaker/minecraft/PhilosophersCircuitListener.java

-package info.daybreaker.minecraft;
-
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-import org.bukkit.block.Chest;
-import org.bukkit.event.block.BlockListener;
-import org.bukkit.event.block.BlockPistonRetractEvent;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.material.MaterialData;
-
-public class PhilosophersCircuitListener extends BlockListener {
-	private final PhilosophersCircuitPlugin plugin;
-
-	public PhilosophersCircuitListener(final PhilosophersCircuitPlugin plugin) {
-		this.plugin = plugin;
-	}
-
-	private boolean isDuplicable(Block b) {
-		if (b.isEmpty() || b.isLiquid())
-			return false;
-		int typeId = b.getTypeId();
-		// The below check routine is borrowed from the solid block check routine, at
-		// https://github.com/VitaB/CraftBukkit/commit/00253076a6cec6d117827ec862ca9f8a7b723bfa
-		return (typeId > 0 && typeId < 6) || (typeId == 7) || (typeId > 11 && typeId < 27) || (typeId == 29)
-				|| (typeId == 33) || (typeId == 35) || (typeId == 36) || (typeId > 40 && typeId < 50)
-				|| (typeId > 51 && typeId < 55) || (typeId > 55 && typeId < 59) || (typeId > 59 && typeId < 65)
-				|| (typeId == 67) || (typeId == 71) || (typeId == 73) || (typeId == 74) || (typeId > 77 && typeId < 83)
-				|| (typeId > 83 && typeId < 90) || (typeId == 91) || (typeId == 92) || (typeId == 95);
-	}
-
-	private boolean isStackable(Material m) {
-		int typeId = m.getId();
-		if ((typeId >= 256 && typeId <= 261) || (typeId >= 267 && typeId <= 279) || (typeId >= 282 && typeId <= 286)
-				|| (typeId >= 290 && typeId <= 294) || (typeId == 297) || (typeId == 319) || (typeId == 320)
-				|| (typeId >= 322 && typeId <= 330) || (typeId >= 333 && typeId <= 335)
-				|| (typeId >= 342 && typeId <= 343) || (typeId == 346) || (typeId == 349) || (typeId == 350)
-				|| (typeId == 354) || (typeId == 355) || (typeId == 358) || (typeId == 359) || (typeId == 2256)
-				|| (typeId == 2257))
-			return false;
-		return true;
-	}
-
-	@Override
-	public void onBlockPistonRetract(BlockPistonRetractEvent ev) {
-
-		if (!ev.isSticky())
-			return;
-		final Block piston = ev.getBlock();
-		final World world = piston.getWorld();
-		final Location pistonLocation = piston.getLocation();
-		final Location retractedLocation = ev.getRetractLocation();
-
-		Block up1 = piston.getRelative(BlockFace.UP, 1);
-		Block up2 = piston.getRelative(BlockFace.UP, 2);
-
-		if (up1.getType().equals(Material.GLOWSTONE) && up2.getType().equals(Material.OBSIDIAN)) {
-			final Material sourceType = retractedLocation.getBlock().getType();
-			
-			if (retractedLocation.getBlock().getType().equals(Material.CHEST)) {
-				// Copy the first item in the chest and decrement the amount of the original stack in the chest.
-				// If we do not decrement it, an infinite amount of item entities on the map may cause severe lag.
-				Chest chest = (Chest) retractedLocation.getBlock().getState();
-				ItemStack stack = chest.getInventory().getItem(0);
-				if (stack != null) {
-					int amount = stack.getAmount();
-					if (amount > 0) {
-						Material sourceMaterial = stack.getType();
-						MaterialData sourceData = stack.getData();
-						short sourceDurability = stack.getDurability();
-						ItemStack poppedStack = new ItemStack(sourceMaterial);
-						if (sourceData != null)
-							poppedStack.setData(sourceData);
-						poppedStack.setDurability(sourceDurability);
-						int numObsidiansAbove = 1;
-						for (int i = 3; i < 128 - pistonLocation.getBlockY(); i++) {
-							if (piston.getRelative(BlockFace.UP, i).getType().equals(Material.OBSIDIAN)) {
-								numObsidiansAbove++;
-							} else
-								break;
-						}
-						if (isStackable(stack.getType()) && stack.getMaxStackSize() > 0) {
-							poppedStack.setAmount(Math.min(numObsidiansAbove, stack.getMaxStackSize()));
-							world.dropItemNaturally(retractedLocation, poppedStack);
-						} else {
-							poppedStack.setAmount(1);
-							for (int i = 0; i < numObsidiansAbove; i++)
-								world.dropItemNaturally(retractedLocation, poppedStack);
-						}
-						if (amount == 1) {
-							chest.getInventory().clear(0); // amount zero is same to one, so we have to clear it.
-						} else
-							stack.setAmount(amount - 1);
-					}
-				}
-			} else {
-				final byte sourceData = retractedLocation.getBlock().getData();
-				
-				if (!isDuplicable(retractedLocation.getBlock()))
-					return;
-				if (sourceType.equals(Material.PISTON_MOVING_PIECE)) // to avoid buggy situation
-					return;
-
-				// After 2 ticks, retractedLocation becomes AIR since the sticky piston pulls the block.
-				// Then we set that block at retractedLocation, and it's now duplicated!
-				plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
-					public void run() {
-						int t = world.getBlockTypeIdAt(retractedLocation);
-						if (t == Material.AIR.getId() || t == Material.PISTON_MOVING_PIECE.getId()) {
-							world.getBlockAt(retractedLocation).setType(sourceType);
-							world.getBlockAt(retractedLocation).setData(sourceData);
-						}
-					}
-				}, 2);
-			}
-		}
-	}
-}

src/info/daybreaker/minecraft/PhilosophersCircuitPistonListener.java

+package info.daybreaker.minecraft;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.Chest;
+import org.bukkit.block.Furnace;
+import org.bukkit.event.block.BlockListener;
+import org.bukkit.event.block.BlockPistonRetractEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.material.MaterialData;
+
+public class PhilosophersCircuitPistonListener extends BlockListener {
+	private final PhilosophersCircuitPlugin plugin;
+	private static final int indexOfSource = 0;
+	private static final int indexOfFuel = 1;
+	private static final int indexOfResult = 2;
+
+	public PhilosophersCircuitPistonListener(final PhilosophersCircuitPlugin plugin) {
+		this.plugin = plugin;
+	}
+
+	private boolean isDuplicable(Block b) {
+		if (b.isEmpty() || b.isLiquid())
+			return false;
+		int typeId = b.getTypeId();
+		// The below check routine is borrowed from the solid block check routine, at
+		// https://github.com/VitaB/CraftBukkit/commit/00253076a6cec6d117827ec862ca9f8a7b723bfa
+		return (typeId > 0 && typeId < 6) || (typeId == 7) || (typeId > 11 && typeId < 27) || (typeId == 29)
+				|| (typeId == 33) || (typeId == 35) || (typeId == 36) || (typeId > 40 && typeId < 50)
+				|| (typeId > 51 && typeId < 55) || (typeId > 55 && typeId < 59) || (typeId > 59 && typeId < 65)
+				|| (typeId == 67) || (typeId == 71) || (typeId == 73) || (typeId == 74) || (typeId > 77 && typeId < 83)
+				|| (typeId > 83 && typeId < 90) || (typeId == 91) || (typeId == 92) || (typeId == 95);
+	}
+
+	private boolean isStackable(Material m) {
+		int typeId = m.getId();
+		if ((typeId >= 256 && typeId <= 261) || (typeId >= 267 && typeId <= 279) || (typeId >= 282 && typeId <= 286)
+				|| (typeId >= 290 && typeId <= 294) || (typeId == 297) || (typeId == 319) || (typeId == 320)
+				|| (typeId >= 322 && typeId <= 330) || (typeId >= 333 && typeId <= 335)
+				|| (typeId >= 342 && typeId <= 343) || (typeId == 346) || (typeId == 349) || (typeId == 350)
+				|| (typeId == 354) || (typeId == 355) || (typeId == 358) || (typeId == 359) || (typeId == 2256)
+				|| (typeId == 2257))
+			return false;
+		return true;
+	}
+
+	@Override
+	public void onBlockPistonRetract(BlockPistonRetractEvent ev) {
+
+		if (!ev.isSticky())
+			return;
+		final Block piston = ev.getBlock();
+		final Location retractedLocation = ev.getRetractLocation();
+		final Block targetBlock = retractedLocation.getBlock();
+		final World world = targetBlock.getWorld();
+
+		if (Utils.checkActivatingCondition(piston)) {
+			final Material sourceType = targetBlock.getType();
+
+			if (plugin.isChestDuplicatorEnabled && retractedLocation.getBlock().getType().equals(Material.CHEST)) {
+				// Copy the first item in the chest and decrement the amount of the original stack in the chest.
+				// If we do not decrement it, an infinite amount of item entities on the map may cause severe lag.
+				Chest chest = (Chest) retractedLocation.getBlock().getState();
+				ItemStack stack = chest.getInventory().getItem(0);
+				if (stack != null) {
+					int amount = stack.getAmount();
+					if (amount > 0) {
+						Material sourceMaterial = stack.getType();
+						MaterialData sourceData = stack.getData();
+						short sourceDurability = stack.getDurability();
+						ItemStack poppedStack = new ItemStack(sourceMaterial);
+						if (sourceData != null)
+							poppedStack.setData(sourceData);
+						poppedStack.setDurability(sourceDurability);
+						int numObsidiansAbove = Utils.countBlocksAbove(piston, Material.OBSIDIAN, 2);
+						if (isStackable(stack.getType()) && stack.getMaxStackSize() > 0) {
+							poppedStack.setAmount(Math.min(numObsidiansAbove, stack.getMaxStackSize()));
+							world.dropItemNaturally(retractedLocation, poppedStack);
+						} else {
+							poppedStack.setAmount(1);
+							for (int i = 0; i < numObsidiansAbove; i++)
+								world.dropItemNaturally(retractedLocation, poppedStack);
+						}
+						if (amount == 1) {
+							chest.getInventory().clear(0); // amount zero is same to one, so we have to clear it.
+						} else
+							stack.setAmount(amount - 1);
+					}
+				}
+			} else if (targetBlock.getType().equals(Material.FURNACE)) {
+
+				final Furnace furnace = (Furnace) targetBlock.getState();
+				Inventory inventory = furnace.getInventory();
+				ItemStack sourceStack = inventory.getItem(indexOfSource);
+				ItemStack fuelStack = inventory.getItem(indexOfFuel);
+				ItemStack resultStack = inventory.getItem(indexOfResult);
+
+				if (fuelStack.getType().equals(Material.COBBLESTONE) && sourceStack.getAmount() > 0) {
+					int fuelAmount = fuelStack.getAmount();
+					if (resultStack.getTypeId() == 0)
+						resultStack = new ItemStack(sourceStack.getType());
+					resultStack.setData(sourceStack.getData());
+					resultStack.setDurability(sourceStack.getDurability());
+					resultStack.setAmount(resultStack.getAmount()
+							+ Math.min(Utils.countBlocksAbove(piston, Material.OBSIDIAN, 2),
+									resultStack.getMaxStackSize()));
+					if (fuelAmount == 1)
+						inventory.clear(indexOfFuel);
+					else
+						fuelStack.setAmount(fuelAmount - 1);
+					inventory.setItem(indexOfResult, resultStack);
+				}
+
+			} else {
+
+				final byte sourceData = targetBlock.getData();
+
+				if (!isDuplicable(targetBlock))
+					return;
+				if (sourceType.equals(Material.PISTON_MOVING_PIECE)) // to avoid buggy situation
+					return;
+
+				// After 2 ticks, retractedLocation becomes AIR since the sticky piston pulls the block.
+				// Then we set that block at retractedLocation, and it's now duplicated!
+				plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
+					public void run() {
+						int t = world.getBlockTypeIdAt(retractedLocation);
+						if (t == Material.AIR.getId() || t == Material.PISTON_MOVING_PIECE.getId()) {
+							world.getBlockAt(retractedLocation).setType(sourceType);
+							world.getBlockAt(retractedLocation).setData(sourceData);
+						}
+					}
+				}, 2);
+			}
+		}
+	}
+}

src/info/daybreaker/minecraft/PhilosophersCircuitPlugin.java

 package info.daybreaker.minecraft;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.io.File;
+import java.io.IOException;
 import java.util.logging.Logger;
 
-import org.bukkit.Location;
 import org.bukkit.event.Event;
 import org.bukkit.event.Event.Priority;
 import org.bukkit.plugin.PluginManager;
 import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.util.config.Configuration;
 
 public class PhilosophersCircuitPlugin extends JavaPlugin {
 
 	/**
-	 * This plugin re-implements the "block duplicator bug" in Minecraft 1.7.2.
-	 * The reason for to do this is to make more fun for experienced players who
-	 * get tired of collecting every material for building.
+	 * This plugin re-implements the "block duplicator bug" in Minecraft 1.7.2. The reason for to do this is to make
+	 * more fun for experienced players who get tired of collecting every material for building.
 	 * 
-	 * To make a modest level of hurdle for new players and not to ruin the game
-	 * play, the player must put a glowstone and obsidian on the top of a sticky
-	 * piston as well as a redstone ciruit with a clock generator (composed of
-	 * two repeaters) and a clock adjuster (composed of one repeater). Slime
-	 * balls, redstone and obsdian only can be obtained at deep levels after
-	 * some exploration, and glowstone only can be mined at the nether which is
-	 * dangerous. Also, to duplicate diamonds, players must collect at least 9
-	 * diamonds to make tehm as a block.
+	 * To make a modest level of hurdle for new players and not to ruin the game play, the player must put a glowstone
+	 * and obsidian on the top of a sticky piston as well as a redstone ciruit with a clock generator (composed of two
+	 * repeaters) and a clock adjuster (composed of one repeater). Slime balls, redstone and obsdian only can be
+	 * obtained at deep levels after some exploration, and glowstone only can be mined at the nether which is dangerous.
+	 * Also, to duplicate diamonds, players must collect at least 9 diamonds to make tehm as a block.
 	 * 
 	 * Now enjoy the industrial age!
 	 */
 
-	private final PhilosophersCircuitListener blockListener = new PhilosophersCircuitListener(
-			this);
+	private final PhilosophersCircuitPistonListener pistonListener = new PhilosophersCircuitPistonListener(this);
+	protected Configuration config;
 	public final Logger log = Logger.getLogger("Minecraft");
 
+	public boolean isChestDuplicatorEnabled = false;
+
+	public void loadConfig() {
+		File file = new File(this.getDataFolder() + File.separator + "config.yml");
+		if (file.exists() && file.canRead()) {
+			config = new Configuration(file);
+			config.load();
+		} else {
+			log.info("Philosopher's Circuit: no config (" + file.getAbsolutePath() + ") found, creating it using defaults.");
+			this.getDataFolder().mkdirs();
+			try {
+				file.createNewFile();
+			} catch (IOException e) {
+				e.printStackTrace();
+				return;
+			}
+			config = new Configuration(file);
+			config.setProperty("chestDuplicator.enabled", false);
+			config.save();
+		}
+	}
+
 	@Override
 	public void onDisable() {
 		log.info("Philosopher's Circuit is disabled.");
 	@Override
 	public void onEnable() {
 		PluginManager pm = getServer().getPluginManager();
-		pm.registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockListener,
-				Priority.Normal, this);
+		pm.registerEvent(Event.Type.BLOCK_PISTON_RETRACT, pistonListener, Priority.Normal, this);
+		loadConfig();
+		isChestDuplicatorEnabled = config.getBoolean("chestDuplicator.enabled", false);
 		log.info("Philosopher's Circuit is enabled.");
 	}
 

src/info/daybreaker/minecraft/Utils.java

+package info.daybreaker.minecraft;
+
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+
+public class Utils {
+	public static int countBlocksAbove(Block block, Material type, int startOffset) {
+		int count = 0;
+		int y = block.getY();
+		for (int i = startOffset; i < 128 - y; i++) {
+			if (block.getRelative(BlockFace.UP, i).getType().equals(type)) {
+				count++;
+			} else
+				break;
+		}
+		return count + startOffset;
+	}
+	
+	public static boolean checkActivatingCondition(Block block) {
+		Block up1 = block.getRelative(BlockFace.UP, 1);
+		Block up2 = block.getRelative(BlockFace.UP, 2);
+		return (up1.getType().equals(Material.GLOWSTONE) && up2.getType().equals(Material.OBSIDIAN));
+	}
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.