diff options
Diffstat (limited to 'src/main/java/gtPlusPlus/xmod/gregtech/common/helpers')
11 files changed, 2740 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/ChargingHelper.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/ChargingHelper.java new file mode 100644 index 0000000000..70c7b2da23 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/ChargingHelper.java @@ -0,0 +1,429 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.util.GT_ModHandler; +import gregtech.common.items.GT_MetaGenerated_Item_01; +import gregtech.common.items.GT_MetaGenerated_Item_02; +import gregtech.common.items.GT_MetaGenerated_Tool_01; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.Pair; +import gtPlusPlus.api.objects.minecraft.BlockPos; +import gtPlusPlus.core.util.Utils; +import gtPlusPlus.core.util.math.MathUtils; +import gtPlusPlus.core.util.minecraft.NBTUtils; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaWirelessCharger; +import ic2.api.info.Info; +import ic2.api.item.ElectricItem; +import ic2.api.item.IElectricItem; +import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; + +public class ChargingHelper { + + private static Map<EntityPlayer, Pair<GregtechMetaWirelessCharger, Byte>> mValidPlayers = new HashMap<EntityPlayer, Pair<GregtechMetaWirelessCharger, Byte>>(); + protected static Map<BlockPos, GregtechMetaWirelessCharger> mChargerMap = new HashMap<BlockPos, GregtechMetaWirelessCharger>(); + private int mTickTimer = 0; + private final int mTickMultiplier = 20; + + //Called whenever the player is updated or ticked. + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onPlayerTick(LivingUpdateEvent event) { + try { + if (event.entity != null && event.entityLiving != null){ + if (event.entityLiving instanceof EntityPlayer){ + EntityPlayer mPlayerMan = (EntityPlayer) event.entityLiving; + + + if (mPlayerMan != null){ + //Utils.LOG_WARNING("Found Player."); + + if (Utils.isServer()){ + //Utils.LOG_WARNING("Found Server-Side."); + + mTickTimer++; + if (mTickTimer % mTickMultiplier == 0){ + + long mVoltage = 0; + long mEuStored = 0; + + if (!mChargerMap.isEmpty() && mValidPlayers.containsKey(mPlayerMan)){ + InventoryPlayer mPlayerInventory = mPlayerMan.inventory; + ItemStack[] mArmourContents = mPlayerInventory.armorInventory.clone(); + ItemStack[] mInventoryContents = mPlayerInventory.mainInventory.clone(); + + for (GregtechMetaWirelessCharger mEntityTemp : mChargerMap.values()){ + if (mEntityTemp != null){ + if (mPlayerMan.getEntityWorld().provider.dimensionId == mEntityTemp.getDimensionID()){ + mVoltage = mEntityTemp.maxEUInput(); + mEuStored = mEntityTemp.getEUVar(); + if (mVoltage > 0 && mEuStored >= mVoltage){ + + Map<EntityPlayer, UUID> LR = mEntityTemp.getLongRangeMap(); + Map<UUID, EntityPlayer> LO = mEntityTemp.getLocalMap(); + + long mStartingEu = mEntityTemp.getEUVar(); + long mCurrentEu = mEntityTemp.getEUVar(); + long mEuUsed = 0; + if (mEntityTemp.getMode() == 0){ + if (!LR.isEmpty() && LR.containsKey(mPlayerMan)){ + mCurrentEu = chargeItems(mEntityTemp, mArmourContents, mPlayerMan); + mCurrentEu = chargeItems(mEntityTemp, mInventoryContents, mPlayerMan); + } + } + else if (mEntityTemp.getMode() == 1){ + if (!LO.isEmpty() && LO.containsValue(mPlayerMan)){ + mCurrentEu = chargeItems(mEntityTemp, mArmourContents, mPlayerMan); + mCurrentEu = chargeItems(mEntityTemp, mInventoryContents, mPlayerMan); + } + } + else { + if (!LR.isEmpty() && LR.containsKey(mPlayerMan)){ + mCurrentEu = chargeItems(mEntityTemp, mArmourContents, mPlayerMan); + mCurrentEu = chargeItems(mEntityTemp, mInventoryContents, mPlayerMan); + } + if (!LO.isEmpty() && LO.containsValue(mPlayerMan)){ + mCurrentEu = chargeItems(mEntityTemp, mArmourContents, mPlayerMan); + mCurrentEu = chargeItems(mEntityTemp, mInventoryContents, mPlayerMan); + } + } + + if ((mEuUsed = (mStartingEu - mCurrentEu)) <= 0 && mEntityTemp != null){ + long mMaxDistance; + if (mEntityTemp.getMode() == 0){ + mMaxDistance = (4*GT_Values.V[mEntityTemp.getTier()]); + } + else if (mEntityTemp.getMode() == 1){ + mMaxDistance = (mEntityTemp.getTier()*10); + } + else { + mMaxDistance = (4*GT_Values.V[mEntityTemp.getTier()]/2); + } + double mDistance = calculateDistance(mEntityTemp, mPlayerMan); + long mVoltageCost = MathUtils.findPercentageOfInt(mMaxDistance, (float) mDistance); + + if (mVoltageCost > 0){ + if (mVoltageCost > mEntityTemp.maxEUInput()){ + mEntityTemp.setEUVar((mEntityTemp.getEUVar()-mEntityTemp.maxEUInput())); + } + else { + mEntityTemp.setEUVar((mEntityTemp.getEUVar()-mVoltageCost)); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + catch (Throwable t){ + //Utils.LOG_WARNING("State of Wireless Charger changed in an invalid way, this prevented a crash."); + + if (!mChargerMap.isEmpty()){ + for (GregtechMetaWirelessCharger r : mChargerMap.values()){ + if (r == null){ + mChargerMap.remove(r); + } + } + } + //t.printStackTrace(); + } + + + } + + public static boolean addEntry(BlockPos mPos, GregtechMetaWirelessCharger mEntity){ + if (mEntity == null){ + return false; + } + if (!mChargerMap.containsKey(mPos)){ + if (mChargerMap.put(mPos, mEntity) == null){ + return true; + } + else { + return false; + } + } + else { + return false; + } + } + + public static boolean removeEntry(BlockPos mPos, GregtechMetaWirelessCharger mEntity){ + if (mEntity == null){ + return false; + } + if (mChargerMap.containsKey(mPos)){ + if (mChargerMap.remove(mPos, mEntity)){ + return true; + } + else { + return false; + } + } + else { + return false; + } + } + + public static boolean addValidPlayer(EntityPlayer mPlayer, GregtechMetaWirelessCharger mEntity){ + if (mEntity == null){ + return false; + } + Logger.WARNING("trying to map new player"); + if (mValidPlayers.containsKey(mPlayer)){ + Logger.WARNING("Key contains player already?"); + return false; + } + else { + Logger.WARNING("key not found, adding"); + Pair<GregtechMetaWirelessCharger, Byte> mEntry = new Pair<GregtechMetaWirelessCharger, Byte>(mEntity, (byte) mEntity.getMode()); + if (mValidPlayers.put(mPlayer, mEntry) == null){ + Logger.WARNING("Added a Player to the Tick Map."); + return true; + } + else { + Logger.WARNING("Tried to add player but it was already there?"); + return false; + } + } + } + + public static boolean removeValidPlayer(EntityPlayer mPlayer, GregtechMetaWirelessCharger mEntity){ + if (mEntity == null){ + return false; + } + Logger.WARNING("trying to remove player from map"); + if (mValidPlayers.containsKey(mPlayer)){ + Logger.WARNING("key found, removing"); + Pair<GregtechMetaWirelessCharger, Byte> mEntry = new Pair<GregtechMetaWirelessCharger, Byte>(mEntity, (byte) mEntity.getMode()); + if (mValidPlayers.remove(mPlayer, mEntry)){ + Logger.WARNING("Removed a Player to the Tick Map."); + return true; + } + else { + Logger.WARNING("Tried to remove player but it was not there?"); + return false; + } + } + else { + Logger.WARNING("Key does not contain player?"); + return false; + } + } + + public double calculateDistance(GregtechMetaWirelessCharger mEntityTemp, EntityPlayer mPlayerMan){ + if (mEntityTemp == null || mPlayerMan == null){ + return 0; + } + return mEntityTemp.getDistanceBetweenTwoPositions(mEntityTemp.getTileEntityPosition(), mEntityTemp.getPositionOfEntity(mPlayerMan)); + } + + public long chargeItems(GregtechMetaWirelessCharger mEntity, ItemStack[] mItems, EntityPlayer mPlayer){ + if (mEntity == null){ + return -100; + } + if (mItems == null || mItems.length == 0){ + return mEntity.getEUVar(); + } + long mInitialValue = mEntity.getEUVar(); + long mReturnValue = chargeItemsEx(mEntity, mItems, mPlayer); + return ((mReturnValue < mInitialValue) ? mReturnValue : mInitialValue); + } + + public long chargeItemsEx(GregtechMetaWirelessCharger mEntity, ItemStack[] mItems, EntityPlayer mPlayer){ + + //Bad Entity + if (mEntity == null){ + return -100; + } + //Bad Inventory + if (mItems == null || mItems.length == 0){ + return mEntity.getEUVar(); + } + //Set Variables to Charge + int mChargedItems = 0; + final int mTier = mEntity.getTier(); + final long mVoltage = mEntity.maxEUInput(); + long mEuStored = mEntity.getEUVar(); + final long mEuStoredOriginal = mEntity.getEUVar(); + //For Inventory Contents + + int mItemSlot = 0; + + for (ItemStack mTemp : mItems){ + mItemSlot++; + if (mTemp != null){ + Logger.WARNING("Slot "+mItemSlot+" contains "+mTemp.getDisplayName()); + } + //Is item Electrical + if (isItemValid(mTemp)){ + Logger.WARNING("1"); + + //Transfer Limit + double mItemEuTLimit = ((IElectricItem) mTemp.getItem()).getTransferLimit(mTemp); + //Check if Tile has more or equal EU to what can be transferred into the item. + if (mEuStored >= mItemEuTLimit){ + Logger.WARNING("2"); + + double mItemMaxCharge = ((IElectricItem) mTemp.getItem()).getMaxCharge(mTemp); + double mitemCurrentCharge = ElectricItem.manager.getCharge(mTemp); + + if (mitemCurrentCharge >= mItemMaxCharge){ + continue; + } + + //Try get charge direct from NBT for GT and IC2 stacks + Logger.WARNING("3"); + if (mTemp.getItem() instanceof GT_MetaGenerated_Tool_01 + || mTemp.getItem() instanceof GT_MetaGenerated_Item_01 + || mTemp.getItem() instanceof GT_MetaGenerated_Item_02 + || ReflectionUtils.getClass("gregtech.common.items.GT_MetaGenerated_Item_03").isInstance(mTemp.getItem()) + || mTemp.getItem().getClass().getName().toLowerCase().equals(("gregtech.common.items.GT_MetaGenerated_Tool_01").toLowerCase())){ + if (!NBTUtils.hasKey(mTemp, "GT.ItemCharge")){ + if (!mTemp.getDisplayName().toLowerCase().contains("battery")){ + if (!GT_ModHandler.isElectricItem(mTemp)){ + continue; + } + } + else { + mitemCurrentCharge = 0; + } + } + else { + mitemCurrentCharge = NBTUtils.getLong(mTemp, "GT.ItemCharge"); + } + } + else if (mTemp.getItem() instanceof IElectricItem){ + mitemCurrentCharge = NBTUtils.getLong(mTemp, "charge"); + } + + double mVoltageIncrease; + if (mItemEuTLimit >= mVoltage){ + mVoltageIncrease = mVoltage; + } + else if (mItemEuTLimit < mVoltage){ + mVoltageIncrease = mItemEuTLimit; + } + else { + mVoltageIncrease = mItemEuTLimit; + } + + Logger.WARNING("4"); + + int mMulti; + if ((mitemCurrentCharge + (mVoltageIncrease*20)) <= (mItemMaxCharge - (mVoltageIncrease*20))){ + mMulti = 20; + } + else if ((mitemCurrentCharge + (mVoltageIncrease*10)) <= (mItemMaxCharge - (mVoltageIncrease*10))){ + mMulti = 10; + } + else if ((mitemCurrentCharge + (mVoltageIncrease*5)) <= (mItemMaxCharge - (mVoltageIncrease*5))){ + mMulti = 5; + } + else { + mMulti = 1; + } + Logger.WARNING("5"); + + + int mMultiVoltage = (int) (mMulti*mVoltageIncrease); + + if ((mitemCurrentCharge + mMultiVoltage) <= mItemMaxCharge){ + Logger.WARNING("6"); + int g = 0; + if ((g = GT_ModHandler.chargeElectricItem(mTemp, mMultiVoltage, Integer.MAX_VALUE, true, false)) > 0){ + Logger.WARNING("6.5 - "+g+" - "+mMulti); + for (int i=0; i<mMulti;i++){ + if (ElectricItem.manager.charge(mTemp, mVoltageIncrease, Integer.MAX_VALUE, false, false) > 0){ + continue; + } + } + } + if (ElectricItem.manager.getCharge(mTemp) > mitemCurrentCharge){ + Logger.WARNING("7"); + mEntity.setEUVar(mEuStored-(mVoltage*mMulti)); + mEuStored = mEntity.getEUVar(); + Logger.WARNING("Charged "+mTemp.getDisplayName()+" | Slot: "+mItemSlot+" | EU Multiplier: "+mMulti+" | EU/t input: "+mVoltageIncrease+" | EU/t consumed by Tile: "+mVoltage+" | Item Max Charge: "+mItemMaxCharge+" | Item Start Charge: "+mitemCurrentCharge+" | Item New Charge"+ElectricItem.manager.getCharge(mTemp)); + mChargedItems++; + } + } + + //Try top up Item Chrage + mitemCurrentCharge = ElectricItem.manager.getCharge(mTemp); + if (mitemCurrentCharge < mItemMaxCharge && mitemCurrentCharge >= (mItemMaxCharge-mVoltage)){ + int xDif = (int) (mItemMaxCharge - mitemCurrentCharge); + Logger.WARNING("8 - "+xDif); + int g = 0; + if ((g = GT_ModHandler.chargeElectricItem(mTemp, xDif, Integer.MAX_VALUE, true, false)) >= 0){ + Logger.WARNING("8.5 - "+g); + if (ElectricItem.manager.getCharge(mTemp) >= mItemMaxCharge){ + Logger.WARNING("9"); + mEntity.setEUVar(mEntity.getEUVar()-(xDif)); + mEuStored = mEntity.getEUVar(); + Logger.WARNING("Charged "+mTemp.getDisplayName()+" | Slot: "+mItemSlot+" | EU Multiplier: "+mMulti+" | EU/t input: "+mVoltageIncrease+" | EU/t consumed by Tile: "+mVoltage+" | Item Max Charge: "+mItemMaxCharge+" | Item Start Charge: "+mitemCurrentCharge+" | Item New Charge"+ElectricItem.manager.getCharge(mTemp)); + mChargedItems++; + } + } + } + + + } + } + else { + if (mTemp != null){ + Logger.WARNING("Found Non-Valid item. "+mTemp.getDisplayName()); + } + } + } + + //Return Values + if (mChargedItems < 1){ + return mEuStoredOriginal; + } + + return mEntity.getEUVar(); + } + + public static boolean isItemValid(final ItemStack itemstack) { + if (itemstack == null){ + return false; + } + if (GT_ModHandler.isElectricItem(itemstack)){ + return true; + } + if ((accepts(itemstack)) || (itemstack.getItem() instanceof IElectricItem)) { + return true; + } + return false; + } + + public static boolean accepts(final ItemStack stack) { + if (stack == null) { + return false; + } + else { + return false; + } + //return (Info.itemEnergy.getEnergyValue(stack) > 0.0D) || (ElectricItem.manager.discharge(stack, (1.0D / 0.0D), 4, true, true, true) > 0.0D); + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/CraftingHelper.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/CraftingHelper.java new file mode 100644 index 0000000000..e06636e168 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/CraftingHelper.java @@ -0,0 +1,42 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.xmod.gregtech.common.helpers.autocrafter.AC_Helper_Container; +import gtPlusPlus.xmod.gregtech.common.helpers.autocrafter.AC_Helper_Utils; +import gtPlusPlus.xmod.gregtech.common.tileentities.machines.multi.production.GT4Entity_AutoCrafter; +import net.minecraftforge.common.util.FakePlayerFactory; + +public class CraftingHelper{ + + public final String mInventoryName; + public final int mPosX; + public final int mPosY; + public final int mPosZ; + public final GT4Entity_AutoCrafter crafter; + public final World world; + public final EntityPlayerMP player; + public final AC_Helper_Container inventory; + + public CraftingHelper(GT4Entity_AutoCrafter AC){ + Logger.INFO("[A-C] Created a crafting helper."); + crafter = AC; + AC_Helper_Utils.addCrafter(AC); + //Get some variables. + world = AC.getBaseMetaTileEntity().getWorld(); + mPosX = AC.getBaseMetaTileEntity().getXCoord(); + mPosY = AC.getBaseMetaTileEntity().getYCoord(); + mPosZ = AC.getBaseMetaTileEntity().getZCoord(); + //Create Fake player to handle crating. + + player = CORE.getFakePlayer(world); + //Set storage container + inventory = new AC_Helper_Container(player.inventory, world, mPosX, mPosY, mPosZ); + mInventoryName = inventory.getMatrix().getInventoryName(); + + } +}
\ No newline at end of file diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/FlotationRecipeHandler.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/FlotationRecipeHandler.java new file mode 100644 index 0000000000..333939d800 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/FlotationRecipeHandler.java @@ -0,0 +1,79 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import java.util.HashMap; + +import gregtech.api.enums.OrePrefixes; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.material.Material; +import gtPlusPlus.core.util.data.AES; +import gtPlusPlus.xmod.gregtech.api.enums.CustomOrePrefix; +import net.minecraft.item.ItemStack; + +public class FlotationRecipeHandler { + + private static HashMap<String, Material> sMaterialMap = new HashMap<String, Material>(); + private static HashMap<String, ItemStack> sMilledMap = new HashMap<String, ItemStack>(); + private static final AES sEncodingHandler = new AES(); + + public static boolean registerOreType(Material aMaterial) { + String aMaterialKey = sEncodingHandler.encode(aMaterial.getUnlocalizedName()); + if (sMaterialMap.containsKey(aMaterialKey)) { + CORE.crash("Tried to register a Flotation material to an ID already in use. ID: "+aMaterialKey); + return false; + } + else { + sMaterialMap.put(aMaterialKey, aMaterial); + sMilledMap.put(aMaterialKey, aMaterial.getMilled(1)); + } + return true; + } + + public static int getHashForMaterial(Material aMaterial) { + return getMaterialsID(aMaterial).hashCode(); + } + + public static String getMaterialsID(Material aMaterial) { + for (String aKey : sMaterialMap.keySet()) { + if (sMaterialMap.get(aKey).equals(aMaterial)) { + return aKey; + } + } + return "BAD_MATERIAL_ID"; + } + + public static Material getMaterialOfMilledProduct(ItemStack aMilled) { + for (String aKey : sMilledMap.keySet()) { + ItemStack aTempMilledStack = sMilledMap.get(aKey); + if (GT_Utility.areStacksEqual(aTempMilledStack, aMilled, true)) { + return sMaterialMap.get(aKey); + } + } + return null; + } + + public static ItemStack findMilledStack(GT_Recipe aRecipe) { + if (aRecipe == null || aRecipe.mInputs == null || aRecipe.mInputs.length <= 0) { + return null; + } + return findMilledStack(aRecipe.mInputs); + } + + public static ItemStack findMilledStack(ItemStack[] aInputs) { + if (aInputs == null || aInputs.length <= 0) { + return null; + } + for (ItemStack aStack : aInputs) { + if (CustomOrePrefix.milled.get().contains(aStack)) { + return aStack; + } + } + return null; + } + + public static AES getEncoder() { + return sEncodingHandler; + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/GT_MethodHelper.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/GT_MethodHelper.java new file mode 100644 index 0000000000..d51107bbf0 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/GT_MethodHelper.java @@ -0,0 +1,80 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import gregtech.api.enums.Textures.BlockIcons; +import gregtech.api.interfaces.ITexture; +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.block.Block; +import net.minecraft.tileentity.TileEntity; + +public class GT_MethodHelper { + + private static final Method mGetTexture; + private static final Class mITexturedTileEntity; + + static { + Class clazz = null; + Method aMeth = null; + if (ReflectionUtils.doesClassExist("gregtech.api.interfaces.tileentity.ITexturedTileEntity")) { + clazz = ReflectionUtils.getClass("gregtech.api.interfaces.tileentity.ITexturedTileEntity"); + aMeth = ReflectionUtils.getMethod(clazz, "getTexture", Block.class, byte.class); + } + mITexturedTileEntity = clazz; + mGetTexture = aMeth; + } + + + public static ITexture[] getTexture(TileEntity tTileEntity, Block aBlock, byte aSide) { + + if (mITexturedTileEntity.isInstance(tTileEntity)) { + + if (mGetTexture != null) { + try { + mGetTexture.invoke(tTileEntity, aBlock, aSide); + } + catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + e.printStackTrace(); + } + } + else { + if (tTileEntity instanceof BaseMetaTileEntity) { + try { + BaseMetaTileEntity aTile = (BaseMetaTileEntity) tTileEntity; + ITexture rIcon = aTile.getCoverTexture(aSide); + Field aFacing = ReflectionUtils.getField(BaseMetaTileEntity.class, "mFacing"); + Field aColor = ReflectionUtils.getField(BaseMetaTileEntity.class, "mColor"); + Field aActive = ReflectionUtils.getField(BaseMetaTileEntity.class, "mActive"); + Field aMetaTile = ReflectionUtils.getField(BaseMetaTileEntity.class, "mMetaTileEntity"); + Method aHasValidTile = ReflectionUtils.getMethod(BaseMetaTileEntity.class, "hasValidMetaTileEntity", new Class[] {}); + + boolean hasValidTileObj = (boolean) aHasValidTile.invoke(aTile, new Object[] {}); + boolean aActiveObj = aActive.getBoolean(aTile); + byte aFacingObj = aFacing.getByte(aTile); + byte aColorObj = aColor.getByte(aTile);; + MetaTileEntity aMetaTileObj = (MetaTileEntity) aMetaTile.get(aTile); + + if (rIcon != null) { + return new ITexture[]{rIcon}; + } else { + return hasValidTileObj + ? aMetaTileObj.getTexture(aTile, aSide, aFacingObj, (byte) (aColorObj - 1), aActiveObj, + aTile.getOutputRedstoneSignal(aSide) > 0) + : BlockIcons.ERROR_RENDERING; + } + } + catch (Throwable t) { + t.printStackTrace(); + } + } + } + } + return BlockIcons.ERROR_RENDERING; + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/MachineUpdateHandler.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/MachineUpdateHandler.java new file mode 100644 index 0000000000..0b52560e0d --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/MachineUpdateHandler.java @@ -0,0 +1,42 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import java.util.HashMap; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import gregtech.api.GregTech_API; +import net.minecraft.block.Block; +import net.minecraftforge.event.world.BlockEvent; + +public class MachineUpdateHandler { + + private static final HashMap<String, Block> mBlockCache = new HashMap<String, Block>(); + + public static void registerBlockToCauseMachineUpdate(String aUnlocalName, Block aBlock) { + mBlockCache.put(aUnlocalName, aBlock); + } + + @SubscribeEvent + public void onBlockEvent(BlockEvent event) { + Block aBlock = event.block; + String aUnlocalName = aBlock != null ? aBlock.getUnlocalizedName() : "NULL"; + boolean aDoUpdate = false; + if (aBlock != null && aUnlocalName != null && !aUnlocalName.equals("NULL")) { + for (String aCachedName : mBlockCache.keySet()) { + if (aCachedName.equals(aUnlocalName)) { + aDoUpdate = true; + break; + } + else { + if (aBlock == mBlockCache.get(aCachedName)) { + aDoUpdate = true; + break; + } + } + } + if (aDoUpdate) { + GregTech_API.causeMachineUpdate(event.world, event.x, event.y, event.z); + } + } + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/TreeFarmHelper.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/TreeFarmHelper.java new file mode 100644 index 0000000000..2ff2712952 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/TreeFarmHelper.java @@ -0,0 +1,1033 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import static gtPlusPlus.core.lib.CORE.ConfigSwitches.enableTreeFarmerParticles; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import com.google.common.collect.Lists; + +import gnu.trove.set.hash.THashSet; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.common.eventhandler.Event.Result; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; + +import gregtech.api.enums.*; +import net.minecraft.block.Block; +import net.minecraft.block.BlockAir; +import net.minecraft.block.IGrowable; +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.network.play.server.S23PacketBlockChange; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.World; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.GT_MetaGenerated_Tool; +import gregtech.common.items.GT_MetaGenerated_Item_02; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.api.objects.minecraft.BlockPos; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.lib.LoadedMods; +import gtPlusPlus.core.players.FakeFarmer; +import gtPlusPlus.core.slots.SlotBuzzSaw.SAWTOOL; +import gtPlusPlus.core.util.Utils; +import gtPlusPlus.core.util.math.MathUtils; +import gtPlusPlus.core.util.minecraft.FluidUtils; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.core.util.minecraft.particles.BlockBreakParticles; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.xmod.gregtech.common.items.MetaGeneratedGregtechItems; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.BonemealEvent; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.oredict.OreDictionary; + +public class TreeFarmHelper { + + public static final FluidStack fertT1 = FluidUtils.getFluidStack("fluid.fertiliser", 3); + public static final FluidStack fertT2 = FluidUtils.getFluidStack("fluid.un18fertiliser", 2); + public static final FluidStack fertT3 = FluidUtils.getFluidStack("fluid.un32fertiliser", 1); + private static final int sawOreId = OreDictionary.getOreID(ToolDictNames.craftingToolSaw.name()); + + public static ITexture[][][] getTextureSet() { + final ITexture[][][] rTextures = new ITexture[10][17][]; + for (byte i = -1; i < 16; i++) { + rTextures[0][i + 1] = TreeFarmHelper.getFront(i); + rTextures[1][i + 1] = TreeFarmHelper.getBack(i); + rTextures[2][i + 1] = TreeFarmHelper.getBottom(i); + rTextures[3][i + 1] = TreeFarmHelper.getTop(i); + rTextures[4][i + 1] = TreeFarmHelper.getSides(i); + rTextures[5][i + 1] = TreeFarmHelper.getFrontActive(i); + rTextures[6][i + 1] = TreeFarmHelper.getBackActive(i); + rTextures[7][i + 1] = TreeFarmHelper.getBottomActive(i); + rTextures[8][i + 1] = TreeFarmHelper.getTopActive(i); + rTextures[9][i + 1] = TreeFarmHelper.getSidesActive(i); + } + return rTextures; + } + + public static ITexture[] getFront(final byte aColor) { + return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[2][aColor + 1]}; + } + + public static ITexture[] getBack(final byte aColor) { + return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[2][aColor + 1]}; + } + + public static ITexture[] getBottom(final byte aColor) { + return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[2][aColor + 1]}; + } + + public static ITexture[] getTop(final byte aColor) { + return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[2][aColor + 1]}; + } + + public static ITexture[] getSides(final byte aColor) { + return new ITexture[]{Textures.BlockIcons.MACHINE_CASINGS[2][aColor + 1]}; + } + + public static ITexture[] getFrontActive(final byte aColor) { + return getFront(aColor); + } + + public static ITexture[] getBackActive(final byte aColor) { + return getBack(aColor); + } + + public static ITexture[] getBottomActive(final byte aColor) { + return getBottom(aColor); + } + + public static ITexture[] getTopActive(final byte aColor) { + return getTop(aColor); + } + + public static ITexture[] getSidesActive(final byte aColor) { + return getSides(aColor); + } + + public static boolean applyBonemeal(final EntityPlayer player, final World world, final int intX, final int intY, final int intZ, final short multiplier){ + final Block block = world.getBlock(intX, intY, intZ); + + + int roll; + int rollNeeded; + + if (multiplier==1){ + roll = MathUtils.randInt(1, 15); + rollNeeded = 15; + } + else if (multiplier==2){ + roll = MathUtils.randInt(1, 10); + rollNeeded = 10; + } + else { + roll = MathUtils.randInt(1, 5); + rollNeeded = 5; + } + + if (roll != rollNeeded){ + return false; + } + + //EntityPlayer player = FakePlayerFactory.getMinecraft((WorldServer)world); + if (!world.isRemote){ + if (enableTreeFarmerParticles){ + world.playAuxSFX(2005, intX, intY, intZ, 0); + } + } + final BonemealEvent event = new BonemealEvent(player, world, block, intX, intY, intZ); + if (MinecraftForge.EVENT_BUS.post(event)){ + Logger.MACHINE_INFO("Not sure why this returned false"); + return false; + } + if (event.getResult() == Result.ALLOW){ + if (!world.isRemote){ + world.playAuxSFX(2005, intX, intY, intZ, 0); + } + return true; + } + if (block instanceof IGrowable){ + final IGrowable igrowable = (IGrowable)block; + if (igrowable.func_149851_a(world, intX, intY, intZ, world.isRemote)){ + if (!world.isRemote){ + if (igrowable.func_149852_a(world, CORE.RANDOM, intX, intY, intZ)){ + igrowable.func_149853_b(world, CORE.RANDOM, intX, intY, intZ); + } + } + return true; + } + } + return false; + } + + public static boolean cleanUp(final IGregTechTileEntity aBaseMetaTileEntity){ + Logger.MACHINE_INFO("called cleanUp()"); + int cleanedUp = 0; + final int xDir = net.minecraftforge.common.util.ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()).offsetX * 11; + final int zDir = net.minecraftforge.common.util.ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()).offsetZ * 11; + + for (int h=1;h<175;h++){ + for (int i = -11; i <= 11; i++) { + for (int j = -11; j <= 11; j++) { + + final Block testBlock = aBaseMetaTileEntity.getBlockOffset(xDir + i, h, zDir + j); + + + if + (( + ((i == -8) || (i == 8)) || + ((i == -9) || (i == 9)) || + ((i == -10) || (i == 10)) || + ((i == -11) || (i == 11)) + ) + && + ( + ((j == -8) || (j == 8)) || + ((j == -9) || (j == 9)) || + ((j == -10) || (j == 10)) || + ((j == -11) || (j == 11)) + )){ + + if (!testBlock.getUnlocalizedName().toLowerCase().contains("air") || !testBlock.getUnlocalizedName().toLowerCase().contains("pumpkin")) { + //Logger.WARNING("5:"+testBlock.getUnlocalizedName()); + } else { + aBaseMetaTileEntity.getWorld().setBlock(aBaseMetaTileEntity.getXCoord()+xDir+i, aBaseMetaTileEntity.getYCoord()+h, aBaseMetaTileEntity.getZCoord()+zDir+j, Blocks.bookshelf); + } + } + + + //If not in the middle - don't know how else to check this one without lots of != + if ( + (i != 7) && (i != -7) && (j != 7) && (j != -7) && + (i != 6) && (i != -6) && (j != 6) && (j != -6) && + (i != 5) && (i != -5) && (j != 5) && (j != -5) && + (i != 4) && (i != -4) && (j != 4) && (j != -4) && + (i != 3) && (i != -3) && (j != 3) && (j != -3) && + (i != 2) && (i != -2) && (j != 2) && (j != -2) && + (i != 1) && (i != -1) && (j != 1) && (j != -1) && + (i != 0) && (j != 0) + ){ + + if (!testBlock.getUnlocalizedName().toLowerCase().contains("air") || !testBlock.getUnlocalizedName().toLowerCase().contains("pumpkin")) { + //Logger.WARNING("0:"+testBlock.getUnlocalizedName()); + } else { + aBaseMetaTileEntity.getWorld().setBlock(aBaseMetaTileEntity.getXCoord()+xDir+i, aBaseMetaTileEntity.getYCoord()+h, aBaseMetaTileEntity.getZCoord()+zDir+j, Blocks.melon_block); + } + + + if (isLeaves(testBlock) || isWoodLog(testBlock)){ + //Logger.WARNING("1:"+testBlock.getUnlocalizedName()); + int posiX, posiY, posiZ; + posiX = aBaseMetaTileEntity.getXCoord()+xDir+i; + posiY = aBaseMetaTileEntity.getYCoord()+h; + posiZ = aBaseMetaTileEntity.getZCoord()+zDir+j; + //Utils.LOG_MACHINE_INFO("Cleaning Up some leftovers."); + cleanedUp++; + aBaseMetaTileEntity.getWorld().setBlockToAir(posiX, posiY, posiZ); + new BlockBreakParticles(aBaseMetaTileEntity.getWorld(), posiX, posiY, posiZ, Blocks.dirt); + } + else { + //Utils.LOG_WARNING("2:"+testBlock.getUnlocalizedName()); + } + } + else { + //Utils.LOG_WARNING("1"); + } + + + } + + } + } + Logger.MACHINE_INFO("cleaning up | "+cleanedUp ); + return true; + } + + public static SAWTOOL isCorrectMachinePart(final ItemStack aStack) { + if (aStack != null){ + //Utils.LOG_WARNING("Found "+aStack.getDisplayName()+" in the GUI slot."); + if ((aStack.getItem() instanceof GT_MetaGenerated_Item_02) || (aStack.getItem() instanceof GT_MetaGenerated_Tool)){ + if (OrePrefixes.craftingTool.contains(aStack)){ + if (aStack.getDisplayName().toLowerCase().contains("saw") || aStack.getDisplayName().toLowerCase().contains("gt.metatool.01")){ + if (aStack.getItemDamage() == 10){ + return SAWTOOL.SAW; + } + else if (aStack.getItemDamage() == 140 || aStack.getDisplayName().toLowerCase().contains("gt.metatool.01.140")){ + return SAWTOOL.BUZZSAW; + } + else if (aStack.getItemDamage() == 110 || aStack.getDisplayName().toLowerCase().contains("gt.metatool.01.110")){ + return SAWTOOL.CHAINSAW; + } + else if (aStack.getItemDamage() == 112 || aStack.getDisplayName().toLowerCase().contains("gt.metatool.01.112")){ + return SAWTOOL.CHAINSAW; + } + else if (aStack.getItemDamage() == 114 || aStack.getDisplayName().toLowerCase().contains("gt.metatool.01.114")){ + return SAWTOOL.CHAINSAW; + } + else { + return SAWTOOL.NONE; + } + } + } + } + } + return SAWTOOL.NONE; + } + + public static ToolType getPartType(final ItemStack aStack) { + if (aStack != null){ + //Utils.LOG_WARNING("Found "+aStack.getDisplayName()+" in the GUI slot."); + + if (aStack.getItem() == MetaGeneratedGregtechItems.INSTANCE) { + int aDmg = aStack.getItemDamage(); + if (aDmg >= 32120 && aDmg <= 32128) { + return ToolType.Unbreakable; + } + Logger.INFO("bad Tool in Slot 2 | "+aStack.getUnlocalizedName().toLowerCase() + " | "+aDmg); + return null; + } + + if (aStack.getItem() instanceof GT_MetaGenerated_Tool) { + if (Arrays.stream(OreDictionary.getOreIDs(aStack)).anyMatch(i -> i == sawOreId)) + return ToolType.Breakable; + } + } + Logger.INFO("bad Tool in Slot 4"); + return null; + } + + public static boolean isHumusLoaded = false; + public static boolean isForestryLogsLoaded = false; + public static boolean isForestryFenceLoaded = false; + public static boolean isForestrySaplingsLoaded = false; + public static boolean isForestryLeavesLoaded = false; + public static Block blockHumus; + + public static boolean isForestryValid(){ + if (!LoadedMods.Forestry){ + return false; + } + if (ReflectionUtils.doesClassExist("forestry.core.blocks.BlockSoil")){ + isHumusLoaded = true; + } + if (ReflectionUtils.doesClassExist("forestry.arboriculture.blocks.BlockLog")){ + isForestryLogsLoaded = true; + } + if (ReflectionUtils.doesClassExist("forestry.arboriculture.blocks.BlockArbFence")){ + isForestryFenceLoaded = true; + } + if (ReflectionUtils.doesClassExist("forestry.arboriculture.blocks.BlockSapling")){ + isForestrySaplingsLoaded = true; + } + if (ReflectionUtils.doesClassExist("forestry.arboriculture.blocks.BlockForestryLeaves")){ + isForestryLeavesLoaded = true; + } + return true; + } + + @Optional.Method(modid = "Forestry") + public static Block getHumus(){ + if(blockHumus != null){ + return blockHumus; + } + else if (isHumusLoaded){ + final Class<?> humusClass = ReflectionUtils.getClass("forestry.core.blocks.BlockSoil"); + final ItemStack humusStack = ItemUtils.getCorrectStacktype("Forestry:soil", 1); + if (humusClass != null){ + blockHumus = Block.getBlockFromItem(humusStack.getItem()); + return Block.getBlockFromItem(humusStack.getItem()); + } + } + return null; + } + + public static boolean isWoodLog(final Block log){ + final String tTool = log.getHarvestTool(0); + + if ((log == Blocks.log) || (log == Blocks.log2)){ + return true; + } + + //Forestry/General Compat + if (log.getClass().getName().toLowerCase().contains("blocklog")){ + return true; + } + + //IC2 Rubber Tree Compat + if (log.getClass().getName().toLowerCase().contains("rubwood") || log.getClass().getName().toLowerCase().contains("rubleaves")){ + 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(final Block log){ + if (log.getUnlocalizedName().toLowerCase().contains("leaf")){ + return true; + } + if (log.getUnlocalizedName().toLowerCase().contains("leaves")){ + return true; + } + if (log.getLocalizedName().toLowerCase().contains("leaf")){ + return true; + } + if (log.getLocalizedName().toLowerCase().contains("leaves")){ + return true; + } + return OrePrefixes.leaves.contains(new ItemStack(log, 1)) || log.getMaterial() == Material.leaves || OrePrefixes.treeLeaves.contains(new ItemStack(log, 1)) || log.getMaterial() == Material.vine || OrePrefixes.mushroom.contains(new ItemStack(log, 1)) || log.getMaterial() == Material.cactus; + } + + public static boolean isSapling(final Block log){ + if (log != null){ + if (OrePrefixes.sapling.contains(new ItemStack(log, 1))){ + //Logger.WARNING(""+log.getLocalizedName()); + } + if (log.getLocalizedName().toLowerCase().contains("sapling")){ + //Logger.WARNING(""+log.getLocalizedName()); + return true; + } + } + return OrePrefixes.sapling.contains(new ItemStack(log, 1)); + } + + public static boolean isDirtBlock(final Block dirt){ + return (dirt == Blocks.dirt ? true : (dirt == Blocks.grass ? true : (getHumus() == null ? false : (dirt == blockHumus ? true : false)))); + } + + public static boolean isFenceBlock(final Block fence){ + 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(final Block air){ + if (air.getLocalizedName().toLowerCase().contains("air")){ + return true; + } + if (air.getClass().getName().toLowerCase().contains("residual") || air.getClass().getName().toLowerCase().contains("heat")){ + return true; + } + return (air == Blocks.air ? true : (air instanceof BlockAir ? true : false)); + } + + /*public static boolean isSaplingBlock(Block sapling){ + return (sapling == Blocks.sapling ? true : (sapling == Blocks.)) + }*/ + + public static BlockPos checkForLogsInGrowArea(final IGregTechTileEntity aBaseMetaTileEntity) { + final int xDir = net.minecraftforge.common.util.ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()).offsetX * 7; + final int zDir = net.minecraftforge.common.util.ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()).offsetZ * 7; + for (int i = -7; i <= 7; i++) { + for (int j = -7; j <= 7; j++) { + for (int h = 0; h <= 1; h++) { + //Farm Floor inner 14x14 + if (((i != -7) && (i != 7)) && ((j != -7) && (j != 7))) { + if (h == 1) { + if (TreeFarmHelper.isWoodLog(aBaseMetaTileEntity.getBlockOffset(xDir + i, h, zDir + j))) { + Logger.INFO("Found a Log"); + return new BlockPos(aBaseMetaTileEntity.getXCoord()+xDir + i, aBaseMetaTileEntity.getYCoord()+h, aBaseMetaTileEntity.getZCoord()+zDir + j, aBaseMetaTileEntity.getWorld()); + } + } + } + } + } + } + return null; + } + + public static ItemStack[] findTreeFromBase(World world, BlockPos h) { + int HARD_LIMIT = 10000; + int mCount = 0; + Logger.INFO("Finding Rest of Tree."); + BlockPos mFirstSpot = h; + Set<BlockPos> mSearchedSpaces = new HashSet<BlockPos>(); + Set<BlockPos> mTreeSet = getConnectedBlocks(world, mFirstSpot, mSearchedSpaces); + Set<Set<BlockPos>> mTreeSet2 = new HashSet<Set<BlockPos>>(); + Set<BlockPos> mFinalTree = new HashSet<BlockPos>(); + Iterator<BlockPos> it = mTreeSet.iterator(); + + + Logger.INFO("Running first iteration."); + while(it.hasNext()){ + BlockPos G = it.next(); + mSearchedSpaces.add(G); + mTreeSet2.add(getConnectedBlocks(world, G, mSearchedSpaces)); + mCount++; + Logger.INFO("First Search: "+G.getLocationString()); + if (mCount > HARD_LIMIT) { + break; + } + } + + mCount = 0; + Iterator<Set<BlockPos>> it2 = mTreeSet2.iterator(); + Iterator<BlockPos> it3; + Logger.INFO("Running second iteration."); + while(it2.hasNext()){ + Set<BlockPos> G = it2.next(); + it3 = G.iterator(); + while(it3.hasNext()){ + BlockPos G2 = it3.next(); + mSearchedSpaces.add(G2); + mFinalTree.add(G2); + mCount++; + Logger.INFO("Second Search: "+G2.getLocationString()); + if (mCount > HARD_LIMIT) { + break; + } + } + if (mCount > HARD_LIMIT) { + break; + } + } + + + if (mFinalTree.size() > 0) { + Logger.INFO("Queuing "+mFinalTree.size()+" to Harvest Manager."); + TreeCutter harvestManager = new TreeCutter(world); + + Iterator<BlockPos> ith = mFinalTree.iterator(); + while(ith.hasNext()){ + BlockPos G = ith.next(); + harvestManager.queue(G); + mCount++; + Logger.INFO("Queued: "+G.getLocationString()); + if (mCount > HARD_LIMIT) { + break; + } + } + + if (harvestManager.isValid) { + ItemStack[] loot = harvestManager.getDrops(); + if (loot.length > 0) { + //Logger.INFO("Returning Drops from harvestManager Queue."); + return loot; + } + } + } + return new ItemStack[] {}; + } + + + public static Set<BlockPos> getConnectedBlocks(World W, BlockPos P, Set<BlockPos> checkedSpaces) { + int HARD_LIMIT = 1000; + int mCount = 0; + Logger.INFO("Finding blocks connected to "+P.getLocationString()+"."); + Set<BlockPos> mCheckedSpaces = checkedSpaces; + Set<BlockPos> mStartSearch = searchSixFaces(W, P, mCheckedSpaces, false); + Set<BlockPos> mSecondSearch = new HashSet<BlockPos>(); + Set<BlockPos> mThirdSearch = new HashSet<BlockPos>(); + Iterator<BlockPos> it = mStartSearch.iterator(); + while(it.hasNext()){ + Logger.INFO("Running first iteration. [II]"); + BlockPos G = it.next(); + mCheckedSpaces.add(G); + Set<BlockPos> mBranchSearch = searchSixFaces(W, G, mCheckedSpaces, true); + Iterator<BlockPos> it2 = mBranchSearch.iterator(); + while(it2.hasNext()){ + Logger.INFO("Running second iteration. [II]"); + BlockPos G2 = it2.next(); + mCheckedSpaces.add(G2); + mSecondSearch.add(G2); + mCount++; + if (mCount > HARD_LIMIT) { + break; + } + } + if (mCount > HARD_LIMIT) { + break; + } + } + mCount = 0; + Iterator<BlockPos> itx = mSecondSearch.iterator(); + while(itx.hasNext()){ + BlockPos G = itx.next(); + mCheckedSpaces.add(G); + Set<BlockPos> mBranchSearch = searchSixFaces(W, G, mCheckedSpaces, true); + Iterator<BlockPos> it2 = mBranchSearch.iterator(); + while(it2.hasNext()){ + BlockPos G2 = it2.next(); + mCheckedSpaces.add(G2); + mThirdSearch.add(G2); + mCount++; + if (mCount > HARD_LIMIT) { + break; + } + } + if (mCount > HARD_LIMIT) { + break; + } + } + return mThirdSearch; + } + + public static Set<BlockPos> searchSixFaces(World W, BlockPos P, Set<BlockPos> checkedSpaces, boolean checkLeaves) { + Set<BlockPos> mConnected = new HashSet<BlockPos>(); + int x = P.xPos; + int y = P.yPos; + int z = P.zPos; + if (checkLeaves) { + if (isWoodLog(W.getBlock(x-1, y, z)) || isLeaves(W.getBlock(x-1, y, z))) { + BlockPos L = new BlockPos(x-1, y, z, W); + if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + } + } + if (isWoodLog(W.getBlock(x+1, y, z)) || isLeaves(W.getBlock(x+1, y, z))) { + BlockPos L = new BlockPos(x+1, y, z, W); + if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + } + } + if (isWoodLog(W.getBlock(x, y-1, z)) || isLeaves(W.getBlock(x, y-1, z))) { + BlockPos L = new BlockPos(x, y-1, z, W); + if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + } + } + if (isWoodLog(W.getBlock(x, y+1, z)) || isLeaves(W.getBlock(x, y+1, z))) { + BlockPos L = new BlockPos(x, y+1, z, W); + if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + } + } + if (isWoodLog(W.getBlock(x, y, z-1)) || isLeaves(W.getBlock(x, y, z-1))) { + BlockPos L = new BlockPos(x, y, z-1, W); + if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + } + } + if (isWoodLog(W.getBlock(x, y, z+1)) || isLeaves(W.getBlock(x, y, z+1))) { + BlockPos L = new BlockPos(x, y, z+1, W); + if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + } + } + } + else { + if (isWoodLog(W.getBlock(x-1, y, z))) { + BlockPos L = new BlockPos(x-1, y, z, W); + //if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + //} + } + if (isWoodLog(W.getBlock(x+1, y, z))) { + BlockPos L = new BlockPos(x+1, y, z, W); + //if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + //} + } + if (isWoodLog(W.getBlock(x, y-1, z))) { + BlockPos L = new BlockPos(x, y-1, z, W); + //if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + //} + } + if (isWoodLog(W.getBlock(x, y+1, z))) { + BlockPos L = new BlockPos(x, y+1, z, W); + //if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + //} + } + if (isWoodLog(W.getBlock(x, y, z-1))) { + BlockPos L = new BlockPos(x, y, z-1, W); + //if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + //} + } + if (isWoodLog(W.getBlock(x, y, z+1))) { + BlockPos L = new BlockPos(x, y, z+1, W); + //if (!checkedSpaces.contains(L)) { + mConnected.add(L); + Logger.INFO("Found Connected. [III]"); + //} + } + } + return mConnected; + } + + + public enum ToolType { + Unbreakable, + Breakable + } + + + /** + * Tree Cutting + */ + + public static class TreeCutter { + + private final World mWorld; + private Map<String, BlockPos> mQueue = new ConcurrentHashMap<String, BlockPos>(); + private AutoMap<ItemStack[]> mDrops = new AutoMap<ItemStack[]>(); + private boolean isValid = true; + + public TreeCutter(World world) { + this.mWorld = world; + } + + public boolean queue(BlockPos pos) { + if (isValid && pos != null) { + //Logger.INFO("Queued: "+pos.getLocationString()); + String hash = Utils.calculateChecksumMD5(pos); + if (hash != null && !mQueue.containsKey(hash)) { + mQueue.put(hash, pos); + return true; + } + } + return false; + } + + private boolean emptyQueue() { + if (isValid) { + Logger.INFO("Emptying Queue."); + if (this.mQueue.size() > 0) { + int totalRemoved = 0; + for (BlockPos h : mQueue.values()) { + final Block block = mWorld.getBlock(h.xPos, h.yPos, h.zPos); + if (block != null) { + final int dropMeta = mWorld.getBlockMetadata(h.xPos, h.yPos, h.zPos); + final ArrayList<ItemStack> blockDrops = block.getDrops(mWorld, h.xPos, h.yPos, h.zPos, dropMeta, 0); + final ItemStack[] drops = ItemUtils.getBlockDrops(blockDrops); + mDrops.put(drops); + //Remove drop that was added to the bus. + mWorld.setBlockToAir(h.xPos, h.yPos, h.zPos); + //new BlockBreakParticles(mWorld, h.xPos, h.yPos, h.zPos, block); + totalRemoved++; + } + } + if (totalRemoved > 0 && mDrops.size() > 0) { + return true; + } + } + } + return false; + } + + public ItemStack[] getDrops() { + //If Queue is successfully cleared and drops are created, let us continue. + if (isValid && emptyQueue()) { + AutoMap<ItemStack> mCollective = new AutoMap<ItemStack>(); + //Iterate ALL of the arrays, add output to a collective. + for (ItemStack[] i : this.mDrops) { + //Array is not null. + if (i != null) { + //Iterate this array. + for (int d=0;d<i.length;d++) { + //Put Output into collective if valid + if (i[d] != null && i[d].stackSize > 0) { + mCollective.put(i[d]); + } + } + } + } + //Build an ItemStack array. + ItemStack[] drops = new ItemStack[mCollective.size()]; + for (int m=0;m<drops.length;m++) { + drops[m] = mCollective.get(m); + } + //Return drops array if it's valid. + if (drops.length > 0) { + isValid = false; + return drops; + } + } + //Invalid or no drops, return empty array. + isValid = false; + return new ItemStack[] {}; + } + + } + + + /** + * Farm AI + */ + private static EntityPlayerMP farmerAI; + public EntityPlayerMP getFakePlayer(World world) { + return farmerAI = checkFakePlayer(world); + } + + public static EntityPlayerMP checkFakePlayer(World world) { + if (farmerAI == null) { + return new FakeFarmer(MinecraftServer.getServer().worldServerForDimension(world.provider.dimensionId)); + } + return farmerAI; + } + + public static boolean onBlockStartBreak (int x, int y, int z, World world){ + final Block wood = world.getBlock(x, y, z); + if (wood == null){ + return false; + } + if (wood.isWood(world, x, y, z) || wood.getMaterial() == Material.sponge) + if(detectTree(world, x,y,z)) { + TreeChopTask chopper = new TreeChopTask(new ChunkPosition(x, y, z), checkFakePlayer(world), 128); + FMLCommonHandler.instance().bus().register(chopper); + // custom block breaking code, don't call vanilla code + return true; + } + //return onBlockStartBreak(stack, x, y, z, player); + return false; + } + + public static boolean detectTree(World world, int pX, int pY, int pZ) { + ChunkPosition pos = null; + Stack<ChunkPosition> candidates = new Stack<>(); + candidates.add(new ChunkPosition(pX, pY, pZ)); + + while (!candidates.isEmpty()) { + ChunkPosition candidate = candidates.pop(); + int curX = candidate.chunkPosX, curY = candidate.chunkPosY, curZ = candidate.chunkPosZ; + + Block block = world.getBlock(curX, curY, curZ); + if ((pos == null || candidate.chunkPosY > pos.chunkPosY) && block.isWood(world, curX, curY, curZ)) { + pos = new ChunkPosition(curX, candidate.chunkPosY + 1, curZ); + // go up + while (world.getBlock(curX, pos.chunkPosY, curZ).isWood(world, curX, pos.chunkPosY, curZ)) { + pos = new ChunkPosition(curX, pos.chunkPosY + 1, curZ); + } + // check if we still have a way diagonally up + candidates.add(new ChunkPosition(curX + 1, pos.chunkPosY + 1, curZ )); + candidates.add(new ChunkPosition(curX , pos.chunkPosY + 1, curZ + 1)); + candidates.add(new ChunkPosition(curX - 1, pos.chunkPosY + 1, curZ )); + candidates.add(new ChunkPosition(curX , pos.chunkPosY + 1, curZ - 1)); + } + } + + // not even one match, so there were no logs. + if (pos == null) { + return false; + } + + // check if there were enough leaves around the last position + // pos now contains the block above the topmost log + // we want at least 5 leaves in the surrounding 26 blocks + int d = 3; + int leaves = 0; + for (int offX = 0; offX < d; offX++) { + for (int offY = 0; offY < d; offY++) { + for (int offZ = 0; offZ < d; offZ++) { + int xPos = pos.chunkPosX -1 + offX, yPos = pos.chunkPosY - 1 + offY, zPos = pos.chunkPosZ - 1 + offZ; + Block leaf = world.getBlock(xPos, yPos, zPos); + if (leaf != null && leaf.isLeaves(world, xPos, yPos, zPos)) { + if (++leaves >= 5) { + return true; + } + } + } + } + } + + // not enough leaves. sorreh + return false; + } + + public static class TreeChopTask { + + public final World world; + public final EntityPlayer player; + public final int blocksPerTick; + + public Queue<ChunkPosition> blocks = Lists.newLinkedList(); + public Set<ChunkPosition> visited = new THashSet<>(); + + public TreeChopTask(ChunkPosition start, EntityPlayer player, int blocksPerTick) { + this.world = player.getEntityWorld(); + this.player = player; + this.blocksPerTick = blocksPerTick; + + this.blocks.add(start); + } + + private void queueCoordinate(int x, int y, int z) { + ChunkPosition pos = new ChunkPosition(x, y, z); + if (!visited.contains(pos)) { + blocks.add(pos); + } + } + + @SubscribeEvent + public void onWorldTick(TickEvent.WorldTickEvent event) { + if (event.side.isClient()) { + finish(); + return; + } + // only if same dimension + if (event.world.provider.dimensionId != world.provider.dimensionId) { + return; + } + + // setup + int left = blocksPerTick; + //NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + + // continue running + ChunkPosition pos; + while (left > 0) { + // completely done or can't do our job anymore?! + if (blocks.isEmpty()/* || tags.getBoolean("Broken")*/) { + finish(); + return; + } + + pos = blocks.remove(); + if (!visited.add(pos)) { + continue; + } + int x = pos.chunkPosX, y = pos.chunkPosY, z = pos.chunkPosZ; + + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + + // can we harvest the block and is effective? + if (!block.isWood(world, x, y, z) || !isWoodLog(block)) { + continue; + } + + // save its neighbors + queueCoordinate(x + 1, y, z ); + queueCoordinate(x, y, z + 1); + queueCoordinate(x - 1, y, z ); + queueCoordinate(x, y, z - 1); + + // also add the layer above.. stupid acacia trees + for (int offX = 0; offX < 3; offX++) { + for (int offZ = 0; offZ < 3; offZ++) { + queueCoordinate(x - 1 + offX, y + 1, z - 1 + offZ); + } + } + + // break it, wooo! + breakExtraBlock(player.worldObj, x, y, z, 0, player, x, y, z); + left--; + } + } + + private void finish() { + // goodbye cruel world + FMLCommonHandler.instance().bus().unregister(this); + } + } + + + public static void breakExtraBlock(World world, int x, int y, int z, int sidehit, EntityPlayer playerEntity, int refX, int refY, int refZ) { + // prevent calling that stuff for air blocks, could lead to unexpected behaviour since it fires events + if (world.isAirBlock(x, y, z)) + return; + + // what? + if(!(playerEntity instanceof EntityPlayerMP)) + return; + EntityPlayerMP player = (EntityPlayerMP) playerEntity; + + // check if the block can be broken, since extra block breaks shouldn't instantly break stuff like obsidian + // or precious ores you can't harvest while mining stone + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + + // only effective materials + if (!isWoodLog(block)) + return; + + Block refBlock = world.getBlock(refX, refY, refZ); + float refStrength = ForgeHooks.blockStrength(refBlock, player, world, refX, refY, refZ); + float strength = ForgeHooks.blockStrength(block, player, world, x,y,z); + + // only harvestable blocks that aren't impossibly slow to harvest + if (!ForgeHooks.canHarvestBlock(block, player, meta) || refStrength/strength > 10f) + return; + + // send the blockbreak event + BlockEvent.BreakEvent event = ForgeHooks.onBlockBreakEvent(world, player.theItemInWorldManager.getGameType(), player, x,y,z); + if(event.isCanceled()) + return; + + if (player.capabilities.isCreativeMode) { + block.onBlockHarvested(world, x, y, z, meta, player); + if (block.removedByPlayer(world, player, x, y, z, false)) + block.onBlockDestroyedByPlayer(world, x, y, z, meta); + + // send update to client + if (!world.isRemote) { + player.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world)); + } + return; + } + + // callback to the tool the player uses. Called on both sides. This damages the tool n stuff. + player.getCurrentEquippedItem().func_150999_a(world, block, x, y, z, player); + + // server sided handling + if (!world.isRemote) { + // serverside we reproduce ItemInWorldManager.tryHarvestBlock + + // ItemInWorldManager.removeBlock + block.onBlockHarvested(world, x,y,z, meta, player); + + if(block.removedByPlayer(world, player, x,y,z, true)) // boolean is if block can be harvested, checked above + { + block.onBlockDestroyedByPlayer( world, x,y,z, meta); + block.harvestBlock(world, player, x,y,z, meta); + block.dropXpOnBlockBreak(world, x,y,z, event.getExpToDrop()); + } + + // always send block update to client + player.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world)); + } + // client sided handling + else { + //PlayerControllerMP pcmp = Minecraft.getMinecraft().playerController; + // clientside we do a "this clock has been clicked on long enough to be broken" call. This should not send any new packets + // the code above, executed on the server, sends a block-updates that give us the correct state of the block we destroy. + + // following code can be found in PlayerControllerMP.onPlayerDestroyBlock + world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12)); + if(block.removedByPlayer(world, player, x,y,z, true)) + { + block.onBlockDestroyedByPlayer(world, x,y,z, meta); + } + // callback to the tool + ItemStack itemstack = player.getCurrentEquippedItem(); + if (itemstack != null) + { + itemstack.func_150999_a(world, block, x, y, z, player); + + if (itemstack.stackSize == 0) + { + player.destroyCurrentEquippedItem(); + } + } + + // send an update to the server, so we get an update back + //if(PHConstruct.extraBlockUpdates) + //Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C07PacketPlayerDigging(2, x,y,z, Minecraft.getMinecraft().objectMouseOver.sideHit)); + } + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java new file mode 100644 index 0000000000..575e094696 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/VolumetricFlaskHelper.java @@ -0,0 +1,188 @@ +package gtPlusPlus.xmod.gregtech.common.helpers; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.xmod.gregtech.api.enums.GregtechItemList; +import gtPlusPlus.xmod.gregtech.common.Meta_GT_Proxy; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; + +public class VolumetricFlaskHelper { + + private static final Class sClassVolumetricFlask; + private static final Method sMethodGetFlaskMaxCapacity; + private static Item mFlask; + + static { + if (Meta_GT_Proxy.sDoesVolumetricFlaskExist) { + sClassVolumetricFlask = ReflectionUtils.getClass("gregtech.common.items.GT_VolumetricFlask"); + Method aMaxCapacity = null; + try { + aMaxCapacity = sClassVolumetricFlask.getDeclaredMethod("getMaxCapacity", new Class[] {}); + } + catch (NoSuchMethodException e) { + e.printStackTrace(); + CORE.crash("Secondary Error Obtaining instance of 'getMaxCapacity' from 'GT_VolumetricFlask'. Crashing."); + } + sMethodGetFlaskMaxCapacity = aMaxCapacity; + } + else { + sClassVolumetricFlask = null; + sMethodGetFlaskMaxCapacity = null; + } + } + + public static ItemStack getVolumetricFlask(int aAmount) { + ItemStack aFlask = ItemUtils.getValueOfItemList("VOLUMETRIC_FLASK", aAmount, (ItemStack) null); + return aFlask; + } + + public static ItemStack getLargeVolumetricFlask(int aAmount) { + ItemStack aFlask = GregtechItemList.VOLUMETRIC_FLASK_8k.get(aAmount); + return aFlask; + } + + public static ItemStack getGiganticVolumetricFlask(int aAmount) { + ItemStack aFlask = GregtechItemList.VOLUMETRIC_FLASK_32k.get(aAmount); + return aFlask; + } + + public static boolean isVolumetricFlask(ItemStack aStack) { + if (isNormalVolumetricFlask(aStack) || isLargeVolumetricFlask(aStack) || isGiganticVolumetricFlask(aStack)) { + return true; + } + return false; + } + + public static boolean isNormalVolumetricFlask(ItemStack aStack) { + if (mFlask == null) { + ItemStack aFlask = ItemUtils.getValueOfItemList("VOLUMETRIC_FLASK", 1, (ItemStack) null); + if (aFlask != null) { + mFlask = aFlask.getItem(); + } + } + if (aStack.getItem() == mFlask) { + return true; + } + return false; + } + + public static boolean isLargeVolumetricFlask(ItemStack aStack) { + if (GregtechItemList.VOLUMETRIC_FLASK_8k.getItem() == aStack.getItem()) { + return true; + } + return false; + } + + public static boolean isGiganticVolumetricFlask(ItemStack aStack) { + if (GregtechItemList.VOLUMETRIC_FLASK_32k.getItem() == aStack.getItem()) { + return true; + } + return false; + } + + public static int getMaxFlaskCapacity(ItemStack aStack) { + if (aStack != null && sMethodGetFlaskMaxCapacity != null) { + Item aItem = aStack.getItem(); + if (sClassVolumetricFlask.isInstance(aItem)) { + int aMaxCapacity = (int) ReflectionUtils.invokeNonBool(aItem, sMethodGetFlaskMaxCapacity, new Object[] {}); + return aMaxCapacity; + } + } + return 0; + } + + public static boolean isFlaskEmpty(ItemStack aStack) { + return getFlaskFluid(aStack) == null; + } + + public static FluidStack getFlaskFluid(ItemStack aStack) { + if (aStack.hasTagCompound()) { + NBTTagCompound nbt = aStack.getTagCompound(); + if (nbt.hasKey("Fluid", 10)) + return FluidStack.loadFluidStackFromNBT(nbt.getCompoundTag("Fluid")); + } + return null; + } + + public static void setFluid(ItemStack stack, FluidStack fluidStack) { + boolean removeFluid = (fluidStack == null) || (fluidStack.amount <= 0); + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt == null) { + if (removeFluid) + return; + stack.setTagCompound(nbt = new NBTTagCompound()); + } + if (removeFluid) { + nbt.removeTag("Fluid"); + if (nbt.hasNoTags()) { + stack.setTagCompound(null); + } + } else { + nbt.setTag("Fluid", fluidStack.writeToNBT(new NBTTagCompound())); + } + } + + public static int getFlaskCapacity(ItemStack aStack) { + int capacity = 1000; + if (aStack.hasTagCompound()) { + NBTTagCompound nbt = aStack.getTagCompound(); + if (nbt.hasKey("Capacity", 3)) + capacity = nbt.getInteger("Capacity"); + } + return Math.min(getMaxFlaskCapacity(aStack), capacity); + } + + public static boolean setNewFlaskCapacity(ItemStack aStack, int aCapacity) { + if (aStack == null || aCapacity <= 0) { + return false; + } + aCapacity = Math.min(aCapacity, getMaxFlaskCapacity(aStack)); + NBTTagCompound nbt = aStack.getTagCompound(); + if (nbt == null) { + aStack.setTagCompound(nbt = new NBTTagCompound()); + } + nbt.setInteger("Capacity", aCapacity); + return true; + } + + public static int fillFlask(ItemStack stack, FluidStack resource, boolean doFill) { + if (stack.stackSize != 1) + return 0; + if ((resource == null) || (resource.amount <= 0)) { + return 0; + } + FluidStack fluidStack = getFlaskFluid(stack); + if (fluidStack == null) { + fluidStack = new FluidStack(resource, 0); + } else if (!fluidStack.isFluidEqual(resource)) { + return 0; + } + int amount = Math.min(getMaxFlaskCapacity(stack) - fluidStack.amount, resource.amount); + if ((doFill) && (amount > 0)) { + fluidStack.amount += amount; + setFluid(stack, fluidStack); + } + return amount; + } + + public static Item generateNewFlask(String unlocalized, String english, int maxCapacity) { + Constructor aFlask = ReflectionUtils.getConstructor(sClassVolumetricFlask, new Class[] {String.class, String.class, int.class}); + if (aFlask != null) { + Object aInstance = ReflectionUtils.createNewInstanceFromConstructor(aFlask, new Object[] {unlocalized, english, maxCapacity}); + if (aInstance != null && aInstance instanceof Item) { + Item aNewFlaskItem = (Item) aInstance; + return aNewFlaskItem; + } + } + return null; + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/autocrafter/AC_Helper_Container.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/autocrafter/AC_Helper_Container.java new file mode 100644 index 0000000000..29dabaf084 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/autocrafter/AC_Helper_Container.java @@ -0,0 +1,118 @@ +package gtPlusPlus.xmod.gregtech.common.helpers.autocrafter; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.*; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.world.World; + +import gtPlusPlus.api.objects.Logger; + +public class AC_Helper_Container extends Container +{ + /** The crafting matrix inventory (3x3). */ + public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); + public IInventory craftResult = new InventoryCraftResult(); + private World worldObj; + + public InventoryCrafting getMatrix(){ + return this.craftMatrix; + } + + public boolean putItemsIntoGrid(ItemStack[] inputs){ + if (inputs.length < 9){ + return false; + } + for (int i=0;i<9;i++){ + this.putStackInSlot(i, inputs[i]); + } + this.onCraftMatrixChanged(this.craftMatrix); + return true; + } + + public AC_Helper_Container(InventoryPlayer playerInventory, World world, int x, int y, int z) + { + this.worldObj = world; + this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35)); + int l; + int i1; + + for (l = 0; l < 3; ++l) + { + for (i1 = 0; i1 < 3; ++i1) + { + this.addSlotToContainer(new Slot(this.craftMatrix, i1 + l * 3, 30 + i1 * 18, 17 + l * 18)); + } + } + + for (l = 0; l < 3; ++l) + { + for (i1 = 0; i1 < 9; ++i1) + { + this.addSlotToContainer(new Slot(playerInventory, i1 + l * 9 + 9, 8 + i1 * 18, 84 + l * 18)); + } + } + + for (l = 0; l < 9; ++l) + { + this.addSlotToContainer(new Slot(playerInventory, l, 8 + l * 18, 142)); + } + + this.onCraftMatrixChanged(this.craftMatrix); + } + + /** + * Callback for when the crafting matrix is changed. + */ + @Override + public void onCraftMatrixChanged(IInventory p_75130_1_) + { + this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); + Logger.INFO("Crafted "+this.craftResult.getStackInSlot(0)); + + } + + /** + * Called when the container is closed. + */ + @Override + public void onContainerClosed(EntityPlayer p_75134_1_) + { + super.onContainerClosed(p_75134_1_); + + if (!this.worldObj.isRemote) + { + for (int i = 0; i < 9; ++i) + { + ItemStack itemstack = this.craftMatrix.getStackInSlotOnClosing(i); + + if (itemstack != null) + { + p_75134_1_.dropPlayerItemWithRandomChoice(itemstack, false); + } + } + } + } + + @Override + public boolean canInteractWith(EntityPlayer p_75145_1_) + { + return true; + } + + /** + * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that. + */ + @Override + public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int p_82846_2_){ + ItemStack itemstack = null; + return itemstack; + } + + @Override + public boolean func_94530_a(ItemStack p_94530_1_, Slot p_94530_2_) + { + return p_94530_2_.inventory != this.craftResult && super.func_94530_a(p_94530_1_, p_94530_2_); + } +}
\ No newline at end of file diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/autocrafter/AC_Helper_Utils.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/autocrafter/AC_Helper_Utils.java new file mode 100644 index 0000000000..772ece96aa --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/autocrafter/AC_Helper_Utils.java @@ -0,0 +1,80 @@ +package gtPlusPlus.xmod.gregtech.common.helpers.autocrafter; + +import java.util.*; +import java.util.Map.Entry; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.xmod.gregtech.common.tileentities.machines.multi.production.GT4Entity_AutoCrafter; + +public class AC_Helper_Utils { + + //AC maps + public static final Map<Integer, GT4Entity_AutoCrafter> sAutocrafterMap = new HashMap<Integer, GT4Entity_AutoCrafter>(); + + //Add Crafter + public final static int addCrafter(GT4Entity_AutoCrafter AC) { + if (!sAutocrafterMap.containsValue(AC)){ + int increase = sAutocrafterMap.size()+1; + sAutocrafterMap.put(increase, AC); + Logger.INFO("[A-C] "+"Added Auto-Crafter to index on position "+increase+"."); + return increase; + } + else { + Logger.INFO("[A-C] Tried adding an Auto-Crafter to Index, but found one already there."); + } + return 0; + } + + //Remove Crafter + public final static boolean removeCrafter(int frequency) { + if (!sAutocrafterMap.isEmpty()){ + if (sAutocrafterMap.containsKey(frequency)){ + sAutocrafterMap.remove(frequency); + return true; + } + } + return false; + } + + public final static boolean removeCrafter(GT4Entity_AutoCrafter AC) { + if (!sAutocrafterMap.isEmpty()){ + if (sAutocrafterMap.containsValue(AC)){ + sAutocrafterMap.remove(getIDByCrafter(AC)); + return true; + } + } + return false; + } + + //Get Crafter + public final static GT4Entity_AutoCrafter getCrafterByID(int ID) { + if (!sAutocrafterMap.isEmpty()) { + Set<Entry<Integer, GT4Entity_AutoCrafter>> players = sAutocrafterMap.entrySet(); + Iterator<Entry<Integer, GT4Entity_AutoCrafter>> i = players.iterator(); + while (i.hasNext()) { + Entry<Integer, GT4Entity_AutoCrafter> current = i.next(); + if (current.getKey().equals(ID)) { + return current.getValue(); + } + } + } + Logger.WARNING("Failed. [getCrafterByID]"); + return null; + } + + public final static int getIDByCrafter(GT4Entity_AutoCrafter AC) { + if (!sAutocrafterMap.isEmpty()) { + Set<Entry<Integer, GT4Entity_AutoCrafter>> players = sAutocrafterMap.entrySet(); + Iterator<Entry<Integer, GT4Entity_AutoCrafter>> i = players.iterator(); + while (i.hasNext()) { + Entry<Integer, GT4Entity_AutoCrafter> current = i.next(); + if (current.getValue().equals(AC)) { + return current.getKey(); + } + } + } + Logger.WARNING("Failed. [getIDByCrafter]"); + return 0; + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/tesseract/TesseractHelper.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/tesseract/TesseractHelper.java new file mode 100644 index 0000000000..a3a116fea6 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/tesseract/TesseractHelper.java @@ -0,0 +1,263 @@ +package gtPlusPlus.xmod.gregtech.common.helpers.tesseract; + +import static gtPlusPlus.core.lib.CORE.*; + +import java.util.*; +import java.util.Map.Entry; + +import net.minecraft.entity.player.EntityPlayer; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.xmod.gregtech.common.tileentities.automation.GT_MetaTileEntity_TesseractGenerator; +import gtPlusPlus.xmod.gregtech.common.tileentities.automation.GT_MetaTileEntity_TesseractTerminal; + +public class TesseractHelper { + + /** + * Tesseract Generator Helpers + * + * @param player + * @return + */ + + //Checks if a Generator is owned by a player. + public final static boolean isGeneratorOwnedByPlayer(EntityPlayer player, + GT_MetaTileEntity_TesseractGenerator generator) { + if (player == null){ + Logger.WARNING("Failed. [isGeneratorOwnedByPlayer]"); + return false; + } + //Utils.LOG_WARNING("Success. [isGeneratorOwnedByPlayer] 1"); + UUID playerIdentifier = player.getUniqueID(); + if (!sTesseractGeneratorOwnershipMap.isEmpty() && playerIdentifier != null) { + //Utils.LOG_WARNING("Success. [isGeneratorOwnedByPlayer] 2"); + Map<Integer, GT_MetaTileEntity_TesseractGenerator> generators = getGeneratorOwnershipByPlayer(player); + Set<Entry<Integer, GT_MetaTileEntity_TesseractGenerator>> players = generators.entrySet(); + Iterator<Entry<Integer, GT_MetaTileEntity_TesseractGenerator>> i = players.iterator(); + while (i.hasNext()) { + //Utils.LOG_WARNING("Success. [isGeneratorOwnedByPlayer] 3"); + Entry<Integer, GT_MetaTileEntity_TesseractGenerator> current = i.next(); + if (current.getValue().equals(generator)) { + //Utils.LOG_WARNING("Success. [isGeneratorOwnedByPlayer] 4"); + return true; + } + } + } + Logger.WARNING("Failed. [isGeneratorOwnedByPlayer]"); + return false; + } + + //Saves A Generator to the Players UUID map along with the Freq. + public final static boolean setGeneratorOwnershipByPlayer(EntityPlayer player, int freq, + GT_MetaTileEntity_TesseractGenerator generator) { + if (player == null){ + return false; + } + UUID playerIdentifier = player.getUniqueID(); + Logger.WARNING("Setting Generator on "+freq+" for "+player.getDisplayName()+"."); + if (playerIdentifier != null) { + Map<Integer, GT_MetaTileEntity_TesseractGenerator> playerOwned = sTesseractGeneratorOwnershipMap + .get(playerIdentifier); + if (playerOwned == null || playerOwned.isEmpty()) { + Map<Integer, GT_MetaTileEntity_TesseractGenerator> newOwnershipMap = new HashMap<Integer, GT_MetaTileEntity_TesseractGenerator>(); + newOwnershipMap.put(freq, generator); + sTesseractGeneratorOwnershipMap.put(playerIdentifier, newOwnershipMap); + Logger.WARNING("Success! [Empty Map]"); + return true; + } else if (sTesseractGeneratorOwnershipMap.containsKey(playerIdentifier)) { + Map<Integer, GT_MetaTileEntity_TesseractGenerator> ownershipMap = sTesseractGeneratorOwnershipMap + .get(playerIdentifier); + if (!ownershipMap.containsKey(freq)){ + ownershipMap.put(freq, generator); + } + ownershipMap.put(freq, generator); + sTesseractGeneratorOwnershipMap.put(playerIdentifier, ownershipMap); + Logger.WARNING("Success!"); + return true; + } + } + Logger.WARNING("Failed. [setGeneratorOwnershipByPlayer]"); + return false; + } + + //Gets Generator based on Frequency. + public final static GT_MetaTileEntity_TesseractGenerator getGeneratorByFrequency(EntityPlayer player, + int freq) { + if (player == null){ + return null; + } + UUID playerIdentifier = player.getUniqueID(); + Logger.WARNING("Getting Generator on "+freq+" for "+player.getDisplayName()+"."); + if (!sTesseractGeneratorOwnershipMap.isEmpty() && playerIdentifier != null) { + //Utils.LOG_WARNING("Success. [getGeneratorByFrequency] 1"); + Map<Integer, GT_MetaTileEntity_TesseractGenerator> generators = getGeneratorOwnershipByPlayer(player); + Set<Entry<Integer, GT_MetaTileEntity_TesseractGenerator>> players = generators.entrySet(); + Iterator<Entry<Integer, GT_MetaTileEntity_TesseractGenerator>> i = players.iterator(); + while (i.hasNext()) { + //Utils.LOG_WARNING("Success. [getGeneratorByFrequency] 2"); + Entry<Integer, GT_MetaTileEntity_TesseractGenerator> current = i.next(); + if (current.getKey().equals(freq)) { + //Utils.LOG_WARNING("Success. [getGeneratorByFrequency] 3"); + Logger.WARNING("Success!"); + return current.getValue(); + } + } + } + Logger.WARNING("Failed. [getGeneratorByFrequency]"); + return null; + } + + //Remove Tesseract Generator + public final static boolean removeGenerator(EntityPlayer player, int frequency) { + if (player == null){ + return false; + } + UUID playerIdentifier = player.getUniqueID(); + if (!sTesseractGeneratorOwnershipMap.isEmpty() && playerIdentifier != null) { + sTesseractGeneratorOwnershipMap.get(playerIdentifier).remove(frequency); + return true; + } + return false; + } + + /** + * + * Tesseract Terminal Helpers + * + * @param player + * @return + */ + + //Checks if a Terminal is owned by a player. + public final static boolean isTerminalOwnedByPlayer(EntityPlayer player, + GT_MetaTileEntity_TesseractTerminal generator) { + if (player == null){ + return false; + } + UUID playerIdentifier = player.getUniqueID(); + if (!sTesseractTerminalOwnershipMap.isEmpty() && playerIdentifier != null) { + Map<Integer, GT_MetaTileEntity_TesseractTerminal> generators = getTerminalOwnershipByPlayer(player); + Set<Entry<Integer, GT_MetaTileEntity_TesseractTerminal>> players = generators.entrySet(); + Iterator<Entry<Integer, GT_MetaTileEntity_TesseractTerminal>> i = players.iterator(); + while (i.hasNext()) { + Entry<Integer, GT_MetaTileEntity_TesseractTerminal> current = i.next(); + if (current.getValue().equals(generator)) { + return true; + } + } + } + return false; + } + + //Saves A Terminal to the Players UUID map along with the Freq. + public final static boolean setTerminalOwnershipByPlayer(EntityPlayer player, int freq, + GT_MetaTileEntity_TesseractTerminal generator) { + if (player == null){ + return false; + } + UUID playerIdentifier = player.getUniqueID(); + if (playerIdentifier != null) { + Logger.WARNING("Setting Terminal on "+freq+" for "+player.getDisplayName()+"."); + Map<Integer, GT_MetaTileEntity_TesseractTerminal> playerOwned = sTesseractTerminalOwnershipMap + .get(playerIdentifier); + if (playerOwned == null || playerOwned.isEmpty()) { + Map<Integer, GT_MetaTileEntity_TesseractTerminal> newOwnershipMap = new HashMap<Integer, GT_MetaTileEntity_TesseractTerminal>(); + newOwnershipMap.put(freq, generator); + sTesseractTerminalOwnershipMap.put(playerIdentifier, newOwnershipMap); + Logger.WARNING("Success! [Empty Map]"); + return true; + } else if (sTesseractTerminalOwnershipMap.containsKey(playerIdentifier)) { + Map<Integer, GT_MetaTileEntity_TesseractTerminal> ownershipMap = sTesseractTerminalOwnershipMap + .get(playerIdentifier); + if (!ownershipMap.containsKey(freq)){ + ownershipMap.put(freq, generator); + } + sTesseractTerminalOwnershipMap.put(playerIdentifier, ownershipMap); + Logger.WARNING("Success!"); + return true; + } + } + Logger.WARNING("Failed. [setTerminalOwnershipByPlayer]"); + return false; + } + + //Gets Terminal based on Frequency. + public final static GT_MetaTileEntity_TesseractTerminal getTerminalByFrequency(EntityPlayer player, + int freq) { + if (player == null){ + return null; + } + UUID playerIdentifier = player.getUniqueID(); + Logger.WARNING("Getting Terminal on "+freq+" for "+player.getDisplayName()+"."); + if (!sTesseractTerminalOwnershipMap.isEmpty() && playerIdentifier != null) { + Map<Integer, GT_MetaTileEntity_TesseractTerminal> generators = getTerminalOwnershipByPlayer(player); + Set<Entry<Integer, GT_MetaTileEntity_TesseractTerminal>> players = generators.entrySet(); + Iterator<Entry<Integer, GT_MetaTileEntity_TesseractTerminal>> i = players.iterator(); + while (i.hasNext()) { + Entry<Integer, GT_MetaTileEntity_TesseractTerminal> current = i.next(); + if (current.getKey().equals(freq)) { + Logger.WARNING("Success!"); + return current.getValue(); + } + } + } + Logger.WARNING("Failed. [getTerminalByFrequency]"); + return null; + } + + //Remove Tesseract Terminal + public final static boolean removeTerminal(EntityPlayer player, int frequency) { + if (player == null){ + return false; + } + UUID playerIdentifier = player.getUniqueID(); + if (!sTesseractTerminalOwnershipMap.isEmpty() && playerIdentifier != null) { + sTesseractTerminalOwnershipMap.get(playerIdentifier).remove(frequency); + return true; + } + return false; + } + + /** + * + * Internal Methods + * + */ + + private final static Map<Integer, GT_MetaTileEntity_TesseractGenerator> getGeneratorOwnershipByPlayer( + EntityPlayer player) { + UUID playerIdentifier = player.getUniqueID(); + if (!sTesseractGeneratorOwnershipMap.isEmpty() && playerIdentifier != null) { + Set<Entry<UUID, Map<Integer, GT_MetaTileEntity_TesseractGenerator>>> players = sTesseractGeneratorOwnershipMap + .entrySet(); + Iterator<Entry<UUID, Map<Integer, GT_MetaTileEntity_TesseractGenerator>>> i = players.iterator(); + while (i.hasNext()) { + Entry<UUID, Map<Integer, GT_MetaTileEntity_TesseractGenerator>> current = i.next(); + if (current.getKey().compareTo(playerIdentifier) == 0) { + return current.getValue(); + } + + } + } + return null; + } + + private final static Map<Integer, GT_MetaTileEntity_TesseractTerminal> getTerminalOwnershipByPlayer( + EntityPlayer player) { + UUID playerIdentifier = player.getUniqueID(); + if (!sTesseractTerminalOwnershipMap.isEmpty() && playerIdentifier != null) { + Set<Entry<UUID, Map<Integer, GT_MetaTileEntity_TesseractTerminal>>> players = sTesseractTerminalOwnershipMap + .entrySet(); + Iterator<Entry<UUID, Map<Integer, GT_MetaTileEntity_TesseractTerminal>>> i = players.iterator(); + while (i.hasNext()) { + Entry<UUID, Map<Integer, GT_MetaTileEntity_TesseractTerminal>> current = i.next(); + if (current.getKey().compareTo(playerIdentifier) == 0) { + return current.getValue(); + } + + } + } + return null; + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/treefarm/TreeGenerator.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/treefarm/TreeGenerator.java new file mode 100644 index 0000000000..bb40c9b379 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/helpers/treefarm/TreeGenerator.java @@ -0,0 +1,386 @@ +package gtPlusPlus.xmod.gregtech.common.helpers.treefarm; + +import java.util.Random; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.api.objects.minecraft.FakeBlockPos; +import gtPlusPlus.api.objects.minecraft.FakeWorld; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.util.math.MathUtils; +import net.minecraft.block.Block; +import net.minecraft.block.BlockSapling; +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; +import net.minecraftforge.common.util.ForgeDirection; + +public class TreeGenerator { + + private static final FakeTreeInFakeWorldGenerator mTreeData; + + static { + Logger.WARNING("Created Fake Tree Generator."); + mTreeData = new FakeTreeInFakeWorldGenerator(); + } + + + public TreeGenerator() { + if (!mTreeData.hasGenerated) { + mTreeData.generate(null, CORE.RANDOM, 0, 0, 0); + } + } + + public AutoMap<ItemStack> generateOutput(int aTreeSize){ + AutoMap<ItemStack> aOutputMap = mTreeData.getOutputFromTree(); + if (aOutputMap != null && aOutputMap.size() > 0) { + Logger.WARNING("Valid tree data output"); + return aOutputMap; + } + Logger.WARNING("Invalid tree data output"); + return new AutoMap<ItemStack>(); + } + + public static class FakeTreeInFakeWorldGenerator extends WorldGenAbstractTree + { + /** The minimum height of a generated tree. */ + private final int minTreeHeight; + /** True if this tree should grow Vines. */ + private final boolean vinesGrow; + /** The metadata value of the wood to use in tree generation. */ + private final int metaWood; + /** The metadata value of the leaves to use in tree generation. */ + private final int metaLeaves; + + private final AutoMap<FakeWorld> mFakeWorld; + private final int mTreesToGenerate; + + private int mCurrentGeneratorIteration = 0; + + private boolean hasGenerated = false; + private AutoMap<ItemStack> aOutputsFromGenerator = new AutoMap<ItemStack>(); + + public FakeTreeInFakeWorldGenerator() + { + this(4, 0, 0, false, 5000); + } + + public FakeTreeInFakeWorldGenerator(int aMinHeight, int aWoodMeta, int aLeafMeta, boolean aVines, int aTreeCount) + { + super(false); + this.minTreeHeight = aMinHeight; + this.metaWood = aWoodMeta; + this.metaLeaves = aLeafMeta; + this.vinesGrow = aVines; + this.mFakeWorld = new AutoMap<FakeWorld>(); + this.mTreesToGenerate = aTreeCount; + Logger.WARNING("Created Fake Tree In Fake World Instance."); + } + + + public AutoMap<ItemStack> getOutputFromTree(){ + if (!hasGenerated) { + Logger.WARNING("Generating Tree sample data"); + generate(null, CORE.RANDOM, 0, 0, 0); + } + AutoMap<ItemStack> aOutputMap = new AutoMap<ItemStack>(); + int aRandomTreeID = MathUtils.randInt(0, this.mFakeWorld.size()-1); + FakeWorld aWorld = this.mFakeWorld.get(aRandomTreeID); + if (aWorld != null) { + //Logger.WARNING("Getting all block data from fake world"); + aOutputMap = aWorld.getAllBlocksStoredInFakeWorld(); + } + return aOutputMap; + + } + + @Override + protected boolean func_150523_a(Block p_150523_1_) + { + return p_150523_1_.getMaterial() == Material.air || p_150523_1_.getMaterial() == Material.leaves || p_150523_1_ == Blocks.grass || p_150523_1_ == Blocks.dirt || p_150523_1_ == Blocks.log || p_150523_1_ == Blocks.log2 || p_150523_1_ == Blocks.sapling || p_150523_1_ == Blocks.vine; + } + + @Override + protected boolean isReplaceable(World world, int x, int y, int z) + { + FakeWorld aWorld = getWorld(); + Block block = aWorld.getBlock(x, y, z); + return block.isAir(null, x, y, z) || block.isLeaves(null, x, y, z) || block.isWood(null, x, y, z) || func_150523_a(block); + } + + @Override + public boolean generate(World world, Random aRand, int aWorldX, int aWorldRealY, int aWorldZ){ + //Only Generate Once - This object is Cached + if (hasGenerated) { + return hasGenerated; + } + else { + for (int yy=0;yy<mTreesToGenerate;yy++) { + generateTree(0, 0, 0); + mCurrentGeneratorIteration++; + } + hasGenerated = true; + if (this.mFakeWorld.size() > 0) { + for (FakeWorld aWorld : this.mFakeWorld) { + for (ItemStack aBlockInFakeWorld : aWorld.getAllBlocksStoredInFakeWorld()) { + aOutputsFromGenerator.add(aBlockInFakeWorld); + } + } + return true; + } + else { + return false; + } + } + } + + private FakeWorld aFakeWorld; + + public FakeWorld getWorld() { + FakeWorld aWorld = this.mFakeWorld.get(mCurrentGeneratorIteration); + if (aWorld == null) { + this.mFakeWorld.set(mCurrentGeneratorIteration, new FakeWorld(200)); + aWorld = this.mFakeWorld.get(mCurrentGeneratorIteration); + } + return aWorld; + } + + public boolean generateTree(int aWorldX, int aWorldRealY, int aWorldZ) { + FakeWorld aWorld = getWorld(); + + //Set some static values + + Logger.WARNING("Stepping through generateTree [0]"); + //Dummy Value + int aWorldY = 10; + + int l = CORE.RANDOM.nextInt(3) + this.minTreeHeight; + boolean flag = true; + + if (aWorldY >= 1 && aWorldY + l + 1 <= 256) + { + Logger.WARNING("Stepping through generateTree [1]"); + byte b0; + int k1; + Block block; + + for (int i1 = aWorldY; i1 <= aWorldY + 1 + l; ++i1) + { + b0 = 1; + + if (i1 == aWorldY) + { + b0 = 0; + } + + if (i1 >= aWorldY + 1 + l - 2) + { + b0 = 2; + } + + for (int j1 = aWorldX - b0; j1 <= aWorldX + b0 && flag; ++j1) + { + for (k1 = aWorldZ - b0; k1 <= aWorldZ + b0 && flag; ++k1) + { + if (i1 >= 0 && i1 < 256) + { + block = aWorld.getBlock(j1, i1, k1); + + if (!this.isReplaceable(null, j1, i1, k1)) + { + flag = false; + } + } + else + { + flag = false; + } + } + } + } + + if (!flag) + { + Logger.WARNING("Stepping through generateTree [2]"); + return false; + } + else + { + Logger.WARNING("Stepping through generateTree [3]"); + Block block2 = aWorld.getBlock(aWorldX, aWorldY - 1, aWorldZ); + FakeBlockPos aBlockToGrowPlantOn = aWorld.getBlockAtCoords(aWorldX, aWorldY-1, aWorldZ); + + boolean isSoil = block2.canSustainPlant(aWorld, aWorldX, aWorldY - 1, aWorldZ, ForgeDirection.UP, (BlockSapling)Blocks.sapling); + if (/*isSoil &&*/ aWorldY < 256 - l - 1) + { + Logger.WARNING("Stepping through generateTree [4]"); + aBlockToGrowPlantOn.onPlantGrow(aWorld, aWorldX, aWorldY - 1, aWorldZ, aWorldX, aWorldY, aWorldZ); + b0 = 3; + byte b1 = 0; + int l1; + int i2; + int j2; + int i3; + + for (k1 = aWorldY - b0 + l; k1 <= aWorldY + l; ++k1) + { + i3 = k1 - (aWorldY + l); + l1 = b1 + 1 - i3 / 2; + + for (i2 = aWorldX - l1; i2 <= aWorldX + l1; ++i2) + { + j2 = i2 - aWorldX; + + for (int k2 = aWorldZ - l1; k2 <= aWorldZ + l1; ++k2) + { + int l2 = k2 - aWorldZ; + + if (Math.abs(j2) != l1 || Math.abs(l2) != l1 || CORE.RANDOM.nextInt(2) != 0 && i3 != 0) + { + Block block1 = aWorld.getBlock(i2, k1, k2); + + if (block1.isAir(null, i2, k1, k2) || block1.isLeaves(null, i2, k1, k2)) + { + this.setBlockAndNotifyAdequately(aWorld, i2, k1, k2, Blocks.leaves, this.metaLeaves); + } + } + } + } + } + Logger.WARNING("Stepping through generateTree [5]"); + + for (k1 = 0; k1 < l; ++k1) + { + block = aWorld.getBlock(aWorldX, aWorldY + k1, aWorldZ); + + if (block.isAir(null, aWorldX, aWorldY + k1, aWorldZ) || block.isLeaves(null, aWorldX, aWorldY + k1, aWorldZ)) + { + this.setBlockAndNotifyAdequately(aWorld, aWorldX, aWorldY + k1, aWorldZ, Blocks.log, this.metaWood); + + if (this.vinesGrow && k1 > 0) + { + if (CORE.RANDOM.nextInt(3) > 0 && aWorld.isAirBlock(aWorldX - 1, aWorldY + k1, aWorldZ)) + { + this.setBlockAndNotifyAdequately(aWorld, aWorldX - 1, aWorldY + k1, aWorldZ, Blocks.vine, 8); + } + + if (CORE.RANDOM.nextInt(3) > 0 && aWorld.isAirBlock(aWorldX + 1, aWorldY + k1, aWorldZ)) + { + this.setBlockAndNotifyAdequately(aWorld, aWorldX + 1, aWorldY + k1, aWorldZ, Blocks.vine, 2); + } + + if (CORE.RANDOM.nextInt(3) > 0 && aWorld.isAirBlock(aWorldX, aWorldY + k1, aWorldZ - 1)) + { + this.setBlockAndNotifyAdequately(aWorld, aWorldX, aWorldY + k1, aWorldZ - 1, Blocks.vine, 1); + } + + if (CORE.RANDOM.nextInt(3) > 0 && aWorld.isAirBlock(aWorldX, aWorldY + k1, aWorldZ + 1)) + { + this.setBlockAndNotifyAdequately(aWorld, aWorldX, aWorldY + k1, aWorldZ + 1, Blocks.vine, 4); + } + } + } + } + Logger.WARNING("Stepping through generateTree [6]"); + + if (this.vinesGrow) + { + Logger.WARNING("Stepping through generateTree [7]"); + for (k1 = aWorldY - 3 + l; k1 <= aWorldY + l; ++k1) + { + i3 = k1 - (aWorldY + l); + l1 = 2 - i3 / 2; + + for (i2 = aWorldX - l1; i2 <= aWorldX + l1; ++i2) + { + for (j2 = aWorldZ - l1; j2 <= aWorldZ + l1; ++j2) + { + if (aWorld.getBlock(i2, k1, j2).isLeaves(null, i2, k1, j2)) + { + if (CORE.RANDOM.nextInt(4) == 0 && aWorld.getBlock(i2 - 1, k1, j2).isAir(null, i2 - 1, k1, j2)) + { + this.growVines(aWorld, i2 - 1, k1, j2, 8); + } + + if (CORE.RANDOM.nextInt(4) == 0 && aWorld.getBlock(i2 + 1, k1, j2).isAir(null, i2 + 1, k1, j2)) + { + this.growVines(aWorld, i2 + 1, k1, j2, 2); + } + + if (CORE.RANDOM.nextInt(4) == 0 && aWorld.getBlock(i2, k1, j2 - 1).isAir(null, i2, k1, j2 - 1)) + { + this.growVines(aWorld, i2, k1, j2 - 1, 1); + } + + if (CORE.RANDOM.nextInt(4) == 0 && aWorld.getBlock(i2, k1, j2 + 1).isAir(null, i2, k1, j2 + 1)) + { + this.growVines(aWorld, i2, k1, j2 + 1, 4); + } + } + } + } + } + Logger.WARNING("Stepping through generateTree [8]"); + + if (CORE.RANDOM.nextInt(5) == 0 && l > 5) + { + for (k1 = 0; k1 < 2; ++k1) + { + for (i3 = 0; i3 < 4; ++i3) + { + if (CORE.RANDOM.nextInt(4 - k1) == 0) + { + l1 = CORE.RANDOM.nextInt(3); + this.setBlockAndNotifyAdequately(aWorld, aWorldX + Direction.offsetX[Direction.rotateOpposite[i3]], aWorldY + l - 5 + k1, aWorldZ + Direction.offsetZ[Direction.rotateOpposite[i3]], Blocks.cocoa, l1 << 2 | i3); + } + } + } + } + } + Logger.WARNING("Stepping through generateTree [9]"); + return true; + } + else + { + Logger.WARNING("Stepping through generateTree [10]"); + return false; + } + } + } + else + { + Logger.WARNING("Stepping through generateTree [11]"); + return false; + } + } + + /** + * Grows vines downward from the given block for a given length. Args: World, x, starty, z, vine-length + */ + private void growVines(FakeWorld aWorld, int aX, int aY, int aZ, int aMeta) + { + int aLoopSize = vinesGrow ? MathUtils.randInt(0, 4) : 0; + for (int i=0;i<aLoopSize;i++) { + this.setBlockAndNotifyAdequately(aWorld, aX, aY, aZ, Blocks.vine, aMeta); + } + } + + @Override + protected void setBlockAndNotifyAdequately(World aWorld, int aX, int aY, int aZ, Block aBlock, int aMeta) { + setBlockAndNotifyAdequately(getWorld(), aX, aY, aZ, aBlock, aMeta); + } + + protected void setBlockAndNotifyAdequately(FakeWorld aWorld, int aX, int aY, int aZ, Block aBlock, int aMeta) { + if (aBlock != null && (aMeta >= 0 && aMeta <= Short.MAX_VALUE)) { + Logger.WARNING("Setting block "+aX+", "+aY+", "+aZ+" | "+aBlock.getLocalizedName()+" | "+aMeta); + aWorld.setBlockAtCoords(aX, aY, aZ, aBlock, aMeta); + //aOutputsFromGenerator.put(ItemUtils.simpleMetaStack(aBlock, aMeta, 1)); + } + } + } + + +} |