diff --git a/src/main/java/resonantinduction/api/fluid/IDrain.java b/src/main/java/resonantinduction/api/fluid/IDrain.java index c71575a4..1ecc67e2 100644 --- a/src/main/java/resonantinduction/api/fluid/IDrain.java +++ b/src/main/java/resonantinduction/api/fluid/IDrain.java @@ -16,29 +16,9 @@ import calclavia.lib.prefab.tile.IRotatable; */ public interface IDrain extends IFluidHandler, IRotatable { - /** - * Can the pump drain in the area in the given direction - * - * @param direction - not the side of the block but rather the direction the block is facing - * @return true if it can - */ - public boolean canDrain(ForgeDirection direction); - - /** - * Can the pump fill in the area in the given direction - * - * @param direction - not the side of the block but rather the direction the block is facing - * @return true if it can - */ - public boolean canFill(ForgeDirection direction); - /** Gets the list of fillable blocks */ public Set getFillList(); /** Gets the list of drainable blocks */ - public Set getFluidList(); - - /** Call this after the drain was used to edit a block at the location */ - public void onUse(Vector3 vec); - + public Set getDrainList(); } diff --git a/src/main/java/resonantinduction/core/resource/ResourceGenerator.java b/src/main/java/resonantinduction/core/resource/ResourceGenerator.java index e9f28b6c..bbab2e11 100644 --- a/src/main/java/resonantinduction/core/resource/ResourceGenerator.java +++ b/src/main/java/resonantinduction/core/resource/ResourceGenerator.java @@ -36,6 +36,7 @@ public class ResourceGenerator public static final ResourceGenerator INSTANCE = new ResourceGenerator(); public static final Set materialNames = new HashSet(); public static final HashMap materialColors = new HashMap(); + public static final HashMap itemColorMap = new HashMap(); @ForgeSubscribe public void oreRegisterEvent(OreRegisterEvent evt) @@ -105,50 +106,7 @@ public class ResourceGenerator for (ItemStack ingotStack : OreDictionary.getOres("ingot" + ingotName.substring(0, 1).toUpperCase() + ingotName.substring(1))) { Item theIngot = ingotStack.getItem(); - - try - { - Icon icon = theIngot.getIconIndex(ingotStack); - String iconString = icon.getIconName(); - - if (iconString != null && !iconString.contains("MISSING_ICON_ITEM")) - { - iconString = (iconString.contains(":") ? iconString.replace(":", ":" + Reference.ITEM_TEXTURE_DIRECTORY) : Reference.ITEM_TEXTURE_DIRECTORY + iconString) + ".png"; - ResourceLocation textureLocation = new ResourceLocation(iconString); - - InputStream inputstream = Minecraft.getMinecraft().getResourceManager().getResource(textureLocation).getInputStream(); - BufferedImage bufferedimage = ImageIO.read(inputstream); - - int width = bufferedimage.getWidth(); - int height = bufferedimage.getWidth(); - - for (int x = 0; x < width; x++) - { - for (int y = 0; y < height; y++) - { - Color rgb = new Color(bufferedimage.getRGB(x, y)); - totalR += rgb.getRed(); - totalG += rgb.getGreen(); - totalB += rgb.getBlue(); - colorCount++; - } - } - } - } - catch (Exception e) - { - ResonantInduction.LOGGER.fine("Failed to compute colors for: " + theIngot); - // e.printStackTrace(); - } - } - - if (colorCount > 0) - { - totalR /= colorCount; - totalG /= colorCount; - totalB /= colorCount; - int resultantColor = new Color(totalR, totalG, totalB).brighter().getRGB(); - materialColors.put(ingotName, resultantColor); + materialColors.put(ingotName, getAverageColor(ingotStack)); } if (!materialColors.containsKey(ingotName)) @@ -157,4 +115,73 @@ public class ResourceGenerator } } } + + /** + * Gets the average color of this item. + * + * @param itemStack + * @return + */ + @SideOnly(Side.CLIENT) + public static int getAverageColor(ItemStack itemStack) + { + int totalR = 0; + int totalG = 0; + int totalB = 0; + + int colorCount = 0; + Item item = itemStack.getItem(); + + if (itemColorMap.containsKey(item)) + { + return itemColorMap.get(item); + } + + try + { + Icon icon = item.getIconIndex(itemStack); + String iconString = icon.getIconName(); + + if (iconString != null && !iconString.contains("MISSING_ICON_ITEM")) + { + iconString = (iconString.contains(":") ? iconString.replace(":", ":" + Reference.ITEM_TEXTURE_DIRECTORY) : Reference.ITEM_TEXTURE_DIRECTORY + iconString) + ".png"; + ResourceLocation textureLocation = new ResourceLocation(iconString); + + InputStream inputstream = Minecraft.getMinecraft().getResourceManager().getResource(textureLocation).getInputStream(); + BufferedImage bufferedimage = ImageIO.read(inputstream); + + int width = bufferedimage.getWidth(); + int height = bufferedimage.getWidth(); + + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + Color rgb = new Color(bufferedimage.getRGB(x, y)); + totalR += rgb.getRed(); + totalG += rgb.getGreen(); + totalB += rgb.getBlue(); + colorCount++; + } + } + } + } + catch (Exception e) + { + ResonantInduction.LOGGER.fine("Failed to compute colors for: " + item); + // e.printStackTrace(); + } + + if (colorCount > 0) + { + totalR /= colorCount; + totalG /= colorCount; + totalB /= colorCount; + int averageColor = new Color(totalR, totalG, totalB).brighter().getRGB(); + itemColorMap.put(item, averageColor); + return averageColor; + } + + return 0xFFFFFF; + } } diff --git a/src/main/java/resonantinduction/core/resource/fluid/BlockFluidMixture.java b/src/main/java/resonantinduction/core/resource/fluid/BlockFluidMixture.java index b854ffc8..92b4d284 100644 --- a/src/main/java/resonantinduction/core/resource/fluid/BlockFluidMixture.java +++ b/src/main/java/resonantinduction/core/resource/fluid/BlockFluidMixture.java @@ -1,8 +1,11 @@ package resonantinduction.core.resource.fluid; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.material.Material; import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.fluids.BlockFluidFinite; import net.minecraftforge.fluids.Fluid; @@ -26,7 +29,7 @@ public class BlockFluidMixture extends BlockFluidFinite implements ITileEntityPr { world.setBlockMetadataWithNotify(x, y, z, quanta - 1, 3); } - + /* IFluidBlock */ @Override public FluidStack drain(World world, int x, int y, int z, boolean doDrain) @@ -37,6 +40,14 @@ public class BlockFluidMixture extends BlockFluidFinite implements ITileEntityPr return stack; } + @SideOnly(Side.CLIENT) + @Override + public int colorMultiplier(IBlockAccess access, int x, int y, int z) + { + TileLiquidMixture tileFluid = (TileLiquidMixture) access.getBlockTileEntity(x, y, z); + return tileFluid.getColor(); + } + @Override public boolean canDrain(World world, int x, int y, int z) { diff --git a/src/main/java/resonantinduction/core/resource/fluid/TileLiquidMixture.java b/src/main/java/resonantinduction/core/resource/fluid/TileLiquidMixture.java index 3e5d57de..64f14536 100644 --- a/src/main/java/resonantinduction/core/resource/fluid/TileLiquidMixture.java +++ b/src/main/java/resonantinduction/core/resource/fluid/TileLiquidMixture.java @@ -3,12 +3,15 @@ package resonantinduction.core.resource.fluid; import java.util.HashSet; import java.util.Set; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraftforge.fluids.FluidStack; import resonantinduction.api.recipe.MachineRecipes; import resonantinduction.api.recipe.MachineRecipes.RecipeType; +import resonantinduction.core.resource.ResourceGenerator; import calclavia.lib.prefab.tile.TileAdvanced; /** @@ -32,6 +35,7 @@ public class TileLiquidMixture extends TileAdvanced { // TODO: Maybe we need to merge the stacks? items.add(itemStack); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); return true; } @@ -62,8 +66,14 @@ public class TileLiquidMixture extends TileAdvanced /** * @return The color of the liquid based on the fluidStacks stored. */ + @SideOnly(Side.CLIENT) public int getColor() { + for (ItemStack item : items) + { + return ResourceGenerator.getAverageColor(item); + } + return 0xFFFFFF; } diff --git a/src/main/java/resonantinduction/mechanical/fluid/pump/BlockGrate.java b/src/main/java/resonantinduction/mechanical/fluid/pump/BlockGrate.java index aaeb0aba..51c63ce4 100644 --- a/src/main/java/resonantinduction/mechanical/fluid/pump/BlockGrate.java +++ b/src/main/java/resonantinduction/mechanical/fluid/pump/BlockGrate.java @@ -54,12 +54,12 @@ public class BlockGrate extends BlockRIRotatable @Override public Icon getIcon(int side, int metadata) { - if (side == metadata) + if (side == 1) { - return blockIcon; + return drainIcon; } - return drainIcon; + return blockIcon; } @Override @@ -72,10 +72,10 @@ public class BlockGrate extends BlockRIRotatable { if (dir == ((TileGrate) entity).getDirection()) { - return blockIcon; + return drainIcon; } } - return drainIcon; + return blockIcon; } } diff --git a/src/main/java/resonantinduction/mechanical/fluid/pump/TileGrate.java b/src/main/java/resonantinduction/mechanical/fluid/pump/TileGrate.java index a1776724..bf736b4b 100644 --- a/src/main/java/resonantinduction/mechanical/fluid/pump/TileGrate.java +++ b/src/main/java/resonantinduction/mechanical/fluid/pump/TileGrate.java @@ -25,20 +25,14 @@ import com.builtbroken.common.Pair; public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain { - /* MAX BLOCKS DRAINED PER 1/2 SECOND */ - public static int MAX_WORLD_EDITS_PER_PROCESS = 50; + public static final int MAX_FLUID_MODIFY_RATE = 50; + + private long lastUseTime = 0; private int currentWorldEdits = 0; - /* LIST OF PUMPS AND THERE REQUESTS FOR THIS DRAIN */ - private HashMap> requestMap = new HashMap>(); - - private List updateQue = new ArrayList(); private LiquidPathFinder pathDrain; private LiquidPathFinder pathFill; - private Vector3 lastDrainOrigin; - public boolean markDrain = false; - public LiquidPathFinder getFillFinder() { if (pathFill == null) @@ -54,7 +48,7 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain return this.getFillFinder().refresh().results; } - public LiquidPathFinder getLiquidFinder() + public LiquidPathFinder getDrainFinder() { if (pathDrain == null) { @@ -64,157 +58,82 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain } @Override - public Set getFluidList() + public Set getDrainList() { - return this.getLiquidFinder().refresh().results; + return getDrainFinder().refresh().results; } @Override - public void updateEntity() + public boolean canUpdate() { - super.updateEntity(); + return false; + } - /* MAIN LOGIC PATH FOR DRAINING BODIES OF LIQUID */ - if (!this.worldObj.isRemote && this.ticks % 20 == 0 && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) + public void update() + { + if (System.currentTimeMillis() - lastUseTime > 1000) { - this.currentWorldEdits = 0; - - /* ONLY FIND NEW SOURCES IF OUR CURRENT LIST RUNS DRY */ - if (this.getLiquidFinder().results.size() < TileGrate.MAX_WORLD_EDITS_PER_PROCESS + 10) - { - this.getLiquidFinder().refresh().start(new Vector3(this).translate(this.getDirection()), TileGrate.MAX_WORLD_EDITS_PER_PROCESS, false); - } - - if (this.getFillFinder().results.size() < TileGrate.MAX_WORLD_EDITS_PER_PROCESS + 10) - { - this.getFillFinder().refresh().start(new Vector3(this).translate(this.getDirection()), TileGrate.MAX_WORLD_EDITS_PER_PROCESS, true); - } - /** - * If we can drain, do the drain action. - */ - if (markDrain) - { - drainAroundArea(worldObj, new Vector3(this), 3); - markDrain = false; - } + currentWorldEdits = 0; + lastUseTime = System.currentTimeMillis(); } } /** - * Drains an area starting at the given location - * - * @param world - world to drain in, most cases will be the TileEntities world - * @param loc - origin to start the path finder with. If this is an instance of IDrain this - * method will act different + * Updates the pathfinding operation. */ - public void drainAroundArea(World world, Vector3 vec, int update) + public void doPathfinding() { - Vector3 origin = vec.clone(); - if (origin == null) + if (this.getDrainFinder().results.size() < TileGrate.MAX_FLUID_MODIFY_RATE + 10) { - return; + this.getDrainFinder().refresh().start(new Vector3(this).translate(this.getDirection()), TileGrate.MAX_FLUID_MODIFY_RATE, false); } - /* Update last drain origin to prevent failed path finding */ - if (this.lastDrainOrigin == null || !this.lastDrainOrigin.equals(origin)) + if (this.getFillFinder().results.size() < TileGrate.MAX_FLUID_MODIFY_RATE + 10) { - this.lastDrainOrigin = origin.clone(); - this.getLiquidFinder().reset(); - } - - TileEntity drain = vec.clone().getTileEntity(world); - TileEntity originTile = null; - - Set drainList = null; - - if (drain instanceof IDrain) - { - if (!((IDrain) drain).canDrain(((IDrain) drain).getDirection())) - { - return; - } - origin = vec.translate(((IDrain) drain).getDirection()); - originTile = origin.getTileEntity(world); - - if (originTile instanceof IFluidHandler) - { - FluidStack draStack = ((IFluidHandler) originTile).drain(ForgeDirection.UP, MAX_WORLD_EDITS_PER_PROCESS * FluidContainerRegistry.BUCKET_VOLUME, false); - - if (draStack != null && FluidUtility.fillTanksAllSides(worldObj, new Vector3(this), draStack, false, ForgeDirection.DOWN) > 0) - { - ((IFluidHandler) originTile).drain(ForgeDirection.UP, FluidUtility.fillTanksAllSides(worldObj, new Vector3(this), draStack, true, ForgeDirection.DOWN), true); - - } - } - else - { - drainList = ((IDrain) drain).getFluidList(); - } - } - - if (drainList == null) - { - if (this.getLiquidFinder().results.size() < MAX_WORLD_EDITS_PER_PROCESS + 10) - { - this.getLiquidFinder().setWorld(world).refresh().start(origin, MAX_WORLD_EDITS_PER_PROCESS, false); - } - drainList = this.getLiquidFinder().refresh().results; - } - - if (originTile == null && drainList != null && drainList.size() > 0) - { - Iterator fluidList = drainList.iterator(); - - while (fluidList.hasNext()) - { - if (this.currentWorldEdits >= MAX_WORLD_EDITS_PER_PROCESS) - { - break; - } - - Vector3 drainLocation = fluidList.next(); - FluidStack drainStack = FluidUtility.drainBlock(world, drainLocation, false, 3); - int filled = FluidUtility.fillTanksAllSides(worldObj, new Vector3(this), drainStack, false); - - if (drainStack != null && filled >= drainStack.amount) - { - /* Remove the block that we drained. */ - FluidUtility.drainBlock(this.worldObj, drainLocation, true, update); - FluidUtility.fillTanksAllSides(worldObj, new Vector3(this), drainStack, true); - this.currentWorldEdits++; - fluidList.remove(); - - if (drain instanceof IDrain) - { - ((IDrain) drain).onUse(drainLocation); - } - } - } + this.getFillFinder().refresh().start(new Vector3(this).translate(this.getDirection()), TileGrate.MAX_FLUID_MODIFY_RATE, true); } } - /** - * Fills the area with fluid. - * - * @return Amount filled - */ - public int fillArea(FluidStack resource, boolean doFill) + @Override + public ForgeDirection getDirection() { - int fillVolume = 0; + return ForgeDirection.getOrientation(worldObj.getBlockMetadata(xCoord, yCoord, zCoord)); + } - if (this.currentWorldEdits < MAX_WORLD_EDITS_PER_PROCESS) + @Override + public void setDirection(ForgeDirection direction) + { + this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, direction.ordinal(), 3); + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) + { + update(); + + if (resource == null) { + return 0; + } + if (currentWorldEdits < MAX_FLUID_MODIFY_RATE) + { int remainingVolume = resource.amount; + /* ID LIQUID BLOCK AND SET VARS FOR BLOCK PLACEMENT */ if (resource == null || resource.amount < FluidContainerRegistry.BUCKET_VOLUME) { return 0; } - fillVolume = resource.amount; - List fluids = new ArrayList(); List blocks = new ArrayList(); List filled = new ArrayList(); + + + if (getFillList() == null || getFillList().size() == 0) + { + doPathfinding(); + } + /* Sort results out into two groups and clear the rest out of the result list */ Iterator it = this.getFillFinder().refresh().results.iterator(); while (it.hasNext()) @@ -233,103 +152,54 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain it.remove(); } } + /* Fill non-full fluids first */ for (Vector3 loc : fluids) { - if (fillVolume <= 0) + if (remainingVolume <= 0) { break; } + if (FluidUtility.isFillableFluid(worldObj, loc)) { - - fillVolume -= FluidUtility.fillBlock(worldObj, loc, FluidUtility.getStack(resource, fillVolume), doFill); + remainingVolume -= FluidUtility.fillBlock(worldObj, loc, FluidUtility.getStack(resource, remainingVolume), doFill); if (doFill) { filled.add(loc); - this.currentWorldEdits++; - if (!this.updateQue.contains(loc)) - { - this.updateQue.add(loc); - } + currentWorldEdits++; } - } - } + /* Fill air or replaceable blocks after non-full fluids */ for (Vector3 loc : blocks) { - if (fillVolume <= 0) + if (remainingVolume <= 0) { break; } + if (FluidUtility.isFillableBlock(worldObj, loc)) { - fillVolume -= FluidUtility.fillBlock(worldObj, loc, FluidUtility.getStack(resource, fillVolume), doFill); + remainingVolume -= FluidUtility.fillBlock(worldObj, loc, FluidUtility.getStack(resource, remainingVolume), doFill); if (doFill) { filled.add(loc); - this.currentWorldEdits++; - if (!this.updateQue.contains(loc)) - { - this.updateQue.add(loc); - } + currentWorldEdits++; } - } } - this.getLiquidFinder().results.removeAll(filled); - return Math.max(resource.amount - fillVolume, 0); + + this.getDrainFinder().results.removeAll(filled); + return Math.max(resource.amount - remainingVolume, 0); } + return 0; } - @Override - public ForgeDirection getDirection() - { - int meta = 0; - if (worldObj != null) - { - meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord) % 6; - } - return ForgeDirection.getOrientation(meta); - } - - @Override - public void setDirection(ForgeDirection direction) - { - if (direction != null && direction != this.getDirection()) - { - this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, direction.ordinal(), 3); - } - } - - @Override - public boolean canFill(ForgeDirection from, Fluid fluid) - { - return this.getDirection() != from; - } - - @Override - public int fill(ForgeDirection from, FluidStack resource, boolean doFill) - { - if (resource == null) - { - return 0; - } - - return this.fillArea(resource, doFill); - } - - @Override - public boolean canDrain(ForgeDirection from, Fluid fluid) - { - return false; - } - @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { @@ -341,32 +211,73 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { - markDrain = true; - return null; + update(); + + FluidStack resultStack = null; + + if (getDrainList() == null || getDrainList().size() == 0) + { + doPathfinding(); + } + + Set drainList = getDrainList(); + + if (drainList != null && drainList.size() > 0) + { + Iterator iterator = drainList.iterator(); + + while (iterator.hasNext()) + { + if (currentWorldEdits >= MAX_FLUID_MODIFY_RATE) + { + break; + } + + Vector3 drainLocation = iterator.next(); + FluidStack drainStack = FluidUtility.drainBlock(worldObj, drainLocation, false, 3); + + if (resultStack == null) + { + drainStack = FluidUtility.drainBlock(worldObj, drainLocation, doDrain, 3); + resultStack = drainStack; + } + else if (resultStack.equals(drainStack)) + { + drainStack = FluidUtility.drainBlock(worldObj, drainLocation, doDrain, 3); + resultStack.amount += drainStack.amount; + } + + if (doDrain) + { + currentWorldEdits++; + iterator.remove(); + } + + if (resultStack.amount >= maxDrain) + { + break; + } + } + } + + return resultStack; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { - return new FluidTankInfo[] { new FluidTank(this.getLiquidFinder().results.size() * FluidContainerRegistry.BUCKET_VOLUME).getInfo() }; + return new FluidTankInfo[] { new FluidTank(this.getDrainFinder().results.size() * FluidContainerRegistry.BUCKET_VOLUME).getInfo() }; } @Override - public boolean canDrain(ForgeDirection direction) + public boolean canFill(ForgeDirection from, Fluid fluid) { - return direction == this.getDirection() && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); + return getDirection() != from; } @Override - public boolean canFill(ForgeDirection direction) + public boolean canDrain(ForgeDirection from, Fluid fluid) { - return direction == this.getDirection() && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); + return getDirection() != from; } - - @Override - public void onUse(Vector3 vec) - { - this.currentWorldEdits++; - } - } diff --git a/src/main/java/resonantinduction/mechanical/fluid/pump/TilePump.java b/src/main/java/resonantinduction/mechanical/fluid/pump/TilePump.java index 16dbedf4..c6057180 100644 --- a/src/main/java/resonantinduction/mechanical/fluid/pump/TilePump.java +++ b/src/main/java/resonantinduction/mechanical/fluid/pump/TilePump.java @@ -136,7 +136,7 @@ public class TilePump extends TileMachine implements IReadOut, ITileConnector, I } else { - drainList = ((IDrain) drain).getFluidList(); + drainList = ((IDrain) drain).getDrainList(); } } @@ -183,11 +183,6 @@ public class TilePump extends TileMachine implements IReadOut, ITileConnector, I this.fill(drainStack, true); this.currentWorldEdits++; fluidList.remove(); - - if (drain instanceof IDrain) - { - ((IDrain) drain).onUse(drainLocation); - } } } }