Applied-Energistics-2-tiler.../me/cluster/MBCalculator.java
2014-02-08 19:34:52 -06:00

195 lines
3.8 KiB
Java

package appeng.me.cluster;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.util.Platform;
public abstract class MBCalculator
{
private IAEMultiBlock target;
public MBCalculator(IAEMultiBlock t) {
target = t;
}
/**
* check if the tile entities are correct for the structure.
*
* @param te
* @return
*/
public abstract boolean isValidTile(TileEntity te);
/**
* construct the correct cluster, usually very simple.
*
* @param w
* @param min
* @param max
* @return
*/
public abstract IAECluster createCluster(World w, WorldCoord min, WorldCoord max);
/**
* configure the mutli-block tiles, most of the important stuff is in here.
*
* @param c
* @param w
* @param min
* @param max
*/
public abstract void updateTiles(IAECluster c, World w, WorldCoord min, WorldCoord max);
/**
* disassembles the multi-block.
*/
public abstract void disconnect();
/**
* verify if the structure is the correct dimentions, or size
*
* @param min
* @param max
* @return
*/
public abstract boolean checkMultiblockScale(WorldCoord min, WorldCoord max);
public boolean isValidTileAt(World w, int x, int y, int z)
{
return isValidTile( w.getTileEntity( x, y, z ) );
}
public void calculateMultiblock(World worldObj, WorldCoord loc)
{
if ( Platform.isClient() )
return;
try
{
WorldCoord min = loc.copy();
WorldCoord max = loc.copy();
World w = worldObj;
// find size of MB structure...
while (isValidTileAt( w, min.x - 1, min.y, min.z ))
min.x--;
while (isValidTileAt( w, min.x, min.y - 1, min.z ))
min.y--;
while (isValidTileAt( w, min.x, min.y, min.z - 1 ))
min.z--;
while (isValidTileAt( w, max.x + 1, max.y, max.z ))
max.x++;
while (isValidTileAt( w, max.x, max.y + 1, max.z ))
max.y++;
while (isValidTileAt( w, max.x, max.y, max.z + 1 ))
max.z++;
if ( checkMultiblockScale( min, max ) )
{
if ( verifyUnownedRegion( w, min, max ) )
{
IAECluster c = createCluster( w, min, max );
try
{
if ( !verifyInternalStructure( worldObj, min, max ) )
{
disconnect();
return;
}
}
catch (Exception err)
{
disconnect();
return;
}
boolean updateGrid = false;
IAECluster clust = target.getCluster();
if ( clust == null )
{
updateTiles( c, w, min, max );
updateGrid = true;
}
else
c = clust;
c.updateStatus( updateGrid );
return;
}
}
}
catch (Throwable err)
{
AELog.error( err );
}
disconnect();
}
public abstract boolean verifyInternalStructure(World worldObj, WorldCoord min, WorldCoord max);
public boolean verifyUnownedRegionInner(World w, int minx, int miny, int minz, int maxx, int maxy, int maxz, ForgeDirection side)
{
switch (side)
{
case WEST:
minx -= 1;
maxx = minx;
break;
case EAST:
maxx += 1;
minx = maxx;
break;
case DOWN:
miny -= 1;
maxy = miny;
break;
case NORTH:
maxz += 1;
minz = maxz;
break;
case SOUTH:
minz -= 1;
maxz = minz;
break;
case UP:
maxy += 1;
miny = maxy;
break;
case UNKNOWN:
return false;
}
for (int x = minx; x <= maxx; x++)
{
for (int y = miny; y <= maxy; y++)
{
for (int z = minz; z <= maxz; z++)
{
TileEntity te = w.getTileEntity( x, y, z );
if ( isValidTile( te ) )
return true;
}
}
}
return false;
}
public boolean verifyUnownedRegion(World w, WorldCoord min, WorldCoord max)
{
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
if ( verifyUnownedRegionInner( w, min.x, min.y, min.z, max.x, max.y, max.z, side ) )
return false;
return true;
}
}