Mekanism-tilera-Edition/src/main/java/mekanism/common/transporter/TransporterStack.java
Aidan C. Brady 177372e9fe 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.
2014-07-11 14:52:55 -04:00

315 lines
6.9 KiB
Java

package mekanism.common.transporter;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import mekanism.api.Coord4D;
import mekanism.api.EnumColor;
import mekanism.common.ILogisticalTransporter;
import mekanism.common.tile.TileEntityLogisticalSorter;
import mekanism.common.transporter.TransporterPathfinder.Destination;
import mekanism.common.util.MekanismUtils;
import mekanism.common.util.TransporterUtils;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
public class TransporterStack
{
public ItemStack itemStack;
public int progress;
public EnumColor color = null;
public boolean initiatedPath = false;
public ForgeDirection idleDir = ForgeDirection.UNKNOWN;
public List<Coord4D> pathToTarget = new ArrayList<Coord4D>();
public Coord4D originalLocation;
public Coord4D homeLocation;
public Coord4D clientNext;
public Coord4D clientPrev;
public Path pathType;
public void write(ILogisticalTransporter tileEntity, ArrayList data)
{
if(color != null)
{
data.add(TransporterUtils.colors.indexOf(color));
}
else {
data.add(-1);
}
data.add(progress);
originalLocation.write(data);
data.add(pathType.ordinal());
if(pathToTarget.indexOf(Coord4D.get(tileEntity.getTile())) > 0)
{
data.add(true);
getNext(tileEntity).write(data);
}
else {
data.add(false);
}
getPrev(tileEntity).write(data);
data.add(MekanismUtils.getID(itemStack));
data.add(itemStack.stackSize);
data.add(itemStack.getItemDamage());
}
public void read(ByteBuf dataStream)
{
int c = dataStream.readInt();
if(c != -1)
{
color = TransporterUtils.colors.get(c);
}
else {
color = null;
}
progress = dataStream.readInt();
originalLocation = Coord4D.read(dataStream);
pathType = Path.values()[dataStream.readInt()];
if(dataStream.readBoolean())
{
clientNext = Coord4D.read(dataStream);
}
clientPrev = Coord4D.read(dataStream);
itemStack = new ItemStack(Item.getItemById(dataStream.readInt()), dataStream.readInt(), dataStream.readInt());
}
public void write(NBTTagCompound nbtTags)
{
if(color != null)
{
nbtTags.setInteger("color", TransporterUtils.colors.indexOf(color));
}
nbtTags.setInteger("progress", progress);
nbtTags.setTag("originalLocation", originalLocation.write(new NBTTagCompound()));
nbtTags.setInteger("idleDir", idleDir.ordinal());
if(homeLocation != null)
{
nbtTags.setTag("homeLocation", homeLocation.write(new NBTTagCompound()));
}
nbtTags.setInteger("pathType", pathType.ordinal());
itemStack.writeToNBT(nbtTags);
}
public void read(NBTTagCompound nbtTags)
{
if(nbtTags.hasKey("color"))
{
color = TransporterUtils.colors.get(nbtTags.getInteger("color"));
}
progress = nbtTags.getInteger("progress");
originalLocation = Coord4D.read(nbtTags.getCompoundTag("originalLocation"));
idleDir = ForgeDirection.values()[nbtTags.getInteger("idleDir")];
if(nbtTags.hasKey("homeLocation"))
{
homeLocation = Coord4D.read(nbtTags.getCompoundTag("homeLocation"));
}
pathType = Path.values()[nbtTags.getInteger("pathType")];
itemStack = ItemStack.loadItemStackFromNBT(nbtTags);
}
public static TransporterStack readFromNBT(NBTTagCompound nbtTags)
{
TransporterStack stack = new TransporterStack();
stack.read(nbtTags);
return stack;
}
public static TransporterStack readFromPacket(ByteBuf dataStream)
{
TransporterStack stack = new TransporterStack();
stack.read(dataStream);
return stack;
}
public boolean hasPath()
{
return pathToTarget != null && pathToTarget.size() >= 2;
}
public ItemStack recalculatePath(ILogisticalTransporter tileEntity, int min)
{
Destination newPath = TransporterPathfinder.getNewBasePath(tileEntity, this, min);
if(newPath == null)
{
return itemStack;
}
pathToTarget = newPath.path;
System.out.println("Def reset");
pathType = Path.DEST;
idleDir = ForgeDirection.UNKNOWN;
initiatedPath = true;
return newPath.rejected;
}
public ItemStack recalculateRRPath(TileEntityLogisticalSorter outputter, ILogisticalTransporter tileEntity, int min)
{
Destination newPath = TransporterPathfinder.getNewRRPath(tileEntity, this, outputter, min);
if(newPath == null)
{
return itemStack;
}
pathToTarget = newPath.path;
System.out.println("RR reset");
pathType = Path.DEST;
idleDir = ForgeDirection.UNKNOWN;
initiatedPath = true;
return newPath.rejected;
}
public boolean calculateIdle(ILogisticalTransporter tileEntity)
{
List<Coord4D> newPath = TransporterPathfinder.getIdlePath(tileEntity, this);
if(newPath == null)
{
return false;
}
if(pathType == Path.HOME)
{
System.out.println("Idle reset");
idleDir = ForgeDirection.UNKNOWN;
}
pathToTarget = newPath;
originalLocation = Coord4D.get(tileEntity.getTile());
initiatedPath = true;
return true;
}
public boolean isFinal(ILogisticalTransporter tileEntity)
{
return pathToTarget.indexOf(Coord4D.get(tileEntity.getTile())) == (pathType == Path.NONE ? 0 : 1);
}
public Coord4D getNext(ILogisticalTransporter tileEntity)
{
if(!tileEntity.getTile().getWorldObj().isRemote)
{
int index = pathToTarget.indexOf(Coord4D.get(tileEntity.getTile()))-1;
if(index < 0)
{
return null;
}
return pathToTarget.get(index);
}
else {
return clientNext;
}
}
public Coord4D getPrev(ILogisticalTransporter tileEntity)
{
if(!tileEntity.getTile().getWorldObj().isRemote)
{
int index = pathToTarget.indexOf(Coord4D.get(tileEntity.getTile()))+1;
if(index < pathToTarget.size())
{
return pathToTarget.get(index);
}
else {
return originalLocation;
}
}
else {
return clientPrev;
}
}
public int getSide(ILogisticalTransporter tileEntity)
{
if(progress < 50)
{
if(getPrev(tileEntity) != null)
{
return Coord4D.get(tileEntity.getTile()).sideDifference(getPrev(tileEntity)).ordinal();
}
}
else if(progress == 50)
{
if(getNext(tileEntity) != null)
{
return getNext(tileEntity).sideDifference(Coord4D.get(tileEntity.getTile())).ordinal();
}
}
else if(progress > 50)
{
if(getNext(tileEntity) != null)
{
return getNext(tileEntity).sideDifference(Coord4D.get(tileEntity.getTile())).ordinal();
}
}
return 0;
}
public boolean canInsertToTransporter(TileEntity tileEntity, ForgeDirection side)
{
if(!(tileEntity instanceof ILogisticalTransporter))
{
return false;
}
TileEntity from = Coord4D.get(tileEntity).getFromSide(side.getOpposite()).getTileEntity(tileEntity.getWorldObj());
ILogisticalTransporter transporter = (ILogisticalTransporter)tileEntity;
if(!transporter.canConnectMutual(side.getOpposite()))
{
return false;
}
return transporter.getColor() == color || transporter.getColor() == null;
}
public Coord4D getDest()
{
return pathToTarget.get(0);
}
public static enum Path
{
DEST, HOME, NONE
}
}