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

View file

@ -36,6 +36,7 @@ public class ResourceGenerator
public static final ResourceGenerator INSTANCE = new ResourceGenerator(); public static final ResourceGenerator INSTANCE = new ResourceGenerator();
public static final Set<String> materialNames = new HashSet<String>(); public static final Set<String> materialNames = new HashSet<String>();
public static final HashMap<String, Integer> materialColors = new HashMap<String, Integer>(); public static final HashMap<String, Integer> materialColors = new HashMap<String, Integer>();
public static final HashMap<Item, Integer> itemColorMap = new HashMap<Item, Integer>();
@ForgeSubscribe @ForgeSubscribe
public void oreRegisterEvent(OreRegisterEvent evt) public void oreRegisterEvent(OreRegisterEvent evt)
@ -105,10 +106,40 @@ public class ResourceGenerator
for (ItemStack ingotStack : OreDictionary.getOres("ingot" + ingotName.substring(0, 1).toUpperCase() + ingotName.substring(1))) for (ItemStack ingotStack : OreDictionary.getOres("ingot" + ingotName.substring(0, 1).toUpperCase() + ingotName.substring(1)))
{ {
Item theIngot = ingotStack.getItem(); Item theIngot = ingotStack.getItem();
materialColors.put(ingotName, getAverageColor(ingotStack));
}
if (!materialColors.containsKey(ingotName))
{
materialColors.put(ingotName, 0xFFFFFF);
}
}
}
/**
* 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 try
{ {
Icon icon = theIngot.getIconIndex(ingotStack); Icon icon = item.getIconIndex(itemStack);
String iconString = icon.getIconName(); String iconString = icon.getIconName();
if (iconString != null && !iconString.contains("MISSING_ICON_ITEM")) if (iconString != null && !iconString.contains("MISSING_ICON_ITEM"))
@ -137,24 +168,20 @@ public class ResourceGenerator
} }
catch (Exception e) catch (Exception e)
{ {
ResonantInduction.LOGGER.fine("Failed to compute colors for: " + theIngot); ResonantInduction.LOGGER.fine("Failed to compute colors for: " + item);
// e.printStackTrace(); // e.printStackTrace();
} }
}
if (colorCount > 0) if (colorCount > 0)
{ {
totalR /= colorCount; totalR /= colorCount;
totalG /= colorCount; totalG /= colorCount;
totalB /= colorCount; totalB /= colorCount;
int resultantColor = new Color(totalR, totalG, totalB).brighter().getRGB(); int averageColor = new Color(totalR, totalG, totalB).brighter().getRGB();
materialColors.put(ingotName, resultantColor); itemColorMap.put(item, averageColor);
return averageColor;
} }
if (!materialColors.containsKey(ingotName)) return 0xFFFFFF;
{
materialColors.put(ingotName, 0xFFFFFF);
}
}
} }
} }

View file

@ -1,8 +1,11 @@
package resonantinduction.core.resource.fluid; 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.ITileEntityProvider;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fluids.BlockFluidFinite; import net.minecraftforge.fluids.BlockFluidFinite;
import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.Fluid;
@ -37,6 +40,14 @@ public class BlockFluidMixture extends BlockFluidFinite implements ITileEntityPr
return stack; 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 @Override
public boolean canDrain(World world, int x, int y, int z) 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.HashSet;
import java.util.Set; import java.util.Set;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import resonantinduction.api.recipe.MachineRecipes; import resonantinduction.api.recipe.MachineRecipes;
import resonantinduction.api.recipe.MachineRecipes.RecipeType; import resonantinduction.api.recipe.MachineRecipes.RecipeType;
import resonantinduction.core.resource.ResourceGenerator;
import calclavia.lib.prefab.tile.TileAdvanced; import calclavia.lib.prefab.tile.TileAdvanced;
/** /**
@ -32,6 +35,7 @@ public class TileLiquidMixture extends TileAdvanced
{ {
// TODO: Maybe we need to merge the stacks? // TODO: Maybe we need to merge the stacks?
items.add(itemStack); items.add(itemStack);
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
return true; return true;
} }
@ -62,8 +66,14 @@ public class TileLiquidMixture extends TileAdvanced
/** /**
* @return The color of the liquid based on the fluidStacks stored. * @return The color of the liquid based on the fluidStacks stored.
*/ */
@SideOnly(Side.CLIENT)
public int getColor() public int getColor()
{ {
for (ItemStack item : items)
{
return ResourceGenerator.getAverageColor(item);
}
return 0xFFFFFF; return 0xFFFFFF;
} }

