Rewrote idle path calculations of Logistical Transporters!

Firstly, stacks will no longer will remember their home locations after a single failed home routing calculation.  More importantly, instead of recursively pathfinding the furthest transporter from a stack's current location, the stack will randomly select a direction to start traveling. Once it reaches the end of a line of transporters, it will attempt to recalculate a path to an inventory.  If it is unsuccessful, it will simply pick another direction to start traveling and the process will repeat.  This keeps the previous behavior, but does it much less CPU-intensively.
This commit is contained in:
Aidan C. Brady 2014-07-11 14:52:55 -04:00
parent 4ba9afb369
commit 177372e9fe
4 changed files with 132 additions and 55 deletions

View file

@ -421,7 +421,7 @@ public class Mekanism
" AB", "E B", " AB", Character.valueOf('A'), EnrichedAlloy, Character.valueOf('B'), Items.string, Character.valueOf('E'), EnergyTablet.getUnchargedItem()
}));
CraftingManager.getInstance().getRecipeList().add(new MekanismRecipe(EnergyTablet.getUnchargedItem(), new Object[] {
"RCR", "ECE", "RCR", Character.valueOf('C'), Items.gold_ingot, Character.valueOf('R'), Items.redstone, Character.valueOf('E'), EnrichedAlloy
"RCR", "ECE", "RCR", Character.valueOf('C'), "ingotGold", Character.valueOf('R'), Items.redstone, Character.valueOf('E'), EnrichedAlloy
}));
CraftingManager.getInstance().getRecipeList().add(new MekanismRecipe(new ItemStack(MachineBlock, 1, 0), new Object[] {
"RCR", "iIi", "RCR", Character.valueOf('i'), "ingotIron", Character.valueOf('C'), "circuitBasic", Character.valueOf('R'), "alloyBasic", Character.valueOf('I'), new ItemStack(BasicBlock, 1, 8)

View file

@ -394,8 +394,18 @@ public class PartLogisticalTransporter extends PartSidedPipe implements ILogisti
{
needsSync.add(stack);
if(!TransporterManager.didEmit(stack.itemStack, stack.recalculatePath(this, 0)))
if(stack.pathType != Path.NONE)
{
if(!TransporterManager.didEmit(stack.itemStack, stack.recalculatePath(this, 0)))
{
if(!stack.calculateIdle(this))
{
TransporterUtils.drop(this, stack);
return false;
}
}
}
else {
if(!stack.calculateIdle(this))
{
TransporterUtils.drop(this, stack);

View file

@ -2,6 +2,7 @@ package mekanism.common.transporter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -28,8 +29,6 @@ public final class TransporterPathfinder
public Coord4D start;
public Set<Destination> destinations = new HashSet<Destination>();
public TransporterStack transportStack;
public IdlePath(World world, Coord4D obj, TransporterStack stack)
@ -39,65 +38,117 @@ public final class TransporterPathfinder
transportStack = stack;
}
public void loop(Coord4D pointer, ArrayList<Coord4D> currentPath, int dist)
public Destination find()
{
if(pointer == null)
ArrayList<Coord4D> ret = new ArrayList<Coord4D>();
ret.add(start);
if(transportStack.idleDir == ForgeDirection.UNKNOWN)
{
return;
}
currentPath.add(pointer);
dist += ((ILogisticalTransporter)pointer.getTileEntity(worldObj)).getCost();
boolean found = false;
for(ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = pointer.getFromSide(side).getTileEntity(worldObj);
if(transportStack.canInsertToTransporter(tile, side) && !currentPath.contains(Coord4D.get(tile)))
ForgeDirection newSide = findSide();
if(newSide == null)
{
loop(Coord4D.get(tile), (ArrayList<Coord4D>)currentPath.clone(), dist);
found = true;
return null;
}
transportStack.idleDir = newSide;
loopSide(ret, newSide);
return new Destination(ret, 0, true, null).setPathType(Path.NONE);
}
if(!found)
{
destinations.add(new Destination(currentPath, dist, true, null));
}
}
public List<Coord4D> find()
{
loop(start, new ArrayList<Coord4D>(), 0);
Destination farthest = null;
for(Destination obj : destinations)
{
if(farthest == null || obj.score > farthest.score)
else {
TileEntity tile = start.getFromSide(transportStack.idleDir).getTileEntity(worldObj);
if(transportStack.canInsertToTransporter(tile, transportStack.idleDir))
{
if(!obj.path.isEmpty() && !obj.path.get(0).equals(start))
loopSide(ret, transportStack.idleDir);
return new Destination(ret, 0, true, null).setPathType(Path.NONE);
}
else {
Destination newPath = TransporterPathfinder.getNewBasePath((ILogisticalTransporter)start.getTileEntity(worldObj), transportStack, 0);
if(newPath != null && TransporterManager.didEmit(transportStack.itemStack, newPath.rejected))
{
farthest = obj;
transportStack.idleDir = ForgeDirection.UNKNOWN;
newPath.setPathType(Path.DEST);
return newPath;
}
else {
ForgeDirection newSide = findSide();
if(newSide == null)
{
return null;
}
transportStack.idleDir = newSide;
loopSide(ret, newSide);
return new Destination(ret, 0, true, null).setPathType(Path.NONE);
}
}
}
if(farthest == null)
}
private void loopSide(List<Coord4D> list, ForgeDirection side)
{
int count = 1;
while(true)
{
return null;
Coord4D coord = start.getFromSide(side, count);
if(transportStack.canInsertToTransporter(coord.getTileEntity(worldObj), side))
{
list.add(coord);
count++;
}
else {
break;
}
}
return farthest.path;
}
private ForgeDirection findSide()
{
if(transportStack.idleDir == ForgeDirection.UNKNOWN)
{
for(ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = start.getFromSide(side).getTileEntity(worldObj);
if(transportStack.canInsertToTransporter(tile, side))
{
return side;
}
}
}
else {
for(ForgeDirection side : EnumSet.complementOf(EnumSet.of(ForgeDirection.UNKNOWN, transportStack.idleDir.getOpposite())))
{
TileEntity tile = start.getFromSide(side).getTileEntity(worldObj);
if(transportStack.canInsertToTransporter(tile, side))
{
return side;
}
}
TileEntity tile = start.getFromSide(transportStack.idleDir.getOpposite()).getTileEntity(worldObj);
if(transportStack.canInsertToTransporter(tile, transportStack.idleDir.getOpposite()))
{
return transportStack.idleDir.getOpposite();
}
}
return null;
}
}
public static class Destination implements Comparable<Destination>
{
public List<Coord4D> path = new ArrayList<Coord4D>();
public Path pathType;
public double score;
public ItemStack rejected;
@ -113,6 +164,12 @@ public final class TransporterPathfinder
score = d;
rejected = rejects;
}
public Destination setPathType(Path type)
{
pathType = type;
return this;
}
@Override
public int hashCode()
@ -513,22 +570,20 @@ public final class TransporterPathfinder
return path;
}
else {
if(stack.homeLocation.getTileEntity(start.getTile().getWorldObj()) == null)
{
stack.homeLocation = null;
}
stack.homeLocation = null;
}
}
IdlePath d = new IdlePath(start.getTile().getWorldObj(), Coord4D.get(start.getTile()), stack);
List<Coord4D> path = d.find();
stack.pathType = Path.NONE;
Destination dest = d.find();
if(path == null)
if(dest == null)
{
return null;
}
stack.pathType = dest.pathType;
return path;
return dest.path;
}
}

View file

@ -27,6 +27,8 @@ public class TransporterStack
public EnumColor color = null;
public boolean initiatedPath = false;
public ForgeDirection idleDir = ForgeDirection.UNKNOWN;
public List<Coord4D> pathToTarget = new ArrayList<Coord4D>();
@ -103,6 +105,7 @@ public class TransporterStack
nbtTags.setInteger("progress", progress);
nbtTags.setTag("originalLocation", originalLocation.write(new NBTTagCompound()));
nbtTags.setInteger("idleDir", idleDir.ordinal());
if(homeLocation != null)
{
@ -122,6 +125,7 @@ public class TransporterStack
progress = nbtTags.getInteger("progress");
originalLocation = Coord4D.read(nbtTags.getCompoundTag("originalLocation"));
idleDir = ForgeDirection.values()[nbtTags.getInteger("idleDir")];
if(nbtTags.hasKey("homeLocation"))
{
@ -163,8 +167,9 @@ public class TransporterStack
}
pathToTarget = newPath.path;
System.out.println("Def reset");
pathType = Path.DEST;
idleDir = ForgeDirection.UNKNOWN;
initiatedPath = true;
return newPath.rejected;
@ -180,8 +185,9 @@ public class TransporterStack
}
pathToTarget = newPath.path;
System.out.println("RR reset");
pathType = Path.DEST;
idleDir = ForgeDirection.UNKNOWN;
initiatedPath = true;
return newPath.rejected;
@ -195,6 +201,12 @@ public class TransporterStack
{
return false;
}
if(pathType == Path.HOME)
{
System.out.println("Idle reset");
idleDir = ForgeDirection.UNKNOWN;
}
pathToTarget = newPath;