/* This file is part of Project-Zed. Project-Zed is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Project-Zed is * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along * with Project-Zed. If not, see <http://www.gnu.org/licenses/> */ package com.projectzed.mod.tileentity.digger; import com.hockeyhurd.hcorelib.api.math.Rect; import com.hockeyhurd.hcorelib.api.math.Vector2; import com.hockeyhurd.hcorelib.api.math.Vector3; import com.hockeyhurd.hcorelib.api.math.VectorHelper; import com.hockeyhurd.hcorelib.api.util.BlockUtils; import com.projectzed.api.item.IItemUpgradeComponent; import com.projectzed.api.tileentity.digger.AbstractTileEntityDigger; import com.projectzed.api.util.EnumFilterType; import com.projectzed.api.util.IItemFilterComponent; import com.projectzed.mod.ProjectZed; import com.projectzed.mod.block.BlockQuarryMarker; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.math.BlockPos; import java.util.ArrayList; import java.util.List; /** * Base class for all quarries. * * @author hockeyhurd * @version Jun 18, 2015 */ public class TileEntityQuarryBase extends AbstractTileEntityDigger implements IItemFilterComponent { protected List<ItemStack> filterStacks; protected int filterMaxSize = 0; // 3 * 3; protected EnumFilterType itemFilterType; /** * @param name name of quarry as required by parent class. */ public TileEntityQuarryBase(String name) { super(name); this.originalEnergyBurnRate = this.energyBurnRate = 0x200; // 512 this.filterStacks = new ArrayList<ItemStack>(filterMaxSize); this.itemFilterType = EnumFilterType.WHITELIST; } @Override protected void initContentsArray() { this.slots = new ItemStack[2 * 9 + filterMaxSize + getSizeUpgradeSlots()]; } @Override protected void initBlackList() { this.blackList = new Material[] { Material.AIR, Material.LAVA, Material.WATER, Material.PLANTS, Material.VINE, Material.WEB }; } @Override public boolean isItemValidForSlot(int slot, ItemStack stack) { return stack != null && stack.stackSize > 0 && slot >= getSizeInventory() - getSizeUpgradeSlots() && slot < getSizeInventory() && stack .getItem() instanceof IItemUpgradeComponent && canInsertItemUpgrade((IItemUpgradeComponent) stack.getItem(), stack); } @Override public int[] getSlotsForFace(EnumFacing side) { if (openSides[side.ordinal()] == 0) return new int[0]; int[] ret = new int[getSizeInventory() - getSizeUpgradeSlots() - filterMaxSize]; for (int i = 0; i < ret.length; i++) { ret[i] = i; } return ret; } @Override protected void importContents() { if (!worldObj.isRemote) { if (worldObj.getTotalWorldTime() % 20L == 0) { // ProjectZed.logHelper.info("energyBurnRate:", energyBurnRate); isSilkTouch = false; waitTime = originalWaitTime; energyBurnRate = originalEnergyBurnRate; if (!isDone()) { ItemStack[] upgrades = getCurrentUpgrades(); if (upgrades.length > 0) { float max = Float.MIN_VALUE; IItemUpgradeComponent comp; for (ItemStack stack : upgrades) { if (stack != null && stack.stackSize > 0) { comp = ((IItemUpgradeComponent) stack.getItem()); if (!comp.effectOnDiggers(this, true)) continue; else { for (int i = 0; i < Math.min(stack.stackSize, comp.maxSize()); i++) { comp.effectOnDiggers(this, false); } } // if (!isSilkTouch && comp instanceof ItemUpgradeSilkTouch) isSilkTouch = true; max = Math.max(max, comp.energyBurnRateRelativeToSize(stack.stackSize, originalEnergyBurnRate)); } } energyBurnRate = (int) Math.max(Math.ceil(max), originalEnergyBurnRate); } } } } } @Override protected void exportContents() { if (!worldObj.isRemote) { // everything that updates every tick: if (!this.isDone && isActiveFromRedstoneSignal() && this.storedPower - this.energyBurnRate >= 0) { doQuarryWork(); } // everything that gets called once per second. if (worldObj.getTotalWorldTime() % 20L == 0) { handleItemSidedIO(); } } if (quarryRect != null && currentMineVec != null) { worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, currentMineVec.x + 0.5d, currentMineVec.y + 0.5d, currentMineVec.z + 0.5d, 0d, 0d, 0d); worldObj.spawnParticle(EnumParticleTypes.FLAME, currentMineVec.x + 0.5d, currentMineVec.y + 0.5d, currentMineVec.z + 0.5d, 0d, 0d, 0d); } } /** * Method to handle quarry work. */ protected void doQuarryWork() { // if (currentMineVec != null) ProjectZed.logHelper.info(currentMineVec.toString()); // if (quarryRect != null) ProjectZed.logHelper.info(quarryRect.getArea()); if (quarryRect == null || quarryRect.getArea() < 25d) { Block currentBlock; Vector2<Integer>[] markerCons; Vector3<Integer> currentVec = new Vector3<Integer>(); for (int i = 2; i < EnumFacing.VALUES.length; i++) { currentVec.x = worldVec().x + EnumFacing.getFront(i).getFrontOffsetX(); currentVec.y = worldVec().y; currentVec.z = worldVec().z + EnumFacing.getFront(i).getFrontOffsetZ(); // currentBlock = worldObj.getBlock(currentVec.x, currentVec.y, currentVec.z); currentBlock = BlockUtils.getBlock(worldObj, currentVec).getBlock(); if (currentBlock != null && currentBlock == ProjectZed.quarryMarker) { markerCons = ((BlockQuarryMarker) currentBlock).getBounds(worldObj, currentVec); if (markerCons != null && markerCons.length == 4) { markerCons[0].x++; markerCons[0].y++; markerCons[3].x--; markerCons[3].y--; quarryRect = new Rect<Integer>(markerCons[0], markerCons[3]); return; } } } } else { if (currentTickTime > 0) currentTickTime--; else { if (currentMineVec == null) currentMineVec = new Vector3<Integer>(quarryRect.min.x, pos.getY() - 1, quarryRect.min.y); if (worldObj.getTileEntity(VectorHelper.toBlockPos(currentMineVec)) != null) { incrementMineVec(); return; } final BlockPos currentMinePos = VectorHelper.toBlockPos(currentMineVec); IBlockState currentBlock = BlockUtils.getBlock(worldObj, currentMineVec); int metaData = BlockUtils.getBlockMetadata(worldObj, currentMineVec); // ProjectZed.logHelper.info("current mat:", currentBlock.getMaterial(), blackListContains(currentBlock.getMaterial(), true)); if (currentBlock != ProjectZed.quarryMarker && !blackListContains(currentBlock.getMaterial(), true) && currentBlock.getBlockHardness(worldObj, currentMinePos) > 0f) { List<ItemStack> dropsList; if (!isSilkTouch) dropsList = currentBlock.getBlock().getDrops(worldObj, currentMinePos, currentBlock, 0); else { dropsList = new ArrayList<ItemStack>(1); dropsList.add(new ItemStack(currentBlock.getBlock(), 1)); } if (dropsList != null && !dropsList.isEmpty()) { boolean result = false; for (int i = 0; i < dropsList.size(); i++) { if (dropsList.get(i) == null || dropsList.get(i).getItem() == null || dropsList.get(i).stackSize == 0) return; result = this.addItemStackToSlots(dropsList.get(i), true); if (!result) { ProjectZed.logHelper.info("I returned false!"); return; } } if (result) { for (int i = 0; i < dropsList.size(); i++) { this.addItemStackToSlots(dropsList.get(i), false); } BlockUtils.setBlockToAir(worldObj, currentMineVec); } } } incrementMineVec(); // reset tick timer: currentTickTime = waitTime; } } } /** * Method to increment quarry mining vector. */ protected void incrementMineVec() { if (currentMineVec != null && quarryRect != null) { this.storedPower -= this.energyBurnRate; if (currentMineVec.x < quarryRect.max.x) { currentMineVec.x++; } else /*if (currentMineVec.x == quarryRect.max.x)*/ { currentMineVec.x = quarryRect.min.x; if (currentMineVec.z < quarryRect.max.y) { currentMineVec.z++; // currentMineVec.x = quarryRect.min.x; } else /*if (currentMineVec.z == quarryRect.max.y)*/ { // currentMineVec.x = quarryRect.min.x; currentMineVec.z = quarryRect.min.y; if (currentMineVec.y > 1) currentMineVec.y--; else this.isDone = true; } } } } @Override public ItemStack[] getItemFilter() { return filterStacks.toArray(new ItemStack[getItemFilterSize()]); } @Override public int getItemFilterSize() { return filterStacks.size(); } @Override public void addToItemFilter(ItemStack stack) { if (filterStacks.size() < filterMaxSize && !filterContainsItemStack(stack, false)) filterStacks.add(stack); } @Override public void removeFromItemFilter(ItemStack stack) { if (!filterStacks.isEmpty() && filterContainsItemStack(stack, false)) filterStacks.remove(stack); } @Override public boolean filterContainsItemStack(ItemStack stack) { return filterContainsItemStack(stack, false); } @Override public boolean filterContainsItemStack(ItemStack stack, boolean stackSizeSp) { if (filterStacks.isEmpty()) return false; for (int i = 0; i < filterStacks.size(); i++) { if (!stackSizeSp && filterStacks.get(i).isItemEqual(stack)) return true; else if (stackSizeSp && ItemStack.areItemStacksEqual(filterStacks.get(i), stack)) return true; } return false; } @Override public EnumFilterType getItemFilterType() { return this.itemFilterType; } @Override public void setItemFilterType(EnumFilterType type) { if (type == EnumFilterType.BLACKLIST || type == EnumFilterType.WHITELIST) this.itemFilterType = type; } }