View file

@ -54,12 +54,12 @@ public class BlockGrate extends BlockRIRotatable
@Override @Override
public Icon getIcon(int side, int metadata) public Icon getIcon(int side, int metadata)
{ {
if (side == metadata) if (side == 1)
{ {
return blockIcon; return drainIcon;
} }
return drainIcon; return blockIcon;
} }
@Override @Override
@ -72,10 +72,10 @@ public class BlockGrate extends BlockRIRotatable
{ {
if (dir == ((TileGrate) entity).getDirection()) 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 public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain
{ {
/* MAX BLOCKS DRAINED PER 1/2 SECOND */ public static final int MAX_FLUID_MODIFY_RATE = 50;
public static int MAX_WORLD_EDITS_PER_PROCESS = 50;
private long lastUseTime = 0;
private int currentWorldEdits = 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 pathDrain;
private LiquidPathFinder pathFill; private LiquidPathFinder pathFill;
private Vector3 lastDrainOrigin;
public boolean markDrain = false;
public LiquidPathFinder getFillFinder() public LiquidPathFinder getFillFinder()
{ {
if (pathFill == null) if (pathFill == null)
@ -54,7 +48,7 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain
return this.getFillFinder().refresh().results; return this.getFillFinder().refresh().results;
} }
public LiquidPathFinder getLiquidFinder() public LiquidPathFinder getDrainFinder()
{ {
if (pathDrain == null) if (pathDrain == null)
{ {
@ -64,157 +58,82 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain
} }
@Override @Override
public Set<Vector3> getFluidList() public Set<Vector3> getDrainList()
{ {
return this.getLiquidFinder().refresh().results; return getDrainFinder().refresh().results;
} }
@Override @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))
{
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) public void update()
{ {
this.getFillFinder().refresh().start(new Vector3(this).translate(this.getDirection()), TileGrate.MAX_WORLD_EDITS_PER_PROCESS, true); if (System.currentTimeMillis() - lastUseTime > 1000)
}
/**
* If we can drain, do the drain action.
*/
if (markDrain)
{ {
drainAroundArea(worldObj, new Vector3(this), 3); currentWorldEdits = 0;
markDrain = false; lastUseTime = System.currentTimeMillis();
}
} }
} }
/** /**
* Drains an area starting at the given location * Updates the pathfinding operation.
*
* @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
*/ */
public void drainAroundArea(World world, Vector3 vec, int update) public void doPathfinding()
{ {
Vector3 origin = vec.clone(); if (this.getDrainFinder().results.size() < TileGrate.MAX_FLUID_MODIFY_RATE + 10)
if (origin == null)
{ {
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.getFillFinder().results.size() < TileGrate.MAX_FLUID_MODIFY_RATE + 10)
if (this.lastDrainOrigin == null || !this.lastDrainOrigin.equals(origin))
{ {
this.lastDrainOrigin = origin.clone(); this.getFillFinder().refresh().start(new Vector3(this).translate(this.getDirection()), TileGrate.MAX_FLUID_MODIFY_RATE, true);
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) @Override
public ForgeDirection getDirection()
{ {
if (this.getLiquidFinder().results.size() < MAX_WORLD_EDITS_PER_PROCESS + 10) return ForgeDirection.getOrientation(worldObj.getBlockMetadata(xCoord, yCoord, zCoord));
{
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) @Override
public void setDirection(ForgeDirection direction)
{ {
Iterator<Vector3> fluidList = drainList.iterator(); this.worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, direction.ordinal(), 3);
while (fluidList.hasNext())
{
if (this.currentWorldEdits >= MAX_WORLD_EDITS_PER_PROCESS)
{
break;
} }
Vector3 drainLocation = fluidList.next(); @Override
FluidStack drainStack = FluidUtility.drainBlock(world, drainLocation, false, 3); public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
int filled = FluidUtility.fillTanksAllSides(worldObj, new Vector3(this), drainStack, false);
if (drainStack != null && filled >= drainStack.amount)
{ {
/* Remove the block that we drained. */ update();
FluidUtility.drainBlock(this.worldObj, drainLocation, true, update);
FluidUtility.fillTanksAllSides(worldObj, new Vector3(this), drainStack, true);
this.currentWorldEdits++;
fluidList.remove();
if (drain instanceof IDrain) if (resource == null)
{ {
((IDrain) drain).onUse(drainLocation); return 0;
}
}
}
}
} }
if (currentWorldEdits < MAX_FLUID_MODIFY_RATE)
{ int remainingVolume = resource.amount;
/**
* Fills the area with fluid.
*
* @return Amount filled
*/
public int fillArea(FluidStack resource, boolean doFill)
{
int fillVolume = 0;
if (this.currentWorldEdits < MAX_WORLD_EDITS_PER_PROCESS)
{
/* ID LIQUID BLOCK AND SET VARS FOR BLOCK PLACEMENT */ /* ID LIQUID BLOCK AND SET VARS FOR BLOCK PLACEMENT */
if (resource == null || resource.amount < FluidContainerRegistry.BUCKET_VOLUME) if (resource == null || resource.amount < FluidContainerRegistry.BUCKET_VOLUME)
{ {
return 0; return 0;
} }
fillVolume = resource.amount;
List<Vector3> fluids = new ArrayList<Vector3>(); List<Vector3> fluids = new ArrayList<Vector3>();
List<Vector3> blocks = new ArrayList<Vector3>(); List<Vector3> blocks = new ArrayList<Vector3>();
List<Vector3> filled = 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 */ /* Sort results out into two groups and clear the rest out of the result list */
Iterator<Vector3> it = this.getFillFinder().refresh().results.iterator(); Iterator<Vector3> it = this.getFillFinder().refresh().results.iterator();
while (it.hasNext()) while (it.hasNext())
@ -233,103 +152,54 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain
it.remove(); it.remove();
} }
} }
/* Fill non-full fluids first */ /* Fill non-full fluids first */
for (Vector3 loc : fluids) for (Vector3 loc : fluids)
{ {
if (fillVolume <= 0) if (remainingVolume <= 0)
{ {
break; break;
} }
if (FluidUtility.isFillableFluid(worldObj, loc)) if (FluidUtility.isFillableFluid(worldObj, loc))
{ {
remainingVolume -= FluidUtility.fillBlock(worldObj, loc, FluidUtility.getStack(resource, remainingVolume), doFill);
fillVolume -= FluidUtility.fillBlock(worldObj, loc, FluidUtility.getStack(resource, fillVolume), doFill);
if (doFill) if (doFill)
{ {
filled.add(loc); filled.add(loc);
this.currentWorldEdits++; currentWorldEdits++;
if (!this.updateQue.contains(loc)) }
{
this.updateQue.add(loc);
} }
} }
}
}
/* Fill air or replaceable blocks after non-full fluids */ /* Fill air or replaceable blocks after non-full fluids */
for (Vector3 loc : blocks) for (Vector3 loc : blocks)
{ {
if (fillVolume <= 0) if (remainingVolume <= 0)
{ {
break; break;
} }
if (FluidUtility.isFillableBlock(worldObj, loc)) 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) if (doFill)
{ {
filled.add(loc); filled.add(loc);
this.currentWorldEdits++; currentWorldEdits++;
if (!this.updateQue.contains(loc)) }
{
this.updateQue.add(loc);
} }
} }
this.getDrainFinder().results.removeAll(filled);
return Math.max(resource.amount - remainingVolume, 0);
} }
}
this.getLiquidFinder().results.removeAll(filled);
return Math.max(resource.amount - fillVolume, 0);
}
return 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 @Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{ {
@ -341,32 +211,73 @@ public class TileGrate extends TileAdvanced implements IFluidHandler, IDrain
@Override @Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{ {
markDrain = true; update();
return null;
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 @Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) 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 @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 @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 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.fill(drainStack, true);
this.currentWorldEdits++; this.currentWorldEdits++;
fluidList.remove(); fluidList.remove();
if (drain instanceof IDrain)
{
((IDrain) drain).onUse(drainLocation);
}
} }
} }
} }