aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Java/cofh/energy/EnergyStorage.java (renamed from src/Java/api/cofh/energy/EnergyStorage.java)2
-rw-r--r--src/Java/cofh/energy/IEnergyConnection.java (renamed from src/Java/api/cofh/energy/IEnergyConnection.java)2
-rw-r--r--src/Java/cofh/energy/IEnergyContainerItem.java (renamed from src/Java/api/cofh/energy/IEnergyContainerItem.java)2
-rw-r--r--src/Java/cofh/energy/IEnergyHandler.java (renamed from src/Java/api/cofh/energy/IEnergyHandler.java)2
-rw-r--r--src/Java/cofh/energy/IEnergyProvider.java (renamed from src/Java/api/cofh/energy/IEnergyProvider.java)2
-rw-r--r--src/Java/cofh/energy/IEnergyReceiver.java (renamed from src/Java/api/cofh/energy/IEnergyReceiver.java)2
-rw-r--r--src/Java/cofh/energy/IEnergyStorage.java (renamed from src/Java/api/cofh/energy/IEnergyStorage.java)2
-rw-r--r--src/Java/cofh/energy/ItemEnergyContainer.java (renamed from src/Java/api/cofh/energy/ItemEnergyContainer.java)2
-rw-r--r--src/Java/cofh/energy/TileEnergyHandler.java (renamed from src/Java/api/cofh/energy/TileEnergyHandler.java)2
-rw-r--r--src/Java/cofh/mod/BaseMod.java284
-rw-r--r--src/Java/cofh/mod/ChildMod.java17
-rw-r--r--src/Java/cofh/mod/ChildModContainer.java43
-rw-r--r--src/Java/gtPlusPlus/core/item/general/RF2EU_Battery.java2
-rw-r--r--src/Java/gtPlusPlus/xmod/forestry/Forestry.java127
-rw-r--r--src/Java/gtPlusPlus/xmod/forestry/trees/ForestryLeaf.java160
-rw-r--r--src/Java/gtPlusPlus/xmod/forestry/trees/ForestrySapling.java55
-rw-r--r--src/Java/gtPlusPlus/xmod/forestry/trees/TreefarmManager.java20
-rw-r--r--src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_Cable.java2
-rw-r--r--src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_SuperConductor.java2
-rw-r--r--src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMetaPipeEntityBase_Cable.java2
-rw-r--r--src/Java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/GregtechMetaTileEntityTreeFarm.java220
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/api/EmptyReplacement.java20
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/api/HarvestType.java56
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/api/IFactoryFruit.java106
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/api/IFactoryHarvestable.java104
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java94
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/api/ReplacementBlock.java135
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableShearable.java50
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableStandard.java71
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableTreeLeaves.java33
-rw-r--r--src/Java/powercrystals/minefactoryreloaded/farmables/plantables/PlantableStandard.java116
31 files changed, 1665 insertions, 72 deletions
diff --git a/src/Java/api/cofh/energy/EnergyStorage.java b/src/Java/cofh/energy/EnergyStorage.java
index a6ec363709..e48fc7b8ac 100644
--- a/src/Java/api/cofh/energy/EnergyStorage.java
+++ b/src/Java/cofh/energy/EnergyStorage.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraft.nbt.NBTTagCompound;
diff --git a/src/Java/api/cofh/energy/IEnergyConnection.java b/src/Java/cofh/energy/IEnergyConnection.java
index 6351f7702d..96055c2282 100644
--- a/src/Java/api/cofh/energy/IEnergyConnection.java
+++ b/src/Java/cofh/energy/IEnergyConnection.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraftforge.common.util.ForgeDirection;
diff --git a/src/Java/api/cofh/energy/IEnergyContainerItem.java b/src/Java/cofh/energy/IEnergyContainerItem.java
index 1f2b8c3c52..1cce2619ae 100644
--- a/src/Java/api/cofh/energy/IEnergyContainerItem.java
+++ b/src/Java/cofh/energy/IEnergyContainerItem.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraft.item.ItemStack;
diff --git a/src/Java/api/cofh/energy/IEnergyHandler.java b/src/Java/cofh/energy/IEnergyHandler.java
index 9d3385c4c0..89ea0b4eb7 100644
--- a/src/Java/api/cofh/energy/IEnergyHandler.java
+++ b/src/Java/cofh/energy/IEnergyHandler.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraftforge.common.util.ForgeDirection;
diff --git a/src/Java/api/cofh/energy/IEnergyProvider.java b/src/Java/cofh/energy/IEnergyProvider.java
index ace09db65e..1f92549c53 100644
--- a/src/Java/api/cofh/energy/IEnergyProvider.java
+++ b/src/Java/cofh/energy/IEnergyProvider.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraftforge.common.util.ForgeDirection;
diff --git a/src/Java/api/cofh/energy/IEnergyReceiver.java b/src/Java/cofh/energy/IEnergyReceiver.java
index 68b071b028..537b4679d5 100644
--- a/src/Java/api/cofh/energy/IEnergyReceiver.java
+++ b/src/Java/cofh/energy/IEnergyReceiver.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraftforge.common.util.ForgeDirection;
diff --git a/src/Java/api/cofh/energy/IEnergyStorage.java b/src/Java/cofh/energy/IEnergyStorage.java
index bf999f8670..d105df55c1 100644
--- a/src/Java/api/cofh/energy/IEnergyStorage.java
+++ b/src/Java/cofh/energy/IEnergyStorage.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
public abstract interface IEnergyStorage
{
diff --git a/src/Java/api/cofh/energy/ItemEnergyContainer.java b/src/Java/cofh/energy/ItemEnergyContainer.java
index f4da898919..697532abe3 100644
--- a/src/Java/api/cofh/energy/ItemEnergyContainer.java
+++ b/src/Java/cofh/energy/ItemEnergyContainer.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
diff --git a/src/Java/api/cofh/energy/TileEnergyHandler.java b/src/Java/cofh/energy/TileEnergyHandler.java
index 606b0ba44b..24cd3c0e34 100644
--- a/src/Java/api/cofh/energy/TileEnergyHandler.java
+++ b/src/Java/cofh/energy/TileEnergyHandler.java
@@ -1,4 +1,4 @@
-package api.cofh.energy;
+package cofh.energy;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
diff --git a/src/Java/cofh/mod/BaseMod.java b/src/Java/cofh/mod/BaseMod.java
new file mode 100644
index 0000000000..7ab858eabd
--- /dev/null
+++ b/src/Java/cofh/mod/BaseMod.java
@@ -0,0 +1,284 @@
+package cofh.mod;
+
+import cofh.mod.updater.IUpdatableMod;
+import cofh.mod.updater.ModRange;
+import cofh.mod.updater.ModVersion;
+import com.google.common.base.Strings;
+import cpw.mods.fml.common.FMLCommonHandler;
+import cpw.mods.fml.common.ICrashCallable;
+import cpw.mods.fml.common.Mod;
+import cpw.mods.fml.common.ModContainer;
+import cpw.mods.fml.common.ObfuscationReflectionHelper;
+import cpw.mods.fml.common.network.NetworkCheckHandler;
+import cpw.mods.fml.common.registry.LanguageRegistry;
+import cpw.mods.fml.common.versioning.InvalidVersionSpecificationException;
+import cpw.mods.fml.relauncher.FMLLaunchHandler;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.resources.IReloadableResourceManager;
+import net.minecraft.client.resources.IResource;
+import net.minecraft.client.resources.IResourceManager;
+import net.minecraft.client.resources.IResourceManagerReloadListener;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StringTranslate;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.helpers.Loader;
+import org.apache.logging.log4j.spi.AbstractLogger;
+
+public abstract class BaseMod implements IUpdatableMod {
+
+ protected File _configFolder;
+ protected final String _modid;
+ protected final Logger _log;
+
+ protected BaseMod(Logger log) {
+
+ String name = getModId();
+ _modid = name.toLowerCase(Locale.US);
+ _log = log;
+ init();
+ }
+
+ protected BaseMod() {
+
+ String name = getModId();
+ _modid = name.toLowerCase(Locale.US);
+ _log = LogManager.getLogger(name);
+ init();
+ }
+
+ private void init() {
+
+ ModContainer container = cpw.mods.fml.common.Loader.instance().activeModContainer();
+ if (container.getSource().isDirectory()) {
+ FMLCommonHandler.instance().registerCrashCallable(new CrashCallable("Loaded from a directory"));
+ } else {
+ try {
+ JarFile jar = new JarFile(container.getSource());
+ ZipEntry file = jar.getEntry("vers.prop");
+ if (file != null) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(jar.getInputStream(file)));
+ String data = reader.readLine();
+ FMLCommonHandler.instance().registerCrashCallable(new CrashCallable(data));
+ } else {
+ FMLCommonHandler.instance().registerCrashCallable(new CrashCallable("Lacking version information."));
+ }
+ jar.close();
+ } catch (IOException e) {
+ FMLCommonHandler.instance().registerCrashCallable(new CrashCallable("Error reading version information." + e.getMessage()));
+ }
+ }
+ }
+
+ @NetworkCheckHandler
+ public final boolean networkCheck(Map<String, String> remoteVersions, Side side) throws InvalidVersionSpecificationException {
+
+ if (!requiresRemoteFrom(side)) {
+ return true;
+ }
+ Mod mod = getClass().getAnnotation(Mod.class);
+ String _modid = mod.modid();
+ if (!remoteVersions.containsKey(_modid)) {
+ return false;
+ }
+ String remotes = mod.acceptableRemoteVersions();
+ if (!"*".equals(remotes)) {
+
+ String remote = remoteVersions.get(_modid);
+ if (Strings.isNullOrEmpty(remotes)) {
+ return getModVersion().equalsIgnoreCase(remote);
+ }
+ return ModRange.createFromVersionSpec(_modid, remotes).containsVersion(new ModVersion(_modid, remote));
+ }
+ return true;
+ }
+
+ protected boolean requiresRemoteFrom(Side side) {
+
+ return true;
+ }
+
+ protected String getConfigBaseFolder() {
+
+ String base = getClass().getPackage().getName();
+ int i = base.indexOf('.');
+ if (i >= 0) {
+ return base.substring(0, i);
+ }
+ return "";
+ }
+
+ protected void setConfigFolderBase(File folder) {
+
+ _configFolder = new File(folder, getConfigBaseFolder() + "/" + _modid + "/");
+ }
+
+ protected File getConfig(String name) {
+
+ return new File(_configFolder, name + ".cfg");
+ }
+
+ protected File getClientConfig() {
+
+ return getConfig("client");
+ }
+
+ protected File getCommonConfig() {
+
+ return getConfig("common");
+ }
+
+ protected String getAssetDir() {
+
+ return _modid;
+ }
+
+ @Override
+ public Logger getLogger() {
+
+ return _log;
+ }
+
+ private void loadLanguageFile(Properties lang, InputStream stream) throws Throwable {
+
+ InputStreamReader is = new InputStreamReader(stream, "UTF-8");
+
+ Properties langPack = new Properties();
+ langPack.load(is);
+
+ lang.putAll(langPack);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private void loadLanguageFile(String lang, Properties langPack) {
+
+ HashMap<String, String> parsedLangFile = new HashMap<String, String>();
+ parsedLangFile.putAll((Map) langPack); // lovely casting hack
+
+ LanguageRegistry.instance().injectLanguage(lang.intern(), parsedLangFile);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected void loadLang() {
+
+ if (FMLLaunchHandler.side() == Side.CLIENT) {
+ try {
+ loadClientLang();
+ return;
+ } catch (Throwable t) {
+ _log.error(AbstractLogger.CATCHING_MARKER, "???", t);
+ }
+ }
+
+ String path = "assets/" + getAssetDir() + "/language/";
+ String lang = "en_US";
+ try (InputStream is = Loader.getResource(path + lang + ".lang", null).openStream();) {
+ Properties langPack = new Properties();
+ loadLanguageFile(langPack, is);
+
+ StringTranslate i = ObfuscationReflectionHelper.getPrivateValue(StringTranslate.class, null, "instance", "field_74817_a");
+ Map m = ObfuscationReflectionHelper.getPrivateValue(StringTranslate.class, i, "field_74816_c", "languageList");
+ m.putAll(langPack);
+ } catch (Throwable t) {
+ _log.catching(Level.INFO, t);
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ private void loadClientLang() {
+
+ IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
+ manager.registerReloadListener(new LangManager(manager));
+ }
+
+ @SideOnly(Side.CLIENT)
+ private class LangManager implements IResourceManagerReloadListener {
+
+ private final String _path;
+
+ public LangManager(IResourceManager manager) {
+
+ _path = getAssetDir() + ":language/";
+ onResourceManagerReload(manager);
+ }
+
+ @Override
+ public void onResourceManagerReload(IResourceManager manager) {
+
+ String l = null;
+ try {
+ l = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode();
+ } catch (Throwable t) {
+ _log.catching(Level.WARN, t);
+ }
+
+ for (String lang : Arrays.asList("en_US", l)) {
+ if (lang != null) {
+ Properties langPack = new Properties();
+ try {
+ List<IResource> files = manager.getAllResources(new ResourceLocation(_path + lang + ".lang"));
+ for (IResource file : files) {
+ if (file.getInputStream() == null) {
+ _log.warn("A resource pack defines an entry for language '" + lang + "' but the InputStream is null.");
+ continue;
+ }
+ try {
+ loadLanguageFile(langPack, file.getInputStream());
+ } catch (Throwable t) {
+ _log.warn(AbstractLogger.CATCHING_MARKER, "A resource pack has a file for language '" + lang + "' but the file is invalid.", t);
+ }
+ }
+ } catch (Throwable t) {
+ _log.info(AbstractLogger.CATCHING_MARKER, "No language data for '" + lang + "'", t);
+ }
+ loadLanguageFile(lang, langPack);
+ }
+ }
+
+ Minecraft.getMinecraft().getLanguageManager().onResourceManagerReload(manager);
+ }
+ }
+
+ private class CrashCallable implements ICrashCallable {
+
+ private final String data;
+
+ private CrashCallable(String data) {
+
+ this.data = data;
+ }
+
+ @Override
+ public String call() throws Exception {
+
+ return data;
+ }
+
+ @Override
+ public String getLabel() {
+
+ return getModId();
+ }
+
+ }
+
+}
diff --git a/src/Java/cofh/mod/ChildMod.java b/src/Java/cofh/mod/ChildMod.java
new file mode 100644
index 0000000000..b07c35a8a1
--- /dev/null
+++ b/src/Java/cofh/mod/ChildMod.java
@@ -0,0 +1,17 @@
+package cofh.mod;
+
+import cpw.mods.fml.common.Mod;
+
+
+public @interface ChildMod {
+
+ /**
+ * The {@link Mod} instance defining this ChildMod
+ */
+ Mod[] mod();
+
+ /**
+ * The parent {@link Mod}
+ */
+ String parent();
+}
diff --git a/src/Java/cofh/mod/ChildModContainer.java b/src/Java/cofh/mod/ChildModContainer.java
new file mode 100644
index 0000000000..994fde93a8
--- /dev/null
+++ b/src/Java/cofh/mod/ChildModContainer.java
@@ -0,0 +1,43 @@
+package cofh.mod;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.eventbus.EventBus;
+
+import cpw.mods.fml.common.*;
+import cpw.mods.fml.common.discovery.ModCandidate;
+import cpw.mods.fml.common.versioning.ArtifactVersion;
+
+public class ChildModContainer extends FMLModContainer {
+
+ private final String parent;
+
+ @SuppressWarnings("unchecked")
+ public ChildModContainer(String className, ModCandidate container, Map<String, Object> modDescriptor) {
+
+ super(className, container, (Map<String, Object>)((List<Object>)modDescriptor.get("mod")).get(0));
+
+ parent = (String) modDescriptor.get("parent");
+ }
+
+ @Override
+ public boolean registerBus(EventBus bus, LoadController controller) {
+
+ Map<String, ModContainer> list = Loader.instance().getIndexedModList();
+ l: {
+ if (!list.containsKey(parent)) {
+ break l;
+ }
+ for (ArtifactVersion info : this.getMetadata().dependencies) {
+ if (!list.containsKey(info.getLabel()) && !ModAPIManager.INSTANCE.hasAPI(info.getLabel())) {
+ break l;
+ }
+ }
+ return super.registerBus(bus, controller);
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/Java/gtPlusPlus/core/item/general/RF2EU_Battery.java b/src/Java/gtPlusPlus/core/item/general/RF2EU_Battery.java
index 592b41b0e9..146af86302 100644
--- a/src/Java/gtPlusPlus/core/item/general/RF2EU_Battery.java
+++ b/src/Java/gtPlusPlus/core/item/general/RF2EU_Battery.java
@@ -8,7 +8,7 @@ import ic2.api.item.*;
import java.util.List;
-import api.cofh.energy.ItemEnergyContainer;
+import cofh.energy.ItemEnergyContainer;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
diff --git a/src/Java/gtPlusPlus/xmod/forestry/Forestry.java b/src/Java/gtPlusPlus/xmod/forestry/Forestry.java
new file mode 100644
index 0000000000..b21d9a154d
--- /dev/null
+++ b/src/Java/gtPlusPlus/xmod/forestry/Forestry.java
@@ -0,0 +1,127 @@
+package gtPlusPlus.xmod.forestry;
+
+import static cpw.mods.fml.common.registry.GameRegistry.findBlock;
+import static cpw.mods.fml.common.registry.GameRegistry.findItem;
+import gtPlusPlus.core.lib.CORE;
+import gtPlusPlus.core.util.Utils;
+import gtPlusPlus.xmod.forestry.trees.ForestryLeaf;
+import gtPlusPlus.xmod.forestry.trees.ForestrySapling;
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+
+import cofh.mod.ChildMod;
+import cpw.mods.fml.common.*;
+import cpw.mods.fml.common.Mod.CustomProperty;
+import cpw.mods.fml.common.Mod.EventHandler;
+import cpw.mods.fml.common.event.FMLInitializationEvent;
+import cpw.mods.fml.common.event.FMLPostInitializationEvent;
+
+@ChildMod(parent = CORE.MODID, mod = @Mod(modid = "Gregtech++|CompatForestry",
+name = "GT++ Compat: Forestry",
+version = CORE.VERSION,
+dependencies = "after:Miscutils;after:Forestry",
+customProperties = @CustomProperty(k = "cofhversion", v = "true")))
+public class Forestry {
+
+ private static final String name = "Forestry";
+
+ @EventHandler
+ public void load(FMLInitializationEvent e) {
+
+ try {
+ initForestry();
+ } catch (Throwable $) {
+ ModContainer This = FMLCommonHandler.instance().findContainerFor(this);
+ LogManager.getLogger(This.getModId()).log(Level.ERROR, "There was a problem loading " + This.getName(), $);
+ }
+ }
+
+ private static void initForestry() {
+
+ Item item;
+
+ item = findItem(name, "sapling");
+ Block block = findBlock(name, "saplingGE");
+ if (item != null && block != null) {
+ ForestrySapling sapling = new ForestrySapling(item, block);
+ //MFRRegistry.registerPlantable(sapling);
+ //MFRRegistry.registerFertilizable(sapling);
+ } else
+ //Utils.LOG_WARNING("Forestry sapling/block null!");
+
+ block = findBlock(name, "soil");
+ if (block != null) {
+ //ForestryBogEarth bog = new ForestryBogEarth(block);
+ //MFRRegistry.registerPlantable(bog);
+ //MFRRegistry.registerFertilizable(bog);
+ //MFRRegistry.registerHarvestable(bog);
+ //MFRRegistry.registerFruit(bog);
+ } else
+ //Utils.LOG_WARNING("Forestry bog earth null!");
+
+ for (int i = 1; true; ++i) {
+ block = findBlock(name, "log" + i);
+ l: if (block == null) {
+ if (i > 1)
+ Utils.LOG_WARNING("Forestry logs null at " + i + ".");
+ else {
+ block = findBlock(name, "logs");
+ if (block != null) {
+ break l;
+ }
+ Utils.LOG_WARNING("Forestry logs null!");
+ }
+ break;
+ }
+ //MFRRegistry.registerHarvestable(new HarvestableWood(block));
+ //MFRRegistry.registerFruitLogBlock(block);
+ }
+
+ for (int i = 1; true; ++i) {
+ block = findBlock(name, "fireproofLog" + i);
+ l: if (block == null) {
+ if (i > 1)
+ Utils.LOG_WARNING("Forestry logs null at " + i + ".");
+ else {
+ block = findBlock(name, "logsFireproof");
+ if (block != null) {
+ break l;
+ }
+ Utils.LOG_WARNING("Forestry logs null!");
+ }
+ break;
+ }
+ //MFRRegistry.registerHarvestable(new HarvestableWood(block));
+ //MFRRegistry.registerFruitLogBlock(block);
+ }
+
+ block = findBlock(name, "leaves");
+ if (block != null) {
+ ForestryLeaf leaf = new ForestryLeaf(block);
+ //MFRRegistry.registerFertilizable(leaf);
+ //MFRRegistry.registerHarvestable(leaf);
+ //MFRRegistry.registerFruit(leaf);
+ } else
+ Utils.LOG_WARNING("Forestry leaves null!");
+
+ block = findBlock(name, "pods");
+ item = findItem(name, "grafterProven");
+ if (block != null) {
+ //ForestryPod pod = new ForestryPod(block, item);
+ //MFRRegistry.registerFertilizable(pod);
+ //MFRRegistry.registerHarvestable(pod);
+ //MFRRegistry.registerFruit(pod);
+ } else
+ Utils.LOG_WARNING("Forestry pods null!");
+ }
+
+ @EventHandler
+ public static void postInit(FMLPostInitializationEvent e) {
+ //MFRRegistry.registerLiquidDrinkHandler("bioethanol", new DrinkHandlerBiofuel());
+ //TileEntityUnifier.updateUnifierLiquids();
+ }
+
+}
diff --git a/src/Java/gtPlusPlus/xmod/forestry/trees/ForestryLeaf.java b/src/Java/gtPlusPlus/xmod/forestry/trees/ForestryLeaf.java
new file mode 100644
index 0000000000..e2550f4643
--- /dev/null
+++ b/src/Java/gtPlusPlus/xmod/forestry/trees/ForestryLeaf.java
@@ -0,0 +1,160 @@
+package gtPlusPlus.xmod.forestry.trees;
+
+import java.util.*;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import powercrystals.minefactoryreloaded.api.*;
+import powercrystals.minefactoryreloaded.farmables.harvestables.HarvestableTreeLeaves;
+import forestry.api.arboriculture.*;
+import forestry.api.genetics.*;
+
+
+public class ForestryLeaf extends HarvestableTreeLeaves implements IFactoryFruit
+{
+ private ITreeRoot root;
+ private ReplacementBlock repl;
+ protected Item _item;
+
+ public ForestryLeaf(Block block)
+ {
+ super(block);
+ root = (ITreeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees");
+ repl = EmptyReplacement.INSTANCE;
+ _item = Item.getItemFromBlock(block);
+ }
+
+ @Override
+ public boolean canBePicked(World world, int x, int y, int z)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if (te instanceof IFruitBearer)
+ {
+ IFruitBearer fruit = (IFruitBearer)te;
+ return fruit.getRipeness() >= 0.99f;
+ }
+ return false;
+ }
+
+ public boolean canFertilize(World world, int x, int y, int z)
+ {
+ return !canBePicked(world, x, y, z);
+ }
+
+ public boolean fertilize(World world, Random rand, int x, int y, int z)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if (te instanceof IFruitBearer)
+ {
+ IFruitBearer fruit = (IFruitBearer)te;
+ fruit.addRipeness(1f);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public ReplacementBlock getReplacementBlock(World world, int x, int y, int z)
+ {
+ return repl;
+ }
+
+ @Override
+ public void prePick(World world, int x, int y, int z)
+ {
+ }
+
+ @Override // HARVESTER
+ public List<ItemStack> getDrops(World world, Random rand, Map<String, Boolean> settings, int x, int y, int z)
+ {
+ ITree tree = getTree(world, x, y, z);
+ if (tree == null)
+ return null;
+
+ ArrayList<ItemStack> prod = new ArrayList<ItemStack>();
+
+ float modifier = 1f;
+ if (settings.get("silkTouch") == Boolean.TRUE)
+ {
+ ItemStack item = new ItemStack(_item);
+ NBTTagCompound tag = new NBTTagCompound();
+ tree.writeToNBT(tag);
+ item.setTagCompound(tag);
+ prod.add(item);
+ }
+ else
+ {
+ boolean hasMate = tree.getMate() != null;
+ for (ITree s : getSaplings(tree, world, x, y, z, modifier))
+ if (s != null) {
+ if ((hasMate && !s.isGeneticEqual(tree)) || rand.nextInt(32) == 0)
+ if (rand.nextBoolean())
+ prod.add(root.getMemberStack(s, EnumGermlingType.POLLEN.ordinal()));
+
+ prod.add(root.getMemberStack(s, EnumGermlingType.SAPLING.ordinal()));
+ }
+
+ getFruits(world, x, y, z, tree, prod);
+ }
+
+ return prod;
+ }
+
+
+ private static ITree[] getSaplings(ITree tree, World world, int x, int y, int z, float modifier) {
+ return tree.getSaplings(world, null, x, y, z, modifier);
+ }
+
+ @Override // FRUIT PICKER
+ public List<ItemStack> getDrops(World world, Random rand, int x, int y, int z)
+ {
+ ITree tree = getTree(world, x, y, z);
+ if (tree == null)
+ return null;
+
+ ArrayList<ItemStack> prod = new ArrayList<ItemStack>();
+ getFruits(world, x, y, z, tree, prod);
+ return prod;
+ }
+
+ private ITree getTree(World world, int x, int y, int z)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if (te instanceof IPollinatable) {
+ IIndividual t = ((IPollinatable)te).getPollen();
+ if (t instanceof ITree)
+ return (ITree)t;
+ }
+ return null;
+ }
+
+ private void getFruits(World world, int x, int y, int z, ITree tree, ArrayList<ItemStack> prod)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if (te instanceof IFruitBearer)
+ {
+ IFruitBearer fruit = (IFruitBearer)te;
+ if (fruit.hasFruit())
+ {
+ //int period = tree.getGenome().getFruitProvider().getRipeningPeriod();
+ //ItemStack[] o = tree.produceStacks(world, x, y, z, (int)(fruit.getRipeness() * period + 0.1f));
+ prod.addAll(fruit.pickFruit(null));
+ }
+ }
+ }
+
+ @Override
+ public void postPick(World world, int x, int y, int z)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if (te instanceof IFruitBearer)
+ {
+ IFruitBearer fruit = (IFruitBearer)te;
+ fruit.addRipeness(-fruit.getRipeness());
+ }
+ }
+}
diff --git a/src/Java/gtPlusPlus/xmod/forestry/trees/ForestrySapling.java b/src/Java/gtPlusPlus/xmod/forestry/trees/ForestrySapling.java
new file mode 100644
index 0000000000..7c81ea0928
--- /dev/null
+++ b/src/Java/gtPlusPlus/xmod/forestry/trees/ForestrySapling.java
@@ -0,0 +1,55 @@
+package gtPlusPlus.xmod.forestry.trees;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import powercrystals.minefactoryreloaded.api.ReplacementBlock;
+import powercrystals.minefactoryreloaded.farmables.plantables.PlantableStandard;
+import forestry.api.arboriculture.ITreeRoot;
+import forestry.api.genetics.AlleleManager;
+
+public class ForestrySapling extends PlantableStandard
+{
+ private ITreeRoot root;
+
+ public ForestrySapling(Item item, Block block)
+ {
+ super(item, block, WILDCARD, null);
+ root = (ITreeRoot)AlleleManager.alleleRegistry.getSpeciesRoot("rootTrees");
+ _plantedBlock = new ReplacementBlock((Block)null) {
+ @Override
+ public boolean replaceBlock(World world, int x, int y, int z, ItemStack stack) {
+ return root.plantSapling(world, root.getMember(stack), null, x, y, z);
+ }
+ };
+ }
+
+ public Block getPlant()
+ {
+ return _block;
+ }
+
+ @Override
+ public boolean canBePlantedHere(World world, int x, int y, int z, ItemStack stack)
+ {
+ if (!world.isAirBlock(x, y, z))
+ return false;
+
+ return root.getMember(stack).canStay(world, x, y, z);
+ }
+
+ public boolean canFertilize(World world, int x, int y, int z)
+ {
+ return true;
+ }
+
+ public boolean fertilize(World world, Random rand, int x, int y, int z)
+ {
+ Block block = world.getBlock(x, y, z);
+ root.getTree(world, x, y, z).getTreeGenerator(world, x, y, z, true).generate(world, rand, x, y, z);
+ return world.getBlock(x, y, z) != block;
+ }
+}
diff --git a/src/Java/gtPlusPlus/xmod/forestry/trees/TreefarmManager.java b/src/Java/gtPlusPlus/xmod/forestry/trees/TreefarmManager.java
index ba8ffd8284..8fe3f62f23 100644
--- a/src/Java/gtPlusPlus/xmod/forestry/trees/TreefarmManager.java
+++ b/src/Java/gtPlusPlus/xmod/forestry/trees/TreefarmManager.java
@@ -63,7 +63,17 @@ public class TreefarmManager {
public static boolean isWoodLog(Block log){
String tTool = log.getHarvestTool(0);
- return OrePrefixes.log.contains(new ItemStack(log, 1))&& ((tTool != null) && (tTool.equals("axe"))) || (log.getMaterial() == Material.wood);
+
+ if (log == Blocks.log || log == Blocks.log2){
+ return true;
+ }
+
+ //IC2 Rubber Tree Compat
+ if (log.getClass().getName().toLowerCase().contains("rubwood")){
+ return true;
+ }
+
+ return OrePrefixes.log.contains(new ItemStack(log, 1))&& ((tTool != null) && (tTool.equals("axe"))) || (log.getMaterial() != Material.wood) ? false : (OrePrefixes.fence.contains(new ItemStack(log, 1)) ? false : true);
}
public static boolean isLeaves(Block log){
@@ -88,7 +98,7 @@ public class TreefarmManager {
}
public static boolean isFenceBlock(Block fence){
- return (fence == Blocks.fence ? true : (fence == Blocks.fence_gate ? true : (fence == Blocks.nether_brick_fence ? true : false)));
+ return (fence == Blocks.fence ? true : (fence == Blocks.fence_gate ? true : (fence == Blocks.nether_brick_fence ? true : (OrePrefixes.fence.contains(new ItemStack(fence, 1)) ? true : false))));
}
public static boolean isAirBlock(Block air){
@@ -96,6 +106,12 @@ public class TreefarmManager {
if (air.getLocalizedName().toLowerCase().contains("air")){
return true;
}
+
+ if (air.getClass().getName().toLowerCase().contains("residual") || air.getClass().getName().toLowerCase().contains("heat")){
+ return true;
+ }
+
+ //Utils.LOG_INFO("Found "+air.getLocalizedName());
return (air == Blocks.air ? true : (air instanceof BlockAir ? true : false));
}
diff --git a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_Cable.java b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_Cable.java
index 53865da327..1e88135e94 100644
--- a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_Cable.java
+++ b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_Cable.java
@@ -17,7 +17,7 @@ import ic2.api.energy.tile.IEnergySink;
import java.util.ArrayList;
import java.util.Arrays;
-import api.cofh.energy.IEnergyReceiver;
+import cofh.energy.IEnergyReceiver;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
diff --git a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_SuperConductor.java b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_SuperConductor.java
index 8e7cc778bd..23c1f3e47f 100644
--- a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_SuperConductor.java
+++ b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GregtechMetaPipeEntity_SuperConductor.java
@@ -18,7 +18,7 @@ import ic2.api.energy.tile.IEnergySink;
import java.util.ArrayList;
import java.util.Arrays;
-import api.cofh.energy.IEnergyReceiver;
+import cofh.energy.IEnergyReceiver;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
diff --git a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMetaPipeEntityBase_Cable.java b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMetaPipeEntityBase_Cable.java
index 4daa150889..0e7d7f30da 100644
--- a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMetaPipeEntityBase_Cable.java
+++ b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMetaPipeEntityBase_Cable.java
@@ -22,7 +22,7 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
-import api.cofh.energy.IEnergyReceiver;
+import cofh.energy.IEnergyReceiver;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
diff --git a/src/Java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/GregtechMetaTileEntityTreeFarm.java b/src/Java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/GregtechMetaTileEntityTreeFarm.java
index a03e4c3952..0587c26b85 100644
--- a/src/Java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/GregtechMetaTileEntityTreeFarm.java
+++ b/src/Java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/GregtechMetaTileEntityTreeFarm.java
@@ -11,8 +11,10 @@ import gregtech.api.metatileentity.implementations.*;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.objects.GT_RenderedTexture;
import gregtech.api.util.GT_Recipe;
+import gregtech.api.util.GT_Utility;
import gtPlusPlus.core.util.Utils;
import gtPlusPlus.core.util.item.ItemUtils;
+import gtPlusPlus.core.util.math.MathUtils;
import gtPlusPlus.xmod.forestry.trees.TreefarmManager;
import gtPlusPlus.xmod.gregtech.common.blocks.textures.TexturesGtBlock;
@@ -35,6 +37,9 @@ public class GregtechMetaTileEntityTreeFarm extends GT_MetaTileEntity_MultiBlock
public ArrayList<GT_MetaTileEntity_TieredMachineBlock> mCasings = new ArrayList();
/* private */ private int treeCheckTicks = 0;
+ /* private */ private int plantSaplingTicks = 0;
+ /* private */ private int cleanupTicks = 0;
+ /* private */ private boolean canChop = false;
public GregtechMetaTileEntityTreeFarm(final int aID, final String aName, final String aNameRegional) {
super(aID, aName, aNameRegional);
@@ -275,44 +280,83 @@ public class GregtechMetaTileEntityTreeFarm extends GT_MetaTileEntity_MultiBlock
//Tree Manager
+ private void tickTrees(){
+ if (treeCheckTicks > 200){
+ treeCheckTicks = 0;
+ }
+ else {
+ treeCheckTicks++;
+ }
+ }
+
+ private void tickSaplings(){
+ if (plantSaplingTicks > 200){
+ plantSaplingTicks = 0;
+ }
+ else {
+ plantSaplingTicks++;
+ }
+ }
+
+ private void tickCleanup(){
+ if (cleanupTicks > 600){
+ cleanupTicks = 0;
+ }
+ else {
+ cleanupTicks++;
+ }
+ }
+
+ private void tickHandler(){
+ //Count Sapling Timer
+ tickSaplings();
+ //Count Tree Cutting Timer
+ tickTrees();
+ //Tick Cleanup script Timer.
+ tickCleanup();
+ }
+
+
@Override
public void onPostTick(final IGregTechTileEntity aBaseMetaTileEntity, final long aTick) {
if (aBaseMetaTileEntity.isServerSide()) {
-
- //Check Inventory slots [1]
+ //Check Inventory slots [1] - Find a valid Buzzsaw Blade or a Saw
try {
Utils.LOG_INFO(mInventory[1].getDisplayName());
} catch (NullPointerException t){}
- //Update Tick Timer Last - Do Not move up the call stack
- if (treeCheckTicks > 100){
- treeCheckTicks = 0;
- }
- else {
- treeCheckTicks++;
- }
-
- //Set Machine State
- if (treeCheckTicks == 100){
- mMachine = checkMachine(aBaseMetaTileEntity, mInventory[1]);
-
- //If Machine can work and it's only one of two times a second this will tick, tick.
- if (mMachine){
+ //If Machine can work and it's only once every 5 seconds this will tick.
+ if (mMachine){
+ //Set Machine State
+ if (treeCheckTicks == 200){
+ //mMachine = checkMachine(aBaseMetaTileEntity, mInventory[1]);
Utils.LOG_INFO("Looking For Trees - Serverside | "+treeCheckTicks);
+ //Find wood to Cut
findLogs(aBaseMetaTileEntity);
-
- cleanUp(aBaseMetaTileEntity);
-
+ }
+ }
+ else {
+ if (plantSaplingTicks == 100){
+ Utils.LOG_INFO("Looking For space to plant saplings - Serverside | "+plantSaplingTicks);
+ //Plant Some Saplings
plantSaplings(aBaseMetaTileEntity);
-
+ }
+ else if (plantSaplingTicks == 200){
+ Utils.LOG_INFO("Looking For Saplings to grow - Serverside | "+plantSaplingTicks);
+ //Try Grow some Saplings
findSaplings(aBaseMetaTileEntity);
+ //Set can work state
+ mMachine = true;
}
- }
-
-
-
-
+ }
+ //Call Cleanup Task last, before ticking.
+ if (cleanupTicks == 600){
+ Utils.LOG_INFO("Looking For rubbish to cleanup - Serverside | "+cleanupTicks);
+ cleanUp(aBaseMetaTileEntity);
+ }
+ //Tick TE
+ tickHandler();
}
//Client Side - do nothing
@@ -377,6 +421,7 @@ public class GregtechMetaTileEntityTreeFarm extends GT_MetaTileEntity_MultiBlock
}
}
}
+ mMachine = false;
if (logsCut > 0)
cleanUp(aBaseMetaTileEntity);
//Utils.LOG_INFO("general failure | maybe there is no logs, not an error. | cut:"+logsCut );
@@ -444,60 +489,98 @@ public class GregtechMetaTileEntityTreeFarm extends GT_MetaTileEntity_MultiBlock
for (int j = -7; j <= 7; j++) {
int h = 1;
- if (TreefarmManager.isAirBlock(aBaseMetaTileEntity.getBlockOffset(xDir + i, h, zDir + j))){
- for (ItemStack n : r){
- if (n != null){
- if (OrePrefixes.sapling.contains(n) || n.getDisplayName().toLowerCase().contains("sapling")){
- Utils.LOG_INFO(""+n.getDisplayName());
-
- int posX, posY, posZ;
- posX = aBaseMetaTileEntity.getXCoord()+xDir+i;
- posY = aBaseMetaTileEntity.getYCoord()+h;
- posZ = aBaseMetaTileEntity.getZCoord()+zDir+j;
-
- //Works for everything but forestry saplings - TODO
- Block saplingToPlace = Block.getBlockFromItem(n.getItem());
-
- //If sapling block is not null
- if (saplingToPlace != null){
- //Plant Sapling
- world.setBlock(posX, posY, posZ, saplingToPlace);
- world.setBlockMetadataWithNotify(posX, posY, posZ, n.getItemDamage(), 4);
- //Deplete Input stack
- depleteInput(n);
+ if ((i != -7 && i != 7) && (j != -7 && j != 7)) {
+ if (TreefarmManager.isAirBlock(aBaseMetaTileEntity.getBlockOffset(xDir + i, h, zDir + j))){
+ //Utils.LOG_INFO("Found air");
+ if (r.size() > 0){
+ Utils.LOG_INFO("r was not null. "+r.size());
+ for (ItemStack n : r){
+ Utils.LOG_INFO("found "+n.getDisplayName());
+ if (OrePrefixes.sapling.contains(n) || n.getDisplayName().toLowerCase().contains("sapling")){
+ //Utils.LOG_INFO(""+n.getDisplayName());
+
+ int posX, posY, posZ;
+ posX = aBaseMetaTileEntity.getXCoord()+xDir+i;
+ posY = aBaseMetaTileEntity.getYCoord()+h;
+ posZ = aBaseMetaTileEntity.getZCoord()+zDir+j;
+
+ //Works for everything but forestry saplings - TODO
+ Block saplingToPlace;
+
+ if (n.getClass().getName().toLowerCase().contains("forestry")){
+ Utils.LOG_INFO("It's a forestry sapling, trying magic.");
+ saplingToPlace = Block.getBlockFromItem(ItemUtils.getItem("Forestry:saplingGE"));
+
+ }
+ else {
+ saplingToPlace = Block.getBlockFromItem(n.getItem());
+ }
+
+
+ //If sapling block is not null
+ if (saplingToPlace != null){
+ Utils.LOG_INFO("Placing Sapling Block.");
+ //Plant Sapling
+ world.setBlock(posX, posY, posZ, saplingToPlace);
+ world.setBlockMetadataWithNotify(posX, posY, posZ, n.getItemDamage(), 4);
+ //Deplete Input stack
+ depleteInput(n);
+ r = getStoredInputs();
+ break;
+ }
+ Utils.LOG_INFO(n.getDisplayName()+" did not have a valid block.");
+ }
+ else {
+ Utils.LOG_INFO("item was not a sapling");
}
}
}
+ else{
+ Utils.LOG_INFO("Input stack empty or null");
+ }
}
- }
+ else {
+ Utils.LOG_INFO("No space for sapling, no air.");
+ }
+ }
+
}
}
Utils.LOG_INFO("Tried to grow saplings: | "+saplings );
return true;
}
- private Block findAirForSaplingToGrow(){
- return null;
- }
-
private boolean cutLog(final World world, final int x, final int y, final int z){
Utils.LOG_INFO("Cutting Log");
try {
//Get Log.
final Block block = world.getBlock(x, y, z);
//Add the stack to the bus.
- addOutput(ItemUtils.getSimpleStack(block));
- //Update bus contents.
- updateSlots();
- //Remove drop that was added to the bus.
- world.setBlockToAir(x, y, z);
- return true;
+
+ ItemStack outputStack = ItemUtils.getSimpleStack(block);
+ if (outputStack != null){
+ Utils.LOG_INFO("Adding 1x "+outputStack.getDisplayName());
+ addOutput(outputStack);
+ //Update bus contents.
+ updateSlots();
+ //Remove drop that was added to the bus.
+ world.setBlockToAir(x, y, z);
+ return true;
+ }
+
} catch (NullPointerException e){}
return false;
}
public static boolean applyBonemeal(World world, int intX, int intY, int intZ){
Block block = world.getBlock(intX, intY, intZ);
+ int chance = MathUtils.randInt(0, 10);
+
+ //Random Growth
+ if (chance < 8){
+ return false;
+ }
+
EntityPlayer player = FakePlayerFactory.getMinecraft((WorldServer)world);
if (!world.isRemote){
if (enableTreeFarmerParticles){
@@ -586,4 +669,27 @@ public class GregtechMetaTileEntityTreeFarm extends GT_MetaTileEntity_MultiBlock
return getSides(aColor);
}
+
+ public boolean depleteInputEx(ItemStack aStack) {
+ if (GT_Utility.isStackInvalid(aStack)) return false;
+
+ Utils.LOG_INFO("Taking one sapling away from in input bus.");
+
+ for (GT_MetaTileEntity_Hatch_InputBus tHatch : this.mInputBusses) {
+ tHatch.mRecipeMap = getRecipeMap();
+ if (isValidMetaTileEntity(tHatch)) {
+ for (int i = tHatch.getBaseMetaTileEntity().getSizeInventory() - 1; i >= 0; --i) {
+ if ((!(GT_Utility.areStacksEqual(aStack, tHatch.getBaseMetaTileEntity().getStackInSlot(i)))) || (tHatch.getBaseMetaTileEntity().getStackInSlot(0).stackSize < aStack.stackSize)){
+ continue;
+ }
+ tHatch.getBaseMetaTileEntity().decrStackSize(0,1);
+ return true;
+ }
+ }
+
+ }
+
+ return false;
+ }
+
} \ No newline at end of file
diff --git a/src/Java/powercrystals/minefactoryreloaded/api/EmptyReplacement.java b/src/Java/powercrystals/minefactoryreloaded/api/EmptyReplacement.java
new file mode 100644
index 0000000000..ef3fd46bb2
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/api/EmptyReplacement.java
@@ -0,0 +1,20 @@
+package powercrystals.minefactoryreloaded.api;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+
+public class EmptyReplacement extends ReplacementBlock
+{
+ public static final EmptyReplacement INSTANCE = new EmptyReplacement();
+
+ public EmptyReplacement()
+ {
+ super((Block)null);
+ }
+
+ @Override
+ public boolean replaceBlock(World world, int x, int y, int z, ItemStack stack) {
+ return true;
+ }
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/api/HarvestType.java b/src/Java/powercrystals/minefactoryreloaded/api/HarvestType.java
new file mode 100644
index 0000000000..85ef23835c
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/api/HarvestType.java
@@ -0,0 +1,56 @@
+package powercrystals.minefactoryreloaded.api;
+
+/**
+ * Determines what algorithm the Harvester uses when it encounters this
+ * IFactoryHarvestable in the world.
+ *
+ * @author PowerCrystals
+ */
+public enum HarvestType {
+
+ /**
+ * Just break the single block - no special action needed. e.g. Carrots,
+ * flowers, wheat.
+ */
+ Normal,
+ /**
+ * Search for harvestable blocks adjacent to this block but leave this
+ * block. e.g. Pumpkin, melon
+ */
+ Gourd,
+ /**
+ * Search for identical blocks above.
+ */
+ Column,
+ /**
+ * Search for identical blocks above but leave the bottom one for the
+ * future. e.g. Cactus, sugarcane.
+ */
+ LeaveBottom,
+ /**
+ * This block is the base of a tree and the harvester should enter
+ * tree-cutting mode.
+ */
+ Tree,
+ /**
+ * This block is the base of the tree and the harvester should enter
+ * tree-cutting mode.
+ * The tree is searched for in the negative y axis instead.
+ */
+ TreeFlipped,
+ /**
+ * This block is part of a tree as above, but leaves are cut before logs.
+ * The tree is searched for in the current mode.
+ * <p>
+ * If not in tree-cutting mode, tree-cutting mode will be entered as though
+ * the type was Tree.
+ */
+ TreeLeaf,
+ /**
+ * This block is part of a tree as above, but fruits are cut before logs.
+ * e.g. cocoa
+ * The tree is not searched for.
+ */
+ TreeFruit
+
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/api/IFactoryFruit.java b/src/Java/powercrystals/minefactoryreloaded/api/IFactoryFruit.java
new file mode 100644
index 0000000000..3f956422c0
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/api/IFactoryFruit.java
@@ -0,0 +1,106 @@
+package powercrystals.minefactoryreloaded.api;
+
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+
+/**
+ * Defines a fruit entry for the Fruit Picker.
+ *
+ * @author powercrystals
+ *
+ */
+public interface IFactoryFruit {
+
+ /**
+ * @return The block this fruit has in the world.
+ */
+ public Block getPlant();
+
+ /**
+ * Used to determine if this fruit can be picked (is it ripe yet, etc)
+ *
+ * @param world
+ * The world where the fruit is being picked
+ * @param x
+ * The x-coordinate of the fruit
+ * @param y
+ * The y-coordinate of the fruit
+ * @param z
+ * The z-coordinate of the fruit
+ *
+ * @return True if the fruit can be picked
+ */
+ public boolean canBePicked(World world, int x, int y, int z);
+
+ /**
+ * @deprecated This method is no longer called. ReplacementBlock now handles
+ * interaction.
+ */
+ @Deprecated
+ public boolean breakBlock();
+
+ /**
+ * Called by the Fruit Picker to determine what block to replace the picked
+ * block with. At the time this method is called, the fruit still exists.
+ *
+ * @param world
+ * The world where the fruit is being picked
+ * @param x
+ * The x-coordinate of the fruit
+ * @param y
+ * The y-coordinate of the fruit
+ * @param z
+ * The z-coordinate of the fruit
+ *
+ * @return The block to replace the fruit block with, or null for air.
+ */
+ public ReplacementBlock getReplacementBlock(World world, int x, int y, int z);
+
+ /**
+ * Called by the Fruit Picker to determine what drops to generate. At the
+ * time this method is called, the fruit still exists.
+ *
+ * @param world
+ * The world where the fruit is being picked
+ * @param x
+ * The x-coordinate of the fruit
+ * @param y
+ * The y-coordinate of the fruit
+ * @param z
+ * The z-coordinate of the fruit
+ */
+ public List<ItemStack> getDrops(World world, Random rand, int x, int y, int z);
+
+ /**
+ * Called by the Fruit Picker after getDrops, prior to the block being
+ * replaced/removed.
+ *
+ * @param world
+ * The world where the fruit is being picked
+ * @param x
+ * The x-coordinate of the fruit
+ * @param y
+ * The y-coordinate of the fruit
+ * @param z
+ * The z-coordinate of the fruit
+ */
+ public void prePick(World world, int x, int y, int z);
+
+ /**
+ * Called by the Fruit Picker after the fruit is picked.
+ *
+ * @param world
+ * The world where the fruit is being picked
+ * @param x
+ * The x-coordinate of the fruit
+ * @param y
+ * The y-coordinate of the fruit
+ * @param z
+ * The z-coordinate of the fruit
+ */
+ public void postPick(World world, int x, int y, int z);
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/api/IFactoryHarvestable.java b/src/Java/powercrystals/minefactoryreloaded/api/IFactoryHarvestable.java
new file mode 100644
index 0000000000..5b6be99f89
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/api/IFactoryHarvestable.java
@@ -0,0 +1,104 @@
+package powercrystals.minefactoryreloaded.api;
+
+import java.util.*;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+
+/**
+ * Defines a harvestable block for the Harvester.
+ *
+ * @author PowerCrystals
+ */
+public interface IFactoryHarvestable {
+
+ /**
+ * @return The block this harvestable instance is managing.
+ */
+ public Block getPlant();
+
+ /**
+ * @return The type of harvest the Harvester should perform on this block.
+ */
+ public HarvestType getHarvestType();
+
+ /**
+ * Used to determine if the harvester should replace this block with air.
+ *
+ * @return Whether or not the Harvester should break the block when
+ * harvesting. If false, no changes will be performed by the
+ * Harvester itself.
+ */
+ public boolean breakBlock();
+
+ /**
+ * Used to determine if this crop can be harvested (is it at a stage that
+ * drops crops, etc.)
+ *
+ * @param world
+ * The world this block is in.
+ * @param harvesterSettings
+ * The harvester's current settings. Do not modify these.
+ * @param x
+ * The X coordinate of the block being harvested.
+ * @param y
+ * The Y coordinate of the block being harvested.
+ * @param z
+ * The Z coordinate of the block being harvested.
+ *
+ * @return True if this block can be harvested.
+ */
+ public boolean canBeHarvested(World world, Map<String, Boolean> harvesterSettings, int x, int y, int z);
+
+ /**
+ * @param world
+ * The world this block is in.
+ * @param rand
+ * A Random instance to use when generating drops.
+ * @param harvesterSettings
+ * The harvester's current settings. Do not modify these.
+ * @param x
+ * The X coordinate of the block being harvested.
+ * @param y
+ * The Y coordinate of the block being harvested.
+ * @param z
+ * The Z coordinate of the block being harvested.
+ *
+ * @return The drops generated by breaking this block. For a default
+ * implementation, calling Block.getDrops() is usually
+ * sufficient.
+ */
+ public List<ItemStack> getDrops(World world, Random rand, Map<String, Boolean> harvesterSettings, int x, int y, int z);
+
+ /**
+ * Called before the block is going to be harvested, after getDrops. Usually
+ * empty.
+ *
+ * @param world
+ * The world this block is in.
+ * @param x
+ * The X coordinate of the block being harvested.
+ * @param y
+ * The Y coordinate of the block being harvested.
+ * @param z
+ * The Z coordinate of the block being harvested.
+ */
+ public void preHarvest(World world, int x, int y, int z);
+
+ /**
+ * Called after the block is going to be harvested. Used to re-till soil,
+ * for example.
+ *
+ * @param world
+ * The world this block is in.
+ * @param x
+ * The X coordinate of the block being harvested.
+ * @param y
+ * The Y coordinate of the block being harvested.
+ * @param z
+ * The Z coordinate of the block being harvested.
+ */
+ public void postHarvest(World world, int x, int y, int z);
+
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java b/src/Java/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java
new file mode 100644
index 0000000000..1d620b37ed
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/api/IFactoryPlantable.java
@@ -0,0 +1,94 @@
+package powercrystals.minefactoryreloaded.api;
+
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+
+/**
+ * Defines a plantable object for use in the Planter.
+ *
+ * @author PowerCrystals
+ */
+public interface IFactoryPlantable {
+
+ /**
+ * @return The item this plantable is managing.
+ */
+ public Item getSeed();
+
+ /**
+ * @param stack
+ * The stack being planted.
+ * @param forFermenting
+ * True if this stack will be converted to biofuel
+ *
+ * @return True if this plantable can be planted (useful for metadata
+ * items).
+ */
+ public boolean canBePlanted(ItemStack stack, boolean forFermenting);
+
+ /**
+ * @param world
+ * The world instance this block or item will be placed into.
+ * @param x
+ * The destination X coordinate.
+ * @param y
+ * The destination Y coordinate.
+ * @param z
+ * The destination Z coordinate.
+ * @param stack
+ * The stack being planted.
+ *
+ * @return The block that will be placed into the world.
+ */
+ public ReplacementBlock getPlantedBlock(World world, int x, int y, int z, ItemStack stack);
+
+ /**
+ * @param world
+ * The world instance this block or item will be placed into.
+ * @param x
+ * The destination X coordinate.
+ * @param y
+ * The destination Y coordinate.
+ * @param z
+ * The destination Z coordinate.
+ * @param stack
+ * The stack being planted.
+ *
+ * @return True if this plantable can be placed at the provided coordinates.
+ */
+ public boolean canBePlantedHere(World world, int x, int y, int z, ItemStack stack);
+
+ /**
+ * Called before planting is performed. Used to till soil, for example.
+ *
+ * @param world
+ * The world instance this block or item will be placed into.
+ * @param x
+ * The destination X coordinate.
+ * @param y
+ * The destination Y coordinate.
+ * @param z
+ * The destination Z coordinate.
+ * @param stack
+ * The stack being planted.
+ */
+ public void prePlant(World world, int x, int y, int z, ItemStack stack);
+
+ /**
+ * Called after planting is performed. Usually empty.
+ *
+ * @param world
+ * The world instance this block or item will be placed into.
+ * @param x
+ * The destination X coordinate.
+ * @param y
+ * The destination Y coordinate.
+ * @param z
+ * The destination Z coordinate.
+ * @param stack
+ * The stack being planted.
+ */
+ public void postPlant(World world, int x, int y, int z, ItemStack stack);
+
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/api/ReplacementBlock.java b/src/Java/powercrystals/minefactoryreloaded/api/ReplacementBlock.java
new file mode 100644
index 0000000000..c67e8a39a2
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/api/ReplacementBlock.java
@@ -0,0 +1,135 @@
+package powercrystals.minefactoryreloaded.api;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.*;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+
+public class ReplacementBlock
+{
+ protected byte _hasMeta;
+ protected int _meta;
+ protected final Block _block;
+ protected final NBTTagCompound _tileTag;
+
+ /**
+ * Called to replace a block in the world.
+ * @param world The world object
+ * @param x The X coord
+ * @param y The Y coord
+ * @param z The Z coord
+ * @param stack The ItemStack being used to replace the block (may be null)
+ * @return True if the block was set successfully
+ */
+ public boolean replaceBlock(World world, int x, int y, int z, ItemStack stack)
+ {
+ int meta = getMeta(world, x, y, z, stack);
+ if (world.setBlock(x, y, z, _block, meta, 3))
+ {
+ if (hasTag(stack) && _block.hasTileEntity(meta))
+ {
+ TileEntity tile = world.getTileEntity(x, y, z);
+ if (tile != null)
+ tile.readFromNBT(getTag(world, x, y, z, stack));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Called to get the metadata of the replacement block in the world.
+ * @param world The world object
+ * @param x The X coord
+ * @param y The Y coord
+ * @param z The Z coord
+ * @param stack The ItemStack being used to replace the block (may be null)
+ * @return The metadata of the block
+ */
+ protected int getMeta(World world, int x, int y, int z, ItemStack stack)
+ {
+ int m = 0;
+ if (_hasMeta > 0)
+ {
+ if (_hasMeta > 1)
+ return _meta;
+ m = stack.getItemDamage();
+ Item item = stack.getItem();
+ if (item instanceof ItemBlock)
+ m = ((ItemBlock)item).getMetadata(m);
+ }
+ return m;
+ }
+
+ /**
+ * Called to set the metdata of this ReplacementBlock to a fixed value
+ * @param meta The metadata of the block
+ * @return This instance
+ */
+ public ReplacementBlock setMeta(int meta)
+ {
+ if (meta >= 0)
+ {
+ _hasMeta = 2;
+ _meta = meta;
+ }
+ return this;
+ }
+
+ /**
+ * Called to set the metdata of this ReplacementBlock to a value read from an ItemStack
+ * @param meta The metadata of the block
+ * @return This instance
+ */
+ public ReplacementBlock setMeta(boolean hasMeta)
+ {
+ _hasMeta = (byte) (hasMeta ? 1 : 0);
+ return this;
+ }
+
+ /**
+ * Called to get the NBTTagCompound a TileEntity will read its state from
+ * @param world The world object
+ * @param x The X coord
+ * @param y The Y coord
+ * @param z The Z coord
+ * @param stack The ItemStack being used to replace the block (may be null)
+ * @return The NBTTagCompound a TileEntity will read its state from
+ */
+ protected NBTTagCompound getTag(World world, int x, int y, int z, ItemStack stack)
+ {
+ return _tileTag;
+ }
+
+ /**
+ * Called to see if a TileEntity should have its state set
+ * @param stack The ItemStack being used to replace the block (may be null)
+ * @return True if the TileEntity should have its state set
+ */
+ protected boolean hasTag(ItemStack stack)
+ {
+ return _tileTag != null;
+ }
+
+ public ReplacementBlock(Item block)
+ {
+ this(Block.getBlockFromItem(block));
+ }
+
+ public ReplacementBlock(Item block, NBTTagCompound tag)
+ {
+ this(Block.getBlockFromItem(block), tag);
+ }
+
+ public ReplacementBlock(Block block)
+ {
+ this(block, null);
+ }
+
+ public ReplacementBlock(Block block, NBTTagCompound tag)
+ {
+ _block = block;
+ _tileTag = tag;
+ }
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableShearable.java b/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableShearable.java
new file mode 100644
index 0000000000..1719ae2486
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableShearable.java
@@ -0,0 +1,50 @@
+package powercrystals.minefactoryreloaded.farmables.harvestables;
+
+import java.util.*;
+
+import net.minecraft.block.Block;
+import net.minecraft.init.Items;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import net.minecraftforge.common.IShearable;
+import powercrystals.minefactoryreloaded.api.HarvestType;
+
+public class HarvestableShearable extends HarvestableStandard
+{
+ public HarvestableShearable(Block block, HarvestType harvestType)
+ {
+ super(block, harvestType);
+ }
+
+ public HarvestableShearable(Block block)
+ {
+ super(block);
+ }
+
+ @Override
+ public List<ItemStack> getDrops(World world, Random rand, Map<String, Boolean> settings, int x, int y, int z)
+ {
+ Block block = world.getBlock(x, y, z);
+ if (settings.get("silkTouch") == Boolean.TRUE)
+ {
+ if (block instanceof IShearable)
+ {
+ ItemStack stack = new ItemStack(Items.shears, 1, 0);
+ if (((IShearable)block).isShearable(stack, world, x, y, z))
+ {
+ return ((IShearable)block).onSheared(stack, world, x, y, z, 0);
+ }
+ }
+ if (Item.getItemFromBlock(block) != null)
+ {
+ ArrayList<ItemStack> drops = new ArrayList<ItemStack>();
+ int meta = block.getDamageValue(world, x, y, z);
+ drops.add(new ItemStack(block, 1, meta));
+ return drops;
+ }
+ }
+
+ return block.getDrops(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
+ }
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableStandard.java b/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableStandard.java
new file mode 100644
index 0000000000..eeab615ed8
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableStandard.java
@@ -0,0 +1,71 @@
+package powercrystals.minefactoryreloaded.farmables.harvestables;
+
+import java.util.*;
+
+import net.minecraft.block.Block;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import powercrystals.minefactoryreloaded.api.HarvestType;
+import powercrystals.minefactoryreloaded.api.IFactoryHarvestable;
+
+public class HarvestableStandard implements IFactoryHarvestable
+{
+ private Block _block;
+ private HarvestType _harvestType;
+
+ public HarvestableStandard(Block block, HarvestType harvestType)
+ {
+ if (block == Blocks.air)
+ throw new IllegalArgumentException("Passed air FactoryHarvestableStandard");
+
+ _block = block;
+ _harvestType = harvestType;
+ }
+
+ public HarvestableStandard(Block block)
+ {
+ this(block, HarvestType.Normal);
+ }
+
+ @Override
+ public Block getPlant()
+ {
+ return _block;
+ }
+
+ @Override
+ public HarvestType getHarvestType()
+ {
+ return _harvestType;
+ }
+
+ @Override
+ public boolean breakBlock()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canBeHarvested(World world, Map<String, Boolean> harvesterSettings, int x, int y, int z)
+ {
+ return true;
+ }
+
+ @Override
+ public List<ItemStack> getDrops(World world, Random rand, Map<String, Boolean> harvesterSettings, int x, int y, int z)
+ {
+ return world.getBlock(x, y, z).getDrops(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
+ }
+
+ @Override
+ public void preHarvest(World world, int x, int y, int z)
+ {
+ }
+
+ @Override
+ public void postHarvest(World world, int x, int y, int z)
+ {
+ world.notifyBlocksOfNeighborChange(x, y, z, getPlant());
+ }
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableTreeLeaves.java b/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableTreeLeaves.java
new file mode 100644
index 0000000000..eaa23bd847
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/farmables/harvestables/HarvestableTreeLeaves.java
@@ -0,0 +1,33 @@
+package powercrystals.minefactoryreloaded.farmables.harvestables;
+
+import net.minecraft.block.Block;
+import net.minecraft.world.World;
+import powercrystals.minefactoryreloaded.api.HarvestType;
+
+public class HarvestableTreeLeaves extends HarvestableShearable
+{
+ public HarvestableTreeLeaves(Block block)
+ {
+ super(block, HarvestType.TreeLeaf);
+ }
+
+ @Override
+ public void postHarvest(World world, int x, int y, int z)
+ {
+ Block id = getPlant();
+
+ notifyBlock(world, x, y - 1, z, id);
+ notifyBlock(world, x - 1, y, z, id);
+ notifyBlock(world, x + 1, y, z, id);
+ notifyBlock(world, x, y, z - 1, id);
+ notifyBlock(world, x, y, z + 1, id);
+ notifyBlock(world, x, y + 1, z, id);
+ }
+
+ protected void notifyBlock(World world, int x, int y, int z, Block id)
+ {
+ Block block = world.getBlock(x, y, z);
+ if (!block.isLeaves(world, x, y, z))
+ world.notifyBlockOfNeighborChange(x, y, z, id);
+ }
+}
diff --git a/src/Java/powercrystals/minefactoryreloaded/farmables/plantables/PlantableStandard.java b/src/Java/powercrystals/minefactoryreloaded/farmables/plantables/PlantableStandard.java
new file mode 100644
index 0000000000..022d947150
--- /dev/null
+++ b/src/Java/powercrystals/minefactoryreloaded/farmables/plantables/PlantableStandard.java
@@ -0,0 +1,116 @@
+package powercrystals.minefactoryreloaded.farmables.plantables;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import net.minecraftforge.common.IPlantable;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.oredict.OreDictionary;
+import powercrystals.minefactoryreloaded.api.IFactoryPlantable;
+import powercrystals.minefactoryreloaded.api.ReplacementBlock;
+
+/*
+ * Used for directly placing blocks (ie saplings) and items (ie sugarcane). Pass in source ID to constructor,
+ * so one instance per source ID.
+ */
+
+public class PlantableStandard implements IFactoryPlantable
+{
+ public static final int WILDCARD = OreDictionary.WILDCARD_VALUE;
+
+ protected Item _seed;
+ protected Block _block;
+ protected ReplacementBlock _plantedBlock;
+ protected int _validMeta;
+
+ public PlantableStandard(Block block)
+ {
+ this(Item.getItemFromBlock(block), block);
+ }
+
+ public PlantableStandard(Block block, Block plantedBlock)
+ {
+ this(Item.getItemFromBlock(block), plantedBlock);
+ }
+
+ public PlantableStandard(Item block, Block plantedBlock)
+ {
+ this(block, plantedBlock, WILDCARD);
+ }
+
+ public PlantableStandard(Block block, int meta)
+ {
+ this(Item.getItemFromBlock(block), block, meta);
+ }
+
+ public PlantableStandard(Block block, Block plantedBlock, int meta)
+ {
+ this(Item.getItemFromBlock(block), plantedBlock, meta);
+ }
+
+ public PlantableStandard(Item block, Block plantedBlock, int validMeta)
+ {
+ this(block, plantedBlock, validMeta, new ReplacementBlock(plantedBlock));
+ }
+
+ public PlantableStandard(Item block, Block plantedBlock, int validMeta, int plantedMeta)
+ {
+ this(block, plantedBlock, validMeta, new ReplacementBlock(plantedBlock).setMeta(plantedMeta));
+ }
+
+ public PlantableStandard(Item block, Block plantedBlock, int validMeta, boolean useItemMeta)
+ {
+ this(block, plantedBlock, validMeta, new ReplacementBlock(plantedBlock).setMeta(useItemMeta));
+ }
+
+ public PlantableStandard(Item block, Block plantedBlock, int validMeta, ReplacementBlock repl)
+ {
+ _seed = block;
+ _block = plantedBlock;
+ _validMeta = validMeta;
+ _plantedBlock = repl;
+ }
+
+ @Override
+ public boolean canBePlanted(ItemStack stack, boolean forFermenting)
+ {
+ return _validMeta == WILDCARD || stack.getItemDamage() == _validMeta;
+ }
+
+ @Override
+ public boolean canBePlantedHere(World world, int x, int y, int z, ItemStack stack)
+ {
+ if (!world.isAirBlock(x, y, z))
+ return false;
+
+ Block groundId = world.getBlock(x, y - 1, z);
+ return (_block.canPlaceBlockAt(world, x, y, z) && _block.canReplace(world, x, y, z, 0, stack)) ||
+ (_block instanceof IPlantable && groundId != null &&
+ groundId.canSustainPlant(world, x, y, z, ForgeDirection.UP, (IPlantable)_block));
+ }
+
+ @Override
+ public void prePlant(World world, int x, int y, int z, ItemStack stack)
+ {
+ return;
+ }
+
+ @Override
+ public void postPlant(World world, int x, int y, int z, ItemStack stack)
+ {
+ return;
+ }
+
+ @Override
+ public ReplacementBlock getPlantedBlock(World world, int x, int y, int z, ItemStack stack)
+ {
+ return _plantedBlock;
+ }
+
+ @Override
+ public Item getSeed()
+ {
+ return _seed;
+ }
+}