Improved and randomized pathfinder
Pathfinder now works better --It levels of at the correct y level for pathfinding --It pathfinder no longer in a perfect line but is randomized --Pathfinder is now limited to search with a set range preventing cross map interaction
This commit is contained in:
parent
05a4f5b418
commit
13699c24b3
3 changed files with 275 additions and 83 deletions
|
@ -23,6 +23,7 @@ import net.minecraftforge.liquids.ILiquidTank;
|
||||||
import net.minecraftforge.liquids.ITankContainer;
|
import net.minecraftforge.liquids.ITankContainer;
|
||||||
import net.minecraftforge.liquids.LiquidContainerRegistry;
|
import net.minecraftforge.liquids.LiquidContainerRegistry;
|
||||||
import net.minecraftforge.liquids.LiquidStack;
|
import net.minecraftforge.liquids.LiquidStack;
|
||||||
|
import universalelectricity.core.vector.Vector2;
|
||||||
import universalelectricity.core.vector.Vector3;
|
import universalelectricity.core.vector.Vector3;
|
||||||
import universalelectricity.core.vector.VectorHelper;
|
import universalelectricity.core.vector.VectorHelper;
|
||||||
|
|
||||||
|
@ -37,7 +38,16 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
|
|
||||||
private List<Vector3> targetSources = new ArrayList<Vector3>();
|
private List<Vector3> targetSources = new ArrayList<Vector3>();
|
||||||
private List<Vector3> updateQue = new ArrayList<Vector3>();
|
private List<Vector3> updateQue = new ArrayList<Vector3>();
|
||||||
private LiquidPathFinder pathFinder;
|
private LiquidPathFinder pathLiquid;
|
||||||
|
|
||||||
|
public LiquidPathFinder getLiquidFinder()
|
||||||
|
{
|
||||||
|
if(pathLiquid == null)
|
||||||
|
{
|
||||||
|
pathLiquid = new LiquidPathFinder(this.worldObj, false, 1000, 100);
|
||||||
|
}
|
||||||
|
return pathLiquid;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMeterReading(EntityPlayer user, ForgeDirection side)
|
public String getMeterReading(EntityPlayer user, ForgeDirection side)
|
||||||
|
@ -49,7 +59,6 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
public void invalidate()
|
public void invalidate()
|
||||||
{
|
{
|
||||||
super.invalidate();
|
super.invalidate();
|
||||||
pathFinder = new LiquidPathFinder(this.worldObj, false, TileEntityDrain.MAX_WORLD_EDITS_PER_PROCESS * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canDrainSources()
|
public boolean canDrainSources()
|
||||||
|
@ -99,13 +108,17 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getKey() instanceof ITankContainer)
|
if (request.getKey() instanceof ITankContainer)
|
||||||
{
|
{
|
||||||
ITankContainer tank = (ITankContainer) request.getKey();
|
ITankContainer tank = (ITankContainer) request.getKey();
|
||||||
Iterator<Vector3> it = this.targetSources.iterator();
|
|
||||||
while (it.hasNext())
|
Vector3[] sortedList = this.sortedDrainList();
|
||||||
|
|
||||||
|
for (int i = 0; sortedList != null && i < sortedList.length; i++)
|
||||||
{
|
{
|
||||||
Vector3 loc = it.next();
|
Vector3 loc = sortedList[i];
|
||||||
|
|
||||||
if (this.currentWorldEdits >= MAX_WORLD_EDITS_PER_PROCESS)
|
if (this.currentWorldEdits >= MAX_WORLD_EDITS_PER_PROCESS)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -142,8 +155,6 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
/* REMOVE BLOCK */
|
/* REMOVE BLOCK */
|
||||||
loc.setBlock(this.worldObj, 0, 0, 2);
|
loc.setBlock(this.worldObj, 0, 0, 2);
|
||||||
this.currentWorldEdits++;
|
this.currentWorldEdits++;
|
||||||
it.remove();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,15 +170,12 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
*/
|
*/
|
||||||
public void getNextFluidBlock()
|
public void getNextFluidBlock()
|
||||||
{
|
{
|
||||||
if (pathFinder == null)
|
|
||||||
{
|
getLiquidFinder().reset();
|
||||||
pathFinder = new LiquidPathFinder(this.worldObj, false, 1000);
|
getLiquidFinder().init(new Vector3(this.xCoord + this.getFacing().offsetX, this.yCoord + this.getFacing().offsetY, this.zCoord + this.getFacing().offsetZ));
|
||||||
}
|
|
||||||
pathFinder.reset();
|
|
||||||
pathFinder.init(new Vector3(this.xCoord + this.getFacing().offsetX, this.yCoord + this.getFacing().offsetY, this.zCoord + this.getFacing().offsetZ));
|
|
||||||
// System.out.println("Nodes:" + pathFinder.nodes.size() + "Results:" +
|
// System.out.println("Nodes:" + pathFinder.nodes.size() + "Results:" +
|
||||||
// pathFinder.results.size());
|
// pathFinder.results.size());
|
||||||
for (Vector3 vec : pathFinder.nodes)
|
for (Vector3 vec : getLiquidFinder().nodes)
|
||||||
{
|
{
|
||||||
this.addVectorToQue(vec);
|
this.addVectorToQue(vec);
|
||||||
}
|
}
|
||||||
|
@ -211,73 +219,95 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
requests.remove();
|
requests.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* CLEANUP TARGET LIST AND REMOVE INVALID SOURCES */
|
|
||||||
Iterator<Vector3> targetIt = this.targetSources.iterator();
|
}
|
||||||
while (targetIt.hasNext())
|
|
||||||
{
|
public Vector3[] sortedDrainList()
|
||||||
Vector3 vec = targetIt.next();
|
{
|
||||||
if (!FluidHelper.isSourceBlock(this.worldObj, vec))
|
|
||||||
{
|
|
||||||
targetIt.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* SORT RESULTS TO PUT THE HiGHEST AND FURTHEST AT THE TOP */
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Vector3> updatedList = new ArrayList<Vector3>();
|
/* CLEANUP TARGET LIST AND REMOVE INVALID SOURCES */
|
||||||
updatedList.addAll(this.targetSources);
|
Iterator<Vector3> targetIt = this.targetSources.iterator();
|
||||||
|
while (targetIt.hasNext())
|
||||||
for (int i = 0; i < updatedList.size(); i++)
|
|
||||||
{
|
{
|
||||||
Vector3 vec = updatedList.get(i).clone();
|
Vector3 vec = targetIt.next();
|
||||||
if (i + 1 < updatedList.size())
|
if (!FluidHelper.isSourceBlock(this.worldObj, vec))
|
||||||
{
|
{
|
||||||
for (int b = i + 1; b < updatedList.size(); b++)
|
targetIt.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3[] sortedList = new Vector3[this.targetSources.size()];
|
||||||
|
for (int b = 0; b < this.targetSources.size(); b++)
|
||||||
|
{
|
||||||
|
sortedList[b] = this.targetSources.get(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SORT RESULTS TO PUT THE HiGHEST AND FURTHEST AT THE TOP */
|
||||||
|
Vector2 machine = new Vector3(this).toVector2();
|
||||||
|
for (int i = 0; i < sortedList.length; i++)
|
||||||
|
{
|
||||||
|
Vector3 vec = sortedList[i].clone();
|
||||||
|
Vector2 first = vec.toVector2();
|
||||||
|
if (i + 1 < sortedList.length)
|
||||||
|
{
|
||||||
|
Vector3 highest = vec;
|
||||||
|
int b = 0;
|
||||||
|
for (b = i + 1; b < sortedList.length; b++)
|
||||||
{
|
{
|
||||||
Vector3 checkVec = updatedList.get(b).clone();
|
Vector3 checkVec = sortedList[b].clone();
|
||||||
if (checkVec != null)
|
if (checkVec != null)
|
||||||
{
|
{
|
||||||
if (checkVec.distanceTo(new Vector3(this)) > vec.distanceTo(new Vector3(this)))
|
Vector2 second = checkVec.toVector2();
|
||||||
|
|
||||||
|
if (second.distanceTo(machine) > vec.toVector2().distanceTo(machine))
|
||||||
{
|
{
|
||||||
updatedList.set(i, checkVec);
|
highest = checkVec.clone();
|
||||||
updatedList.set(b, vec);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (b < sortedList.length)
|
||||||
}
|
|
||||||
for (int i = 0; i < updatedList.size(); i++)
|
|
||||||
{
|
|
||||||
Vector3 vec = updatedList.get(i).clone();
|
|
||||||
if (i + 1 < updatedList.size())
|
|
||||||
{
|
|
||||||
for (int b = i + 1; b < updatedList.size(); b++)
|
|
||||||
{
|
{
|
||||||
Vector3 checkVec = updatedList.get(b).clone();
|
sortedList[i] = vec;
|
||||||
if (checkVec != null)
|
sortedList[b] = highest;
|
||||||
{
|
|
||||||
if (checkVec.intY() > vec.intY())
|
|
||||||
{
|
|
||||||
updatedList.set(i, checkVec);
|
|
||||||
updatedList.set(b, vec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.targetSources.clear();
|
for (int i = 0; i < sortedList.length; i++)
|
||||||
this.targetSources.addAll(updatedList);
|
{
|
||||||
updatedList.clear();
|
Vector3 vec = sortedList[i].clone();
|
||||||
|
if (i + 1 < sortedList.length)
|
||||||
|
{
|
||||||
|
Vector3 highest = vec;
|
||||||
|
int b = 0;
|
||||||
|
for (b = i + 1; b < sortedList.length; b++)
|
||||||
|
{
|
||||||
|
Vector3 checkVec = sortedList[b].clone();
|
||||||
|
if (checkVec != null)
|
||||||
|
{
|
||||||
|
if (checkVec.intY() > highest.intY())
|
||||||
|
{
|
||||||
|
highest = checkVec.clone();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (b < sortedList.length)
|
||||||
|
{
|
||||||
|
sortedList[i] = vec;
|
||||||
|
sortedList[b] = highest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sortedList;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
System.out.println("FluidMech: Error sorting fill collection \n");
|
System.out.println("FluidMech: Critical Error Processing Drain List");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -318,17 +348,16 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
|
|
||||||
int blocks = (resource.amount / LiquidContainerRegistry.BUCKET_VOLUME);
|
int blocks = (resource.amount / LiquidContainerRegistry.BUCKET_VOLUME);
|
||||||
|
|
||||||
/* FIND ALL VALID BLOCKS ON LEVEL OR BELLOW */
|
/* FIND ALL VALID BLOCKS ON LEVEL OR BELLOW */
|
||||||
LiquidPathFinder pathFinder = new LiquidPathFinder(this.worldObj, true, this.MAX_WORLD_EDITS_PER_PROCESS * 2);
|
|
||||||
final Vector3 faceVec = new Vector3(this.xCoord + this.getFacing().offsetX, this.yCoord + this.getFacing().offsetY, this.zCoord + this.getFacing().offsetZ);
|
final Vector3 faceVec = new Vector3(this.xCoord + this.getFacing().offsetX, this.yCoord + this.getFacing().offsetY, this.zCoord + this.getFacing().offsetZ);
|
||||||
pathFinder.init(faceVec);
|
getLiquidFinder().init(faceVec);
|
||||||
|
|
||||||
/* SORT RESULTS TO PUT THE LOWEST AND CLOSEST AT THE TOP */
|
/* SORT RESULTS TO PUT THE LOWEST AND CLOSEST AT THE TOP */
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (pathFinder.results.size() > 1)
|
if (getLiquidFinder().results.size() > 1)
|
||||||
{
|
{
|
||||||
Collections.sort(pathFinder.results, new Comparator()
|
Collections.sort(getLiquidFinder().results, new Comparator()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public int compare(Object o1, Object o2)
|
public int compare(Object o1, Object o2)
|
||||||
|
@ -362,7 +391,7 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
}
|
}
|
||||||
/* START FILLING IN OR CHECKING IF CAN FILL AREA */
|
/* START FILLING IN OR CHECKING IF CAN FILL AREA */
|
||||||
int fillable = 0;
|
int fillable = 0;
|
||||||
for (Vector3 loc : pathFinder.results)
|
for (Vector3 loc : getLiquidFinder().results)
|
||||||
{
|
{
|
||||||
if (blocks <= 0)
|
if (blocks <= 0)
|
||||||
{
|
{
|
||||||
|
@ -387,7 +416,7 @@ public class TileEntityDrain extends TileEntityFluidDevice implements ITankConta
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Vector3 loc : pathFinder.results)
|
for (Vector3 loc : getLiquidFinder().results)
|
||||||
{
|
{
|
||||||
if (blocks <= 0)
|
if (blocks <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,14 @@ package fluidmech.common.pump.path;
|
||||||
import hydraulic.helpers.FluidHelper;
|
import hydraulic.helpers.FluidHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraftforge.common.ForgeDirection;
|
import net.minecraftforge.common.ForgeDirection;
|
||||||
|
import universalelectricity.core.vector.Vector2;
|
||||||
import universalelectricity.core.vector.Vector3;
|
import universalelectricity.core.vector.Vector3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,9 +27,14 @@ public class LiquidPathFinder
|
||||||
private boolean fill; /* ARE WE FILLING THE PATH OR DRAINING THE PATH */
|
private boolean fill; /* ARE WE FILLING THE PATH OR DRAINING THE PATH */
|
||||||
private ForgeDirection priority; /* BASED ON fill -- WHICH DIRECTION WILL THE PATH GO FIRST */
|
private ForgeDirection priority; /* BASED ON fill -- WHICH DIRECTION WILL THE PATH GO FIRST */
|
||||||
private int resultLimit = 2000;
|
private int resultLimit = 2000;
|
||||||
|
private Vector2 Start;
|
||||||
|
private double range;
|
||||||
|
private Random random = new Random();
|
||||||
|
List<ForgeDirection> bn = new ArrayList<ForgeDirection>();
|
||||||
|
|
||||||
public LiquidPathFinder(final World world, final boolean fill, final int resultLimit)
|
public LiquidPathFinder(final World world, final boolean fill, final int resultLimit, final double range)
|
||||||
{
|
{
|
||||||
|
this.range = range;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.fill = fill;
|
this.fill = fill;
|
||||||
if (fill)
|
if (fill)
|
||||||
|
@ -39,6 +47,10 @@ public class LiquidPathFinder
|
||||||
}
|
}
|
||||||
this.resultLimit = resultLimit;
|
this.resultLimit = resultLimit;
|
||||||
this.reset();
|
this.reset();
|
||||||
|
bn.add(ForgeDirection.EAST);
|
||||||
|
bn.add(ForgeDirection.WEST);
|
||||||
|
bn.add(ForgeDirection.NORTH);
|
||||||
|
bn.add(ForgeDirection.SOUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,28 +85,25 @@ public class LiquidPathFinder
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec = node.clone().modifyPositionFromSide(this.priority);
|
if (find(this.priority, node.clone()))
|
||||||
if (this.isValidNode(vec) & !this.nodes.contains(vec))
|
|
||||||
{
|
{
|
||||||
if (this.findNodes(vec))
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.shuffle(bn);
|
||||||
|
Collections.shuffle(bn);
|
||||||
|
|
||||||
|
for (ForgeDirection direction : bn)
|
||||||
|
{
|
||||||
|
if (find(direction, vec))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
|
if (find(this.priority.getOpposite(), node.clone()))
|
||||||
{
|
{
|
||||||
if (direction != this.priority)
|
return true;
|
||||||
{
|
|
||||||
vec = node.clone().modifyPositionFromSide(direction);
|
|
||||||
if (this.isValidNode(vec) & !this.nodes.contains(vec))
|
|
||||||
{
|
|
||||||
if (this.findNodes(vec))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -105,6 +114,20 @@ public class LiquidPathFinder
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean find(ForgeDirection direction, Vector3 vec)
|
||||||
|
{
|
||||||
|
vec = vec.clone().modifyPositionFromSide(direction);
|
||||||
|
double distance = vec.toVector2().distanceTo(this.Start);
|
||||||
|
if (distance <= this.range && this.isValidNode(vec) & !this.nodes.contains(vec))
|
||||||
|
{
|
||||||
|
if (this.findNodes(vec))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValidNode(Vector3 pos)
|
public boolean isValidNode(Vector3 pos)
|
||||||
{
|
{
|
||||||
int blockID = pos.getBlockID(world);
|
int blockID = pos.getBlockID(world);
|
||||||
|
@ -130,8 +153,9 @@ public class LiquidPathFinder
|
||||||
/**
|
/**
|
||||||
* Called to execute the pathfinding operation.
|
* Called to execute the pathfinding operation.
|
||||||
*/
|
*/
|
||||||
public LiquidPathFinder init(Vector3 startNode)
|
public LiquidPathFinder init(final Vector3 startNode)
|
||||||
{
|
{
|
||||||
|
this.Start = startNode.toVector2();
|
||||||
this.findNodes(startNode);
|
this.findNodes(startNode);
|
||||||
if (this.fill && this.isValidNode(startNode))
|
if (this.fill && this.isValidNode(startNode))
|
||||||
{
|
{
|
||||||
|
|
139
src/minecraft/fluidmech/common/pump/path/LiquidPathFinder2D.java
Normal file
139
src/minecraft/fluidmech/common/pump/path/LiquidPathFinder2D.java
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
package fluidmech.common.pump.path;
|
||||||
|
|
||||||
|
import hydraulic.helpers.FluidHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraftforge.common.ForgeDirection;
|
||||||
|
import universalelectricity.core.vector.Vector3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simpler pathfinder based on Calclavia's PathFinder from UE api
|
||||||
|
*/
|
||||||
|
public class LiquidPathFinder2D
|
||||||
|
{
|
||||||
|
private World world; /* MC WORLD */
|
||||||
|
public List<Vector3> nodes = new ArrayList<Vector3>(); /*
|
||||||
|
* LOCATIONs THE PATH FINDER HAS GONE
|
||||||
|
* OVER
|
||||||
|
*/
|
||||||
|
public List<Vector3> results = new ArrayList<Vector3>();/* LOCATIONS THAT ARE VALID RESULTS */
|
||||||
|
private boolean fill; /* ARE WE FILLING THE PATH OR DRAINING THE PATH */
|
||||||
|
private ForgeDirection priority; /* BASED ON fill -- WHICH DIRECTION WILL THE PATH GO FIRST */
|
||||||
|
private int resultLimit = 2000;
|
||||||
|
|
||||||
|
public LiquidPathFinder2D(final World world, final int resultLimit)
|
||||||
|
{
|
||||||
|
this.world = world;
|
||||||
|
this.fill = fill;
|
||||||
|
if (fill)
|
||||||
|
{
|
||||||
|
priority = ForgeDirection.DOWN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
priority = ForgeDirection.UP;
|
||||||
|
}
|
||||||
|
this.resultLimit = resultLimit;
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True on success finding, false on failure.
|
||||||
|
*/
|
||||||
|
public boolean findNodes(final Vector3 node)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Vector3 vec = node.clone();
|
||||||
|
this.nodes.add(node);
|
||||||
|
Chunk chunk = this.world.getChunkFromBlockCoords(vec.intX(), vec.intZ());
|
||||||
|
|
||||||
|
if (chunk == null || !chunk.isChunkLoaded)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = node.getBlockID(world);
|
||||||
|
int meta = node.getBlockID(world);
|
||||||
|
if (this.fill && (id == 0 || (FluidHelper.getLiquidFromBlockId(id) != null && meta != 0)))
|
||||||
|
{
|
||||||
|
this.results.add(node);
|
||||||
|
}
|
||||||
|
else if (!this.fill && FluidHelper.isSourceBlock(world, node))
|
||||||
|
{
|
||||||
|
this.results.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isDone(node))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
|
||||||
|
{
|
||||||
|
if (direction != ForgeDirection.DOWN && direction != ForgeDirection.UP)
|
||||||
|
{
|
||||||
|
vec = node.clone().modifyPositionFromSide(direction);
|
||||||
|
if (this.isValidNode(vec) & !this.nodes.contains(vec))
|
||||||
|
{
|
||||||
|
if (this.findNodes(vec))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValidNode(Vector3 pos)
|
||||||
|
{
|
||||||
|
int blockID = pos.getBlockID(world);
|
||||||
|
if (!this.fill)
|
||||||
|
{
|
||||||
|
return FluidHelper.getLiquidFromBlockId(pos.getBlockID(world)) != null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FluidHelper.getLiquidFromBlockId(pos.getBlockID(world)) != null || (blockID == 0 && FluidHelper.getConnectedSources(world, pos) > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDone(Vector3 vec)
|
||||||
|
{
|
||||||
|
if (this.results.size() >= this.resultLimit || this.nodes.size() >= 4000)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to execute the pathfinding operation.
|
||||||
|
*/
|
||||||
|
public LiquidPathFinder2D init(Vector3 startNode)
|
||||||
|
{
|
||||||
|
this.findNodes(startNode);
|
||||||
|
if (this.fill && this.isValidNode(startNode))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiquidPathFinder2D reset()
|
||||||
|
{
|
||||||
|
this.nodes.clear();
|
||||||
|
this.results.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue