package fi.dy.masa.litematica.util; import net.minecraft.block.material.Material; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntitySign; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3i; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import fi.dy.masa.litematica.interfaces.IWorldUpdateSuppressor; import fi.dy.masa.litematica.world.SchematicWorldHandler; import fi.dy.masa.litematica.world.WorldSchematic; public class WorldUtils { public static boolean shouldPreventBlockUpdates(World world) { return ((IWorldUpdateSuppressor) world).getShouldPreventUpdates(); } public static void setShouldPreventBlockUpdates(World world, boolean preventUpdates) { ((IWorldUpdateSuppressor) world).setShouldPreventUpdates(preventUpdates); } public static void loadChunksClientWorld(WorldClient world, BlockPos origin, Vec3i areaSize) { BlockPos posEnd = origin.add(PositionUtils.getRelativeEndPositionFromAreaSize(areaSize)); BlockPos posMin = fi.dy.masa.malilib.util.PositionUtils.getMinCorner(origin, posEnd); BlockPos posMax = fi.dy.masa.malilib.util.PositionUtils.getMaxCorner(origin, posEnd); final int cxMin = posMin.getX() >> 4; final int czMin = posMin.getZ() >> 4; final int cxMax = posMax.getX() >> 4; final int czMax = posMax.getZ() >> 4; for (int cz = czMin; cz <= czMax; ++cz) { for (int cx = cxMin; cx <= cxMax; ++cx) { world.getChunkProvider().loadChunk(cx, cz); } } } public static void insertSignTextFromSchematic(TileEntitySign teClient) { WorldSchematic worldSchematic = SchematicWorldHandler.getSchematicWorld(); if (worldSchematic != null) { TileEntity te = worldSchematic.getTileEntity(teClient.getPos()); if (te instanceof TileEntitySign) { ITextComponent[] textSchematic = ((TileEntitySign) te).signText; ITextComponent[] textClient = teClient.signText; if (textClient != null && textSchematic != null) { int size = Math.min(textSchematic.length, textClient.length); for (int i = 0; i < size; ++i) { if (textSchematic[i] != null) { textClient[i] = textSchematic[i].createCopy(); } } } } } } /** * Checks if the given one block thick slice has non-air blocks or not. * NOTE: The axis is the perpendicular axis (that goes through the plane). * @param axis * @param pos1 * @param pos2 * @return */ public static boolean isSliceEmpty(World world, EnumFacing.Axis axis, BlockPos pos1, BlockPos pos2) { switch (axis) { case Z: { int x1 = Math.min(pos1.getX(), pos2.getX()); int x2 = Math.max(pos1.getX(), pos2.getX()); int y1 = Math.min(pos1.getY(), pos2.getY()); int y2 = Math.max(pos1.getY(), pos2.getY()); int z = pos1.getZ(); int cxMin = (x1 >> 4); int cxMax = (x2 >> 4); for (int cx = cxMin; cx <= cxMax; ++cx) { Chunk chunk = world.getChunk(cx, z >> 4); int xMin = Math.max(x1, cx << 4 ); int xMax = Math.min(x2, (cx << 4) + 15); int yMax = Math.min(y2, chunk.getTopFilledSegment() + 15); for (int x = xMin; x <= xMax; ++x) { for (int y = y1; y <= yMax; ++y) { if (chunk.getBlockState(x, y, z).getMaterial() != Material.AIR) { return false; } } } } break; } case Y: { int x1 = Math.min(pos1.getX(), pos2.getX()); int x2 = Math.max(pos1.getX(), pos2.getX()); int y = pos1.getY(); int z1 = Math.min(pos1.getZ(), pos2.getZ()); int z2 = Math.max(pos1.getZ(), pos2.getZ()); int cxMin = (x1 >> 4); int cxMax = (x2 >> 4); int czMin = (z1 >> 4); int czMax = (z2 >> 4); for (int cz = czMin; cz <= czMax; ++cz) { for (int cx = cxMin; cx <= cxMax; ++cx) { Chunk chunk = world.getChunk(cx, cz); if (y > chunk.getTopFilledSegment() + 15) { continue; } int xMin = Math.max(x1, cx << 4 ); int xMax = Math.min(x2, (cx << 4) + 15); int zMin = Math.max(z1, cz << 4 ); int zMax = Math.min(z2, (cz << 4) + 15); for (int z = zMin; z <= zMax; ++z) { for (int x = xMin; x <= xMax; ++x) { if (chunk.getBlockState(x, y, z).getMaterial() != Material.AIR) { return false; } } } } } break; } case X: { int x = pos1.getX(); int z1 = Math.min(pos1.getZ(), pos2.getZ()); int z2 = Math.max(pos1.getZ(), pos2.getZ()); int y1 = Math.min(pos1.getY(), pos2.getY()); int y2 = Math.max(pos1.getY(), pos2.getY()); int czMin = (z1 >> 4); int czMax = (z2 >> 4); for (int cz = czMin; cz <= czMax; ++cz) { Chunk chunk = world.getChunk(x >> 4, cz); int zMin = Math.max(z1, cz << 4 ); int zMax = Math.min(z2, (cz << 4) + 15); int yMax = Math.min(y2, chunk.getTopFilledSegment() + 15); for (int z = zMin; z <= zMax; ++z) { for (int y = y1; y <= yMax; ++y) { if (chunk.getBlockState(x, y, z).getMaterial() != Material.AIR) { return false; } } } } break; } } return true; } }