use of net.minecraft.world.chunk.IChunkProvider in project ICBM-Classic by BuiltBrokenModding.
the class BlastRegen method doExplode.
@Override
public void doExplode() {
if (!world().isRemote) {
try {
Chunk oldChunk = world().getChunkFromBlockCoords(position.xi(), position.zi());
if (world() instanceof WorldServer) {
IChunkProvider provider = world().getChunkProvider();
Chunk newChunk = ((ChunkProviderServer) provider).currentChunkProvider.provideChunk(oldChunk.xPosition, oldChunk.zPosition);
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < world().getHeight(); y++) {
Block blockID = newChunk.getBlock(x, y, z);
int metadata = newChunk.getBlockMetadata(x, y, z);
world().setBlock(x + oldChunk.xPosition * 16, y, z + oldChunk.zPosition * 16, blockID, metadata, 3);
}
}
}
oldChunk.isTerrainPopulated = false;
provider.populate(provider, oldChunk.xPosition, oldChunk.zPosition);
oldChunk.isModified = true;
}
} catch (Exception e) {
ICBMClassic.INSTANCE.logger().error("ICBM Rejuvenation Failed!", e);
}
}
}
use of net.minecraft.world.chunk.IChunkProvider in project ForestryMC by ForestryMC.
the class MultiblockControllerBase method checkForDisconnections.
@Override
public Set<IMultiblockComponent> checkForDisconnections() {
if (!this.shouldCheckForDisconnections) {
return Collections.emptySet();
}
if (this.isEmpty()) {
MultiblockRegistry.addDeadController(world, this);
return Collections.emptySet();
}
IChunkProvider chunkProvider = world.getChunkProvider();
// Invalidate our reference coord, we'll recalculate it shortly
referenceCoord = null;
// Reset visitations and find the minimum coordinate
Set<IMultiblockComponent> deadParts = new HashSet<>();
BlockPos c;
IMultiblockComponent referencePart = null;
int originalSize = connectedParts.size();
for (IMultiblockComponent part : connectedParts) {
// This happens during chunk unload.
BlockPos partCoord = part.getCoordinates();
if (chunkProvider.getLoadedChunk(partCoord.getX() >> 4, partCoord.getZ() >> 4) == null || isInvalid(part)) {
deadParts.add(part);
onDetachBlock(part);
continue;
}
if (TileUtil.getTile(world, partCoord) != part) {
deadParts.add(part);
onDetachBlock(part);
continue;
}
MultiblockLogic logic = (MultiblockLogic) part.getMultiblockLogic();
logic.setUnvisited();
logic.forfeitMultiblockSaveDelegate();
c = part.getCoordinates();
if (referenceCoord == null) {
referenceCoord = c;
referencePart = part;
} else if (c.compareTo(referenceCoord) < 0) {
referenceCoord = c;
referencePart = part;
}
}
connectedParts.removeAll(deadParts);
deadParts.clear();
if (referencePart == null || isEmpty()) {
// There are no valid parts remaining. The entire multiblock was unloaded during a chunk unload. Halt.
shouldCheckForDisconnections = false;
MultiblockRegistry.addDeadController(world, this);
return Collections.emptySet();
} else {
MultiblockLogic logic = (MultiblockLogic) referencePart.getMultiblockLogic();
logic.becomeMultiblockSaveDelegate();
}
// Now visit all connected parts, breadth-first, starting from reference coord's part
IMultiblockComponent part;
LinkedList<IMultiblockComponent> partsToCheck = new LinkedList<>();
partsToCheck.add(referencePart);
while (!partsToCheck.isEmpty()) {
part = partsToCheck.removeFirst();
MultiblockLogic partLogic = (MultiblockLogic) part.getMultiblockLogic();
partLogic.setVisited();
// Chunk-safe on server, but not on client
List<IMultiblockComponent> nearbyParts = MultiblockUtil.getNeighboringParts(world, part);
for (IMultiblockComponent nearbyPart : nearbyParts) {
// Ignore different machines
MultiblockLogic nearbyPartLogic = (MultiblockLogic) nearbyPart.getMultiblockLogic();
if (nearbyPartLogic.getController() != this) {
continue;
}
if (!nearbyPartLogic.isVisited()) {
nearbyPartLogic.setVisited();
partsToCheck.add(nearbyPart);
}
}
}
// Finally, remove all parts that remain disconnected.
Set<IMultiblockComponent> removedParts = new HashSet<>();
for (IMultiblockComponent orphanCandidate : connectedParts) {
MultiblockLogic logic = (MultiblockLogic) orphanCandidate.getMultiblockLogic();
if (!logic.isVisited()) {
deadParts.add(orphanCandidate);
onDetachBlock(orphanCandidate);
removedParts.add(orphanCandidate);
}
}
// Trim any blocks that were invalid, or were removed.
connectedParts.removeAll(deadParts);
// Cleanup. Not necessary, really.
deadParts.clear();
// Juuuust in case.
if (referenceCoord == null) {
selectNewReferenceCoord();
}
// We've run the checks from here on out.
shouldCheckForDisconnections = false;
return removedParts;
}
use of net.minecraft.world.chunk.IChunkProvider in project ForestryMC by ForestryMC.
the class MultiblockControllerBase method selectNewReferenceCoord.
@Nullable
private BlockPos selectNewReferenceCoord() {
IChunkProvider chunkProvider = world.getChunkProvider();
IMultiblockComponent theChosenOne = null;
referenceCoord = null;
for (IMultiblockComponent part : connectedParts) {
BlockPos partCoord = part.getCoordinates();
if (isInvalid(part) || chunkProvider.getLoadedChunk(partCoord.getX() >> 4, partCoord.getZ() >> 4) == null) {
// Chunk is unloading, skip this coord to prevent chunk thrashing
continue;
}
if (referenceCoord == null || referenceCoord.compareTo(partCoord) > 0) {
referenceCoord = part.getCoordinates();
theChosenOne = part;
}
}
if (theChosenOne != null) {
MultiblockLogic logic = (MultiblockLogic) theChosenOne.getMultiblockLogic();
logic.becomeMultiblockSaveDelegate();
}
return referenceCoord;
}
use of net.minecraft.world.chunk.IChunkProvider in project ForestryMC by ForestryMC.
the class MultiblockControllerBase method detachAllBlocks.
@Override
public Set<IMultiblockComponent> detachAllBlocks() {
IChunkProvider chunkProvider = world.getChunkProvider();
for (IMultiblockComponent part : connectedParts) {
BlockPos partCoord = part.getCoordinates();
if (chunkProvider.getLoadedChunk(partCoord.getX() >> 4, partCoord.getZ() >> 4) != null) {
onDetachBlock(part);
}
}
Set<IMultiblockComponent> detachedParts = connectedParts;
connectedParts = new HashSet<>();
return detachedParts;
}
use of net.minecraft.world.chunk.IChunkProvider in project ForestryMC by ForestryMC.
the class MultiblockUtil method getNeighboringParts.
/**
* Returns an array containing references to neighboring IMultiblockComponent tile entities.
* Primarily a utility method. Only works after tileentity construction.
* <p>
* This method is chunk-safe on the server; it will not query for parts in chunks that are unloaded.
* Note that no method is chunk-safe on the client, because ChunkProviderClient is stupid.
*
* @return An array of references to neighboring IMultiblockComponent tile entities.
*/
public static List<IMultiblockComponent> getNeighboringParts(World world, IMultiblockComponent part) {
BlockPos partCoord = part.getCoordinates();
List<BlockPos> neighbors = new ArrayList<>(EnumFacing.values().length);
for (EnumFacing facing : EnumFacing.values()) {
BlockPos neighborCoord = new BlockPos(partCoord);
neighborCoord = neighborCoord.offset(facing);
neighbors.add(neighborCoord);
}
List<IMultiblockComponent> neighborParts = new ArrayList<>();
IChunkProvider chunkProvider = world.getChunkProvider();
for (BlockPos neighbor : neighbors) {
if (chunkProvider.getLoadedChunk(neighbor.getX() >> 4, neighbor.getZ() >> 4) == null) {
// Chunk not loaded, skip it.
continue;
}
TileUtil.actOnTile(world, neighbor, IMultiblockComponent.class, neighborParts::add);
}
return neighborParts;
}
Aggregations