Improve Pump search Algo

Mainly just cleaned up the code and replaced the TreeSets with Deques.

Also made it so the pump will only keep the pumping the same type of
liquid it started on.  If you wish to reset it to pump any liquid hit
with a wrench and the next liquid it pumps will be the new filter.
This commit is contained in:
CovertJaguar 2013-07-19 07:09:18 -07:00
parent 108adc1a03
commit 0ce916dcd8
14 changed files with 284 additions and 240 deletions

View file

@ -19,7 +19,7 @@
<property name="mcpsrc.dir" value="${mcp.dir}/src"/>
<property name="mc.version" value="1.6.2"/>
<property name="forge.version" value="9.10.0.790"/>
<property name="forge.version" value="9.10.0.800"/>
<!-- <property name="project.version" value="0.0.0"/>-->
<property name="buildcraft.name" value="buildcraft"/>

View file

@ -140,7 +140,7 @@ public class BuildCraftEnergy {
// Oil and fuel
buildcraftFluidOil = new Fluid("oil");
buildcraftFluidOil = new Fluid("oil").setDensity(800).setViscosity(1500);
FluidRegistry.registerFluid(buildcraftFluidOil);
fluidOil = FluidRegistry.getFluid("oil");

View file

@ -91,6 +91,7 @@ import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import java.util.LinkedList;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.block.Block;
@ -447,14 +448,6 @@ public class BuildCraftTransport {
}
}
@Deprecated
public static Item createPipe(int defaultID, Class<? extends Pipe> clas, String descr, Object a, Object b, Object c) {
if (c != null) {
return buildPipe(defaultID, clas, descr, a, b, c);
}
return buildPipe(defaultID, clas, descr, a, b);
}
public static Item buildPipe(int defaultID, Class<? extends Pipe> clas, String descr, Object... ingredients) {
String name = Character.toLowerCase(clas.getSimpleName().charAt(0)) + clas.getSimpleName().substring(1);

View file

@ -71,9 +71,9 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, IP
currentIterator = it;
double dx = to.i - from.i;
double dy = to.j - from.j;
double dz = to.k - from.k;
double dx = to.x - from.x;
double dy = to.y - from.y;
double dz = to.z - from.z;
double size = Math.sqrt(dx * dx + dy * dy + dz * dz);
@ -81,11 +81,11 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, IP
cy = dy / size / 10;
cz = dz / size / 10;
ix = from.i;
iy = from.j;
iz = from.k;
ix = from.x;
iy = from.y;
iz = from.z;
lastDistance = (ix - to.i) * (ix - to.i) + (iy - to.j) * (iy - to.j) + (iz - to.k) * (iz - to.k);
lastDistance = (ix - to.x) * (ix - to.x) + (iy - to.y) * (iy - to.y) + (iz - to.z) * (iz - to.z);
if (Math.abs(dx) > Math.abs(dz)) {
if (dx > 0) {
@ -132,7 +132,7 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, IP
iy += cy;
iz += cz;
double distance = (ix - to.i) * (ix - to.i) + (iy - to.j) * (iy - to.j) + (iz - to.k) * (iz - to.k);
double distance = (ix - to.x) * (ix - to.x) + (iy - to.y) * (iy - to.y) + (iz - to.z) * (iz - to.z);
if (distance > lastDistance)
return null;
@ -188,9 +188,9 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, IP
path = ((TilePathMarker) tile).getPath();
for (BlockIndex b : path) {
worldObj.setBlock(b.i, b.j, b.k, 0);
worldObj.setBlock(b.x, b.y, b.z, 0);
BuildCraftBuilders.pathMarkerBlock.dropBlockAsItem(worldObj, b.i, b.j, b.k, BuildCraftBuilders.pathMarkerBlock.blockID, 0);
BuildCraftBuilders.pathMarkerBlock.dropBlockAsItem(worldObj, b.x, b.y, b.z, BuildCraftBuilders.pathMarkerBlock.blockID, 0);
}
break;
@ -200,9 +200,9 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, IP
}
if (path != null && pathLasers == null) {
path.getFirst().i = xCoord;
path.getFirst().j = yCoord;
path.getFirst().k = zCoord;
path.getFirst().x = xCoord;
path.getFirst().y = yCoord;
path.getFirst().z = zCoord;
createLasersForPath();
}
@ -217,8 +217,8 @@ public class TileBuilder extends TileBuildCraft implements IBuilderInventory, IP
for (BlockIndex b : path) {
if (previous != null) {
EntityPowerLaser laser = new EntityPowerLaser(worldObj, new Position(previous.i + 0.5, previous.j + 0.5, previous.k + 0.5), new Position(
b.i + 0.5, b.j + 0.5, b.k + 0.5));
EntityPowerLaser laser = new EntityPowerLaser(worldObj, new Position(previous.x + 0.5, previous.y + 0.5, previous.z + 0.5), new Position(
b.x + 0.5, b.y + 0.5, b.z + 0.5));
laser.setTexture(0);
laser.show();

View file

@ -17,25 +17,25 @@ import net.minecraft.world.World;
*/
public class BlockIndex implements Comparable<BlockIndex> {
public int i;
public int j;
public int k;
public int x;
public int y;
public int z;
/**
* Creates an index for a block located on i, j. k
* Creates an index for a block located on x, y. z
*/
public BlockIndex(int i, int j, int k) {
public BlockIndex(int x, int y, int z) {
this.i = i;
this.j = j;
this.k = k;
this.x = x;
this.y = y;
this.z = z;
}
public BlockIndex(NBTTagCompound c) {
this.i = c.getInteger("i");
this.j = c.getInteger("j");
this.k = c.getInteger("k");
this.x = c.getInteger("i");
this.y = c.getInteger("j");
this.z = c.getInteger("k");
}
/**
@ -44,17 +44,17 @@ public class BlockIndex implements Comparable<BlockIndex> {
@Override
public int compareTo(BlockIndex o) {
if (o.i < i)
if (o.x < x)
return 1;
else if (o.i > i)
else if (o.x > x)
return -1;
else if (o.k < k)
else if (o.z < z)
return 1;
else if (o.k > k)
else if (o.z > z)
return -1;
else if (o.j < j)
else if (o.y < y)
return 1;
else if (o.j > j)
else if (o.y > y)
return -1;
else
return 0;
@ -62,18 +62,18 @@ public class BlockIndex implements Comparable<BlockIndex> {
public void writeTo(NBTTagCompound c) {
c.setInteger("i", i);
c.setInteger("j", j);
c.setInteger("k", k);
c.setInteger("i", x);
c.setInteger("j", y);
c.setInteger("k", z);
}
public int getBlockId(World world) {
return world.getBlockId(i, j, k);
return world.getBlockId(x, y, z);
}
@Override
public String toString() {
return "{" + i + ", " + j + ", " + k + "}";
return "{" + x + ", " + y + ", " + z + "}";
}
@Override
@ -81,7 +81,7 @@ public class BlockIndex implements Comparable<BlockIndex> {
if (obj instanceof BlockIndex) {
BlockIndex b = (BlockIndex) obj;
return b.i == i && b.j == j && b.k == k;
return b.x == x && b.y == y && b.z == z;
}
return super.equals(obj);
@ -89,6 +89,6 @@ public class BlockIndex implements Comparable<BlockIndex> {
@Override
public int hashCode() {
return (i * 37 + j) * 37 + k;
return (x * 37 + y) * 37 + z;
}
}

View file

@ -129,7 +129,7 @@ public class Box implements IBox {
}
public boolean contains(BlockIndex i) {
return contains(i.i, i.j, i.k);
return contains(i.x, i.y, i.z);
}
@Override

View file

@ -143,7 +143,7 @@ public class EntityRobot extends Entity implements IEntityAdditionalSpawnData {
BlockIndex newDesination = getNewDestination();
if (newDesination != null) {
setDestination(newDesination.i, newDesination.j, newDesination.k);
setDestination(newDesination.x, newDesination.y, newDesination.z);
}
}
@ -162,7 +162,7 @@ public class EntityRobot extends Entity implements IEntityAdditionalSpawnData {
List<BlockIndex> potentialDestinations = new ArrayList<BlockIndex>();
for (BlockIndex blockIndex : moveArea.getBlocksInArea()) {
if (BlockUtil.isSoftBlock(worldObj, blockIndex.i, blockIndex.j, blockIndex.k) && movementBoundary.contains(blockIndex)) {
if (BlockUtil.isSoftBlock(worldObj, blockIndex.x, blockIndex.y, blockIndex.z) && movementBoundary.contains(blockIndex)) {
potentialDestinations.add(blockIndex);
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) SpaceToad, 2011-2012
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.liquids;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
/**
*
* @author CovertJaguar <http://www.railcraft.info/>
*/
public class SingleUseTank extends Tank {
private Fluid acceptedFluid;
public SingleUseTank(String name, int capacity) {
super(name, capacity);
}
@Override
public int fill(FluidStack resource, boolean doFill) {
if (resource == null)
return 0;
if (acceptedFluid == null)
acceptedFluid = resource.getFluid();
if (acceptedFluid != resource.getFluid())
return 0;
return super.fill(resource, doFill);
}
public void reset() {
acceptedFluid = null;
}
public Fluid getAcceptedFluid(){
return acceptedFluid;
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
if (acceptedFluid != null)
nbt.setString("acceptedFluid", acceptedFluid.getName());
return nbt;
}
@Override
public FluidTank readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
acceptedFluid = FluidRegistry.getFluid(nbt.getString("acceptedFluid"));
return this;
}
}

View file

@ -392,14 +392,18 @@ public class Utils {
if (fluidBlock.canDrain(world, x, y, z))
return fluidBlock.drain(world, x, y, z, doDrain);
} else if (blockId == Block.waterStill.blockID || blockId == Block.waterMoving.blockID) {
if (doDrain) {
int meta = world.getBlockMetadata(x, y, z);
if (meta != 0)
return null;
if (doDrain)
world.setBlockToAir(x, y, z);
}
return new FluidStack(FluidRegistry.WATER, FluidContainerRegistry.BUCKET_VOLUME);
} else if (blockId == Block.lavaStill.blockID || blockId == Block.lavaMoving.blockID) {
if (doDrain) {
int meta = world.getBlockMetadata(x, y, z);
if (meta != 0)
return null;
if (doDrain)
world.setBlockToAir(x, y, z);
}
return new FluidStack(FluidRegistry.LAVA, FluidContainerRegistry.BUCKET_VOLUME);
}
return null;

View file

@ -9,13 +9,11 @@
package buildcraft.energy;
import buildcraft.energy.render.EntityDropParticleFX;
import buildcraft.transport.render.TileEntityPickupFX;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Random;
import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.util.Icon;

View file

@ -1,14 +1,13 @@
/**
* Copyright (c) SpaceToad, 2011
* http://www.mod-buildcraft.com
* Copyright (c) SpaceToad, 2011 http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* BuildCraft is distributed under the terms of the Minecraft Mod Public License
* 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.factory;
import buildcraft.api.tools.IToolWrench;
import buildcraft.core.CreativeTabBuildCraft;
import buildcraft.core.utils.Utils;
import cpw.mods.fml.relauncher.Side;
@ -17,6 +16,8 @@ import java.util.ArrayList;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
@ -25,10 +26,10 @@ import net.minecraft.world.World;
public class BlockPump extends BlockContainer {
private Icon textureTop;
private Icon textureBottom;
private Icon textureSide;
private Icon textureBottom;
private Icon textureSide;
public BlockPump(int i) {
public BlockPump(int i) {
super(i, Material.iron);
setHardness(5F);
setCreativeTab(CreativeTabBuildCraft.tabBuildCraft);
@ -42,12 +43,12 @@ public class BlockPump extends BlockContainer {
@Override
public Icon getIcon(int i, int j) {
switch (i) {
case 0:
return textureBottom;
case 1:
return textureTop;
default:
return textureSide;
case 0:
return textureBottom;
case 1:
return textureTop;
default:
return textureSide;
}
}
@ -57,7 +58,31 @@ public class BlockPump extends BlockContainer {
super.breakBlock(world, x, y, z, par5, par6);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public boolean onBlockActivated(World world, int i, int j, int k, EntityPlayer entityplayer, int par6, float par7, float par8, float par9) {
TileEntity tile = world.getBlockTileEntity(i, j, k);
if (tile instanceof TilePump) {
TilePump pump = (TilePump) tile;
// Drop through if the player is sneaking
if (entityplayer.isSneaking())
return false;
// Restart the quarry if its a wrench
Item equipped = entityplayer.getCurrentEquippedItem() != null ? entityplayer.getCurrentEquippedItem().getItem() : null;
if (equipped instanceof IToolWrench && ((IToolWrench) equipped).canWrench(entityplayer, i, j, k)) {
pump.tank.reset();
((IToolWrench) equipped).wrenchUsed(entityplayer, i, j, k);
return true;
}
}
return false;
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public void addCreativeItems(ArrayList itemList) {
itemList.add(new ItemStack(this));
@ -65,10 +90,9 @@ public class BlockPump extends BlockContainer {
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister)
{
textureTop = par1IconRegister.registerIcon("buildcraft:pump_top");
textureBottom = par1IconRegister.registerIcon("buildcraft:pump_bottom");
textureSide = par1IconRegister.registerIcon("buildcraft:pump_side");
public void registerIcons(IconRegister par1IconRegister) {
textureTop = par1IconRegister.registerIcon("buildcraft:pump_top");
textureBottom = par1IconRegister.registerIcon("buildcraft:pump_bottom");
textureSide = par1IconRegister.registerIcon("buildcraft:pump_side");
}
}

View file

@ -3,8 +3,7 @@ package buildcraft.factory;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.Fluid;
public class PumpDimensionList {
public PumpDimensionList(String string) {
@ -35,8 +34,8 @@ public class PumpDimensionList {
else
e.dimID = Integer.parseInt(dimIDString);
e.liquidName = entryString.substring(i + 1);
if(e.liquidName.equals("*"))
e.fluidName = entryString.substring(i + 1);
if(e.fluidName.equals("*"))
e.matchAnyFluid = true;
entries.add(0, e);
@ -47,23 +46,14 @@ public class PumpDimensionList {
private class Entry {
boolean isWhitelist;
FluidStack liquidStack;
String liquidName;
String fluidName;
int dimID;
boolean matchAnyFluid;
boolean matchAnyDim;
private void initFluidStack() {
liquidStack = FluidRegistry.getFluidStack(liquidName, 1);
if(liquidStack == null)
throw new RuntimeException("Configuration error: unknown liquid "+liquidName+" in pumping.controlList");
}
boolean matches(FluidStack liquid, int dim) {
boolean matches(Fluid fluid, int dim) {
if(!matchAnyFluid) {
if(liquidStack == null)
initFluidStack();
if(!liquidStack.isFluidEqual(liquid))
if(!fluid.getName().equals(fluidName))
return false;
}
if(!matchAnyDim && dimID != dim)
@ -74,9 +64,9 @@ public class PumpDimensionList {
private List<Entry> entries;
public boolean isFluidAllowed(FluidStack liquid, int dim) {
public boolean isFluidAllowed(Fluid fluid, int dim) {
for(Entry e : entries)
if(e.matches(liquid, dim))
if(e.matches(fluid, dim))
return e.isWhitelist;
return false;
}

View file

@ -19,16 +19,20 @@ import buildcraft.core.BlockIndex;
import buildcraft.core.EntityBlock;
import buildcraft.core.IMachine;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.liquids.SingleUseTank;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketPayloadArrays;
import buildcraft.core.network.PacketPayloadStream;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.core.utils.Utils;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
@ -36,7 +40,6 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
@ -44,8 +47,8 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
public static int MAX_LIQUID = FluidContainerRegistry.BUCKET_VOLUME * 16;
EntityBlock tube;
private TreeMap<Integer, LinkedList<BlockIndex>> blocksToPump = new TreeMap<Integer, LinkedList<BlockIndex>>();
FluidTank tank;
private TreeMap<Integer, Deque<BlockIndex>> pumpLayerQueues = new TreeMap<Integer, Deque<BlockIndex>>();
SingleUseTank tank;
double tubeY = Double.NaN;
int aimY = 0;
private PowerHandler powerHandler;
@ -53,7 +56,7 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
public TilePump() {
powerHandler = new PowerHandler(this, Type.MACHINE);
initPowerProvider();
tank = new FluidTank(MAX_LIQUID);
tank = new SingleUseTank("tank", MAX_LIQUID);
}
private void initPowerProvider() {
@ -69,56 +72,49 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
if (tube == null)
return;
if (!CoreProxy.proxy.isRenderWorld(worldObj)) {
if (tube.posY - aimY > 0.01) {
tubeY = tube.posY - 0.01;
setTubePosition();
if (CoreProxy.proxy.isRenderWorld(worldObj))
return;
if (CoreProxy.proxy.isSimulating(worldObj)) {
sendNetworkUpdate();
}
if (tube.posY - aimY > 0.01) {
tubeY = tube.posY - 0.01;
setTubePosition();
sendNetworkUpdate();
return;
}
return;
}
if (worldObj.getWorldTime() % 4 != 0)
return;
if (tank.getFluid() == null || tank.getFluid().amount <= 0) {
BlockIndex index = getNextIndexToPump(false);
BlockIndex index = getNextIndexToPump(false);
if (isPumpableFluid(index)) {
FluidStack liquidToPump = Utils.drainBlock(worldObj, index.i, index.j, index.k, false);
FluidStack fluidToPump = index != null ? Utils.drainBlock(worldObj, index.x, index.y, index.z, false) : null;
if (fluidToPump != null) {
if (isFluidAllowed(fluidToPump.getFluid()) && tank.fill(fluidToPump, false) == fluidToPump.amount) {
if (tank.fill(liquidToPump, false) == liquidToPump.amount) {
if (powerHandler.useEnergy(10, 10, true) == 10) {
index = getNextIndexToPump(true);
if (powerHandler.useEnergy(10, 10, true) == 10) {
index = getNextIndexToPump(true);
if (liquidToPump.getFluid() != FluidRegistry.WATER || BuildCraftCore.consumeWaterSources) {
Utils.drainBlock(worldObj, index.i, index.j, index.k, true);
}
tank.fill(liquidToPump, true);
if (CoreProxy.proxy.isSimulating(worldObj)) {
sendNetworkUpdate();
}
}
if (fluidToPump.getFluid() != FluidRegistry.WATER || BuildCraftCore.consumeWaterSources) {
Utils.drainBlock(worldObj, index.x, index.y, index.z, true);
}
} else {
if (worldObj.getWorldTime() % 100 == 0) {
// TODO: improve that decision
initializePumpFromPosition(xCoord, aimY, zCoord);
tank.fill(fluidToPump, true);
}
}
} else {
if (worldObj.getWorldTime() % 128 == 0) {
// TODO: improve that decision
if (getNextIndexToPump(false) == null) {
for (int y = yCoord - 1; y > 0; --y) {
if (isFluid(new BlockIndex(xCoord, y, zCoord))) {
aimY = y;
return;
} else if (!worldObj.isAirBlock(xCoord, y, zCoord)) {
return;
}
}
initializePumpFromPosition(xCoord, aimY, zCoord);
if (getNextIndexToPump(false) == null) {
for (int y = yCoord - 1; y > 0; --y) {
if (isPumpableFluid(xCoord, y, zCoord)) {
aimY = y;
return;
} else if (!worldObj.isAirBlock(xCoord, y, zCoord)) {
return;
}
}
}
@ -170,110 +166,95 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
}
private BlockIndex getNextIndexToPump(boolean remove) {
LinkedList<BlockIndex> topLayer = null;
if (pumpLayerQueues.isEmpty())
return null;
int topLayerHeight = 0;
for (Integer layer : blocksToPump.keySet()) {
if (layer > topLayerHeight && blocksToPump.get(layer).size() != 0) {
topLayerHeight = layer;
topLayer = blocksToPump.get(layer);
}
}
Deque<BlockIndex> topLayer = pumpLayerQueues.lastEntry().getValue();
if (topLayer != null) {
if (topLayer.isEmpty())
pumpLayerQueues.pollLastEntry();
if (remove) {
BlockIndex index = topLayer.pop();
if (topLayer.size() == 0) {
blocksToPump.remove(topLayerHeight);
}
BlockIndex index = topLayer.removeLast();
return index;
} else
return topLayer.getLast();
} else
return null;
}
return topLayer.peekLast();
}
return null;
}
private Deque<BlockIndex> getLayerQueue(int layer) {
Deque<BlockIndex> pumpQueue = pumpLayerQueues.get(layer);
if (pumpQueue == null) {
pumpQueue = new LinkedList<BlockIndex>();
pumpLayerQueues.put(layer, pumpQueue);
}
return pumpQueue;
}
private void initializePumpFromPosition(int x, int y, int z) {
int liquidId = 0;
Set<BlockIndex> markedBlocks = new HashSet<BlockIndex>();
TreeSet<BlockIndex> lastFound = new TreeSet<BlockIndex>();
if (!blocksToPump.containsKey(y)) {
blocksToPump.put(y, new LinkedList<BlockIndex>());
}
LinkedList<BlockIndex> pumpList = blocksToPump.get(y);
liquidId = worldObj.getBlockId(x, y, z);
if (!isFluid(new BlockIndex(x, y, z)))
Fluid pumpingFluid = getFluid(x, y, z);
if(pumpingFluid == null)
return;
if(pumpingFluid != tank.getAcceptedFluid() && tank.getAcceptedFluid() != null)
return;
addToPumpIfFluid(new BlockIndex(x, y, z), markedBlocks, lastFound, pumpList, liquidId);
Set<BlockIndex> visitedBlocks = new HashSet<BlockIndex>();
Deque<BlockIndex> fluidsFound = new LinkedList<BlockIndex>();
long timeoutTime = System.currentTimeMillis() + 1000;
queueForPumping(x, y, z, visitedBlocks, fluidsFound, pumpingFluid);
while (lastFound.size() > 0) {
TreeSet<BlockIndex> visitIteration = new TreeSet<BlockIndex>(lastFound);
lastFound.clear();
// long timeoutTime = System.nanoTime() + 10000;
for (BlockIndex index : visitIteration) {
addToPumpIfFluid(new BlockIndex(index.i + 1, index.j, index.k), markedBlocks, lastFound, pumpList, liquidId);
addToPumpIfFluid(new BlockIndex(index.i - 1, index.j, index.k), markedBlocks, lastFound, pumpList, liquidId);
addToPumpIfFluid(new BlockIndex(index.i, index.j, index.k + 1), markedBlocks, lastFound, pumpList, liquidId);
addToPumpIfFluid(new BlockIndex(index.i, index.j, index.k - 1), markedBlocks, lastFound, pumpList, liquidId);
while (!fluidsFound.isEmpty()) {
Deque<BlockIndex> fluidsToExpand = fluidsFound;
fluidsFound = new LinkedList<BlockIndex>();
if (!blocksToPump.containsKey(index.j + 1)) {
blocksToPump.put(index.j + 1, new LinkedList<BlockIndex>());
}
for (BlockIndex index : fluidsToExpand) {
queueForPumping(index.x + 1, index.y, index.z, visitedBlocks, fluidsFound, pumpingFluid);
queueForPumping(index.x - 1, index.y, index.z, visitedBlocks, fluidsFound, pumpingFluid);
queueForPumping(index.x, index.y, index.z + 1, visitedBlocks, fluidsFound, pumpingFluid);
queueForPumping(index.x, index.y, index.z - 1, visitedBlocks, fluidsFound, pumpingFluid);
pumpList = blocksToPump.get(index.j + 1);
addToPumpIfFluid(new BlockIndex(index.i, index.j + 1, index.k), markedBlocks, lastFound, pumpList, liquidId);
queueForPumping(index.x, index.y + 1, index.z, visitedBlocks, fluidsFound, pumpingFluid);
if (System.currentTimeMillis() > timeoutTime)
return;
// if (System.nanoTime() > timeoutTime)
// return;
}
}
}
public void addToPumpIfFluid(BlockIndex index, Set<BlockIndex> markedBlocks, TreeSet<BlockIndex> lastFound, LinkedList<BlockIndex> pumpList,
int liquidId) {
if (liquidId != worldObj.getBlockId(index.i, index.j, index.k))
return;
if (markedBlocks.add(index)) {
if ((index.i - xCoord) * (index.i - xCoord) + (index.k - zCoord) * (index.k - zCoord) > 64 * 64)
public void queueForPumping(int x, int y, int z, Set<BlockIndex> visitedBlocks, Deque<BlockIndex> fluidsFound, Fluid pumpingFluid) {
BlockIndex index = new BlockIndex(x, y, z);
if (visitedBlocks.add(index)) {
if ((x - xCoord) * (x - xCoord) + (z - zCoord) * (z - zCoord) > 64 * 64)
return;
if (isPumpableFluid(index)) {
pumpList.push(index);
}
if (isFluid(index)) {
lastFound.add(index);
Fluid fluid = getFluid(x, y, z);
if (fluid == pumpingFluid) {
getLayerQueue(y).add(index);
fluidsFound.add(index);
}
}
}
private boolean isPumpableFluid(BlockIndex index) {
return isFluid(index) && worldObj.getBlockMetadata(index.i, index.j, index.k) == 0;
private boolean isPumpableFluid(int x, int y, int z) {
return getFluid(x, y, z) != null;
}
private boolean isFluid(BlockIndex index) {
if (index == null)
return false;
private Fluid getFluid(int x, int y, int z) {
FluidStack fluidStack = Utils.drainBlock(worldObj, x, y, z, false);
if (fluidStack == null)
return null;
FluidStack liquid = Utils.drainBlock(worldObj, index.i, index.j, index.k, false);
if (liquid == null)
return false;
return isFluidAllowed(fluidStack.getFluid()) ? fluidStack.getFluid() : null;
}
return BuildCraftFactory.pumpDimensionList.isFluidAllowed(liquid, worldObj.provider.dimensionId);
private boolean isFluidAllowed(Fluid fluid) {
return BuildCraftFactory.pumpDimensionList.isFluidAllowed(fluid, worldObj.provider.dimensionId);
}
@Override
@ -307,7 +288,8 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
@Override
public boolean isActive() {
return isPumpableFluid(getNextIndexToPump(false));
BlockIndex next = getNextIndexToPump(false);
return isPumpableFluid(next.x, next.y, next.z);
}
@Override
@ -321,38 +303,29 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
@Override
public PacketPayload getPacketPayload() {
PacketPayloadArrays payload = new PacketPayloadArrays(3, 1, 0);
if (tank.getFluid() != null) {
payload.intPayload[0] = tank.getFluid().getFluid().getID();
payload.intPayload[1] = tank.getFluid().amount;
} else {
payload.intPayload[0] = 0;
payload.intPayload[1] = 0;
}
payload.intPayload[2] = aimY;
payload.floatPayload[0] = (float) tubeY;
PacketPayloadStream payload = new PacketPayloadStream(new PacketPayloadStream.StreamWriter() {
@Override
public void writeData(DataOutputStream data) throws IOException {
data.writeInt(aimY);
data.writeFloat((float) tubeY);
}
});
return payload;
}
@Override
public void handleUpdatePacket(PacketUpdate packet) {
PacketPayloadArrays payload = (PacketPayloadArrays)packet.payload;
if (payload.intPayload[0] > 0) {
FluidStack liquid = new FluidStack(FluidRegistry.getFluid(payload.intPayload[0]), payload.intPayload[1]);
tank.setFluid(liquid);
} else {
tank.setFluid(null);
}
aimY = payload.intPayload[2];
tubeY = payload.floatPayload[0];
public void handleUpdatePacket(PacketUpdate packet) throws IOException {
PacketPayloadStream payload = (PacketPayloadStream) packet.payload;
DataInputStream data = payload.stream;
aimY = data.readInt();
tubeY = data.readFloat();
setTubePosition();
}
@Override
public void handleDescriptionPacket(PacketUpdate packet) {
public void handleDescriptionPacket(PacketUpdate packet) throws IOException {
handleUpdatePacket(packet);
}
@ -379,7 +352,7 @@ public class TilePump extends TileBuildCraft implements IMachine, IPowerReceptor
tube = null;
tubeY = Double.NaN;
aimY = 0;
blocksToPump.clear();
pumpLayerQueues.clear();
}
}

View file

@ -175,7 +175,7 @@ public class TileLaser extends TileBuildCraft implements IPowerReceptor, IAction
return;
BlockIndex b = targets.get(worldObj.rand.nextInt(targets.size()));
laserTarget = (ILaserTarget) worldObj.getBlockTileEntity(b.i, b.j, b.k);
laserTarget = (ILaserTarget) worldObj.getBlockTileEntity(b.x, b.y, b.z);
}
protected void createLaser() {