Cleaned up the grate code

This commit is contained in:
Calclavia 2014-01-25 20:25:27 +08:00
parent 99030c23c0
commit 676af2e409
7 changed files with 217 additions and 283 deletions

View file

@ -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<Vector3> getFillList();
/** Gets the list of drainable blocks */
public Set<Vector3> getFluidList();
/** Call this after the drain was used to edit a block at the location */
public void onUse(Vector3 vec);
public Set<Vector3> getDrainList();
}

View file

@ -36,6 +36,7 @@ public class ResourceGenerator
public static final ResourceGenerator INSTANCE = new ResourceGenerator();
public static final Set<String> materialNames = new HashSet<String>();
public static final HashMap<String, Integer> materialColors = new HashMap<String, Integer>();
public static final HashMap<Item, Integer> itemColorMap = new HashMap<Item, Integer>();
@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;
}
}

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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<TileEntity, Pair<FluidStack, Integer>> requestMap = new HashMap<TileEntity, Pair<FluidStack, Integer>>();
private List<Vector3> updateQue = new ArrayList<Vector3>();
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<Vector3> getFluidList()
public Set<Vector3> 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<Vector3> 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<Vector3> 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<Vector3> fluids = new ArrayList<Vector3>();
List<Vector3> blocks = new ArrayList<Vector3>();
List<Vector3> filled = new ArrayList<Vector3>();
if (getFillList() == null || getFillList().size() == 0)
{
doPathfinding();
}
/* Sort results out into two groups and clear the rest out of the result list */
Iterator<Vector3> 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<Vector3> drainList = getDrainList();
if (drainList != null && drainList.size() > 0)
{
Iterator<Vector3> 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++;
}
}

View file

@ -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);
}
}
}
}