use of forestry.api.multiblock.IMultiblockComponent in project ForestryMC by ForestryMC.
the class MultiblockWorldRegistry method onPartAdded.
/**
* Called when a multiblock part is added to the world, either via chunk-load or user action.
* If its chunk is loaded, it will be processed during the next tick.
* If the chunk is not loaded, it will be added to a list of objects waiting for a chunkload.
*
* @param part The part which is being added to this world.
*/
public void onPartAdded(IMultiblockComponent part) {
BlockPos worldLocation = part.getCoordinates();
if (world.getChunkProvider().getLoadedChunk(worldLocation.getX() >> 4, worldLocation.getZ() >> 4) == null) {
// Part goes into the waiting-for-chunk-load list
Set<IMultiblockComponent> partSet;
long chunkHash = ChunkPos.asLong(worldLocation.getX() >> 4, worldLocation.getZ() >> 4);
synchronized (partsAwaitingChunkLoadMutex) {
if (!partsAwaitingChunkLoad.containsKey(chunkHash)) {
partSet = new HashSet<>();
partsAwaitingChunkLoad.put(chunkHash, partSet);
} else {
partSet = partsAwaitingChunkLoad.get(chunkHash);
}
partSet.add(part);
}
} else {
// Part goes into the orphan queue, to be checked this tick
addOrphanedPartThreadsafe(part);
}
}
use of forestry.api.multiblock.IMultiblockComponent in project ForestryMC by ForestryMC.
the class RectangularMultiblockControllerBase method isMachineWhole.
@Override
protected void isMachineWhole() throws MultiblockValidationException {
int minX = sizeLimits.getMinimumXSize();
int minY = sizeLimits.getMinimumYSize();
int minZ = sizeLimits.getMinimumZSize();
if (connectedParts.size() < sizeLimits.getMinimumNumberOfBlocksForAssembledMachine()) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.small", minX, minY, minZ));
}
BlockPos maximumCoord = getMaximumCoord();
BlockPos minimumCoord = getMinimumCoord();
// Quickly check for exceeded dimensions
int deltaX = maximumCoord.getX() - minimumCoord.getX() + 1;
int deltaY = maximumCoord.getY() - minimumCoord.getY() + 1;
int deltaZ = maximumCoord.getZ() - minimumCoord.getZ() + 1;
int maxX = sizeLimits.getMaximumXSize();
int maxY = sizeLimits.getMaximumYSize();
int maxZ = sizeLimits.getMaximumZSize();
if (maxX > 0 && deltaX > maxX) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.large.x", maxX));
}
if (maxY > 0 && deltaY > maxY) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.large.y", maxY));
}
if (maxZ > 0 && deltaZ > maxZ) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.large.z", maxZ));
}
if (deltaX < minX) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.small.x", minX));
}
if (deltaY < minY) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.small.y", minY));
}
if (deltaZ < minZ) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.small.z", minZ));
}
// Now we run a simple check on each block within that volume.
// Any block deviating = NO DEAL SIR
TileEntity te;
IMultiblockComponent part;
Class<? extends RectangularMultiblockControllerBase> myClass = this.getClass();
for (int x = minimumCoord.getX(); x <= maximumCoord.getX(); x++) {
for (int y = minimumCoord.getY(); y <= maximumCoord.getY(); y++) {
for (int z = minimumCoord.getZ(); z <= maximumCoord.getZ(); z++) {
// Okay, figure out what sort of block this should be.
BlockPos pos = new BlockPos(x, y, z);
te = TileUtil.getTile(world, pos);
if (te instanceof IMultiblockComponent) {
part = (IMultiblockComponent) te;
// Ensure this part should actually be allowed within a cube of this controller's type
if (!myClass.equals(part.getMultiblockLogic().getController().getClass())) {
throw new MultiblockValidationException(Translator.translateToLocalFormatted("for.multiblock.error.invalid.part", Translator.translateToLocal(getUnlocalizedType())));
}
} else {
// This is permitted so that we can incorporate certain non-multiblock parts inside interiors
part = null;
}
// Validate block type against both part-level and material-level validators.
int extremes = 0;
if (x == minimumCoord.getX()) {
extremes++;
}
if (y == minimumCoord.getY()) {
extremes++;
}
if (z == minimumCoord.getZ()) {
extremes++;
}
if (x == maximumCoord.getX()) {
extremes++;
}
if (y == maximumCoord.getY()) {
extremes++;
}
if (z == maximumCoord.getZ()) {
extremes++;
}
if (extremes >= 1) {
// Side
int exteriorLevel = y - minimumCoord.getY();
if (part != null) {
isGoodForExteriorLevel(part, exteriorLevel);
} else {
isBlockGoodForExteriorLevel(exteriorLevel, this.world, pos);
}
} else {
if (part != null) {
isGoodForInterior(part);
} else {
isBlockGoodForInterior(this.world, pos);
}
}
}
}
}
}
use of forestry.api.multiblock.IMultiblockComponent in project ForestryMC by ForestryMC.
the class BlockGreenhouse method getCamouflageHandler.
@Override
public ICamouflageHandler getCamouflageHandler(IBlockAccess world, BlockPos pos) {
TileEntity tile = TileUtil.getTile(world, pos, TileEntity.class);
if (tile instanceof ICamouflagedTile) {
ICamouflagedTile block = (ICamouflagedTile) tile;
ICamouflageHandler handler = null;
if (tile instanceof ICamouflageHandler) {
handler = (ICamouflageHandler) tile;
}
if ((handler == null || handler.getCamouflageBlock().isEmpty()) && tile instanceof IMultiblockComponent) {
IMultiblockComponent component = (IMultiblockComponent) tile;
IMultiblockController controller = component.getMultiblockLogic().getController();
if (controller instanceof ICamouflageHandler) {
handler = (ICamouflageHandler) controller;
}
}
return handler;
}
return null;
}
use of forestry.api.multiblock.IMultiblockComponent in project ForestryMC by ForestryMC.
the class BlockGreenhouse method getCamouflageBlock.
@Override
public ItemStack getCamouflageBlock(IBlockAccess world, BlockPos pos) {
if (world == null || pos == null) {
return ItemStack.EMPTY;
}
TileEntity tile = TileUtil.getTile(world, pos, TileEntity.class);
if (tile instanceof ICamouflagedTile) {
ICamouflagedTile block = (ICamouflagedTile) tile;
ItemStack camouflageStack = ItemStack.EMPTY;
if (tile instanceof ICamouflageHandler) {
ICamouflageHandler tileHandler = (ICamouflageHandler) tile;
ItemStack tileCamouflageStack = tileHandler.getCamouflageBlock();
ItemStack defaultCamouflageStack = tileHandler.getDefaultCamouflageBlock();
if (!ItemStackUtil.isIdenticalItem(tileCamouflageStack, defaultCamouflageStack)) {
camouflageStack = tileCamouflageStack;
}
}
if (camouflageStack.isEmpty() && tile instanceof IMultiblockComponent) {
IMultiblockComponent component = (IMultiblockComponent) tile;
IMultiblockController controller = component.getMultiblockLogic().getController();
if (controller instanceof ICamouflageHandler) {
ICamouflageHandler multiblockHandler = (ICamouflageHandler) controller;
camouflageStack = multiblockHandler.getCamouflageBlock();
}
if (!controller.isAssembled()) {
camouflageStack = ItemStack.EMPTY;
}
}
return camouflageStack;
}
return ItemStack.EMPTY;
}
use of forestry.api.multiblock.IMultiblockComponent in project ForestryMC by ForestryMC.
the class CamouflageUtil method getCamouflageHandler.
@Nullable
public static ICamouflageHandler getCamouflageHandler(IBlockAccess world, BlockPos pos) {
TileEntity tile = TileUtil.getTile(world, pos, TileEntity.class);
if (tile instanceof ICamouflagedTile) {
ICamouflagedTile block = (ICamouflagedTile) tile;
ICamouflageHandler handler = null;
if (tile instanceof ICamouflageHandler) {
handler = (ICamouflageHandler) tile;
}
if ((handler == null || handler.getCamouflageBlock().isEmpty()) && tile instanceof IMultiblockComponent) {
IMultiblockComponent component = (IMultiblockComponent) tile;
IMultiblockController controller = component.getMultiblockLogic().getController();
if (controller instanceof ICamouflageHandler) {
handler = (ICamouflageHandler) controller;
}
}
return handler;
}
return null;
}
Aggregations