package net.tropicraft.world.genlayer; import net.minecraft.world.gen.layer.IntCache; public class GenLayerTropiVoronoiZoom extends GenLayerTropicraft { public enum Mode { CARTESIAN, MANHATTAN; } public Mode zoomMode; public GenLayerTropiVoronoiZoom(long seed, GenLayerTropicraft parent, Mode zoomMode) { super(seed); super.parent = parent; this.zoomMode = zoomMode; this.setZoom(1); } /** * Returns a list of integer values generated by this layer. These may be interpreted as temperatures, rainfall * amounts, or biomeList[] indices based on the particular GenLayer subclass. */ public int[] getInts(int x, int y, int width, int length) { final int randomResolution = 1024; final double half = 0.5D; final double almostTileSize = 3.6D; final double tileSize = 4D; x -= 2; y -= 2; int scaledX = x >> 2; int scaledY = y >> 2; int scaledWidth = (width >> 2) + 2; int scaledLength = (length >> 2) + 2; int[] parentValues = this.parent.getInts(scaledX, scaledY, scaledWidth, scaledLength); int bitshiftedWidth = scaledWidth - 1 << 2; int bitshiftedLength = scaledLength - 1 << 2; int[] aint1 = IntCache.getIntCache(bitshiftedWidth * bitshiftedLength); int i; for(int j = 0; j < scaledLength - 1; ++j) { i = 0; int baseValue = parentValues[i + 0 + (j + 0) * scaledWidth]; for(int advancedValueJ = parentValues[i + 0 + (j + 1) * scaledWidth]; i < scaledWidth - 1; ++i) { this.initChunkSeed((long)(i + scaledX << 2), (long)(j + scaledY << 2)); double offsetY = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize; double offsetX = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize; this.initChunkSeed((long)(i + scaledX + 1 << 2), (long)(j + scaledY << 2)); double offsetYY = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize + tileSize; double offsetXY = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize; this.initChunkSeed((long)(i + scaledX << 2), (long)(j + scaledY + 1 << 2)); double offsetYX = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize; double offsetXX = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize + tileSize; this.initChunkSeed((long)(i + scaledX + 1 << 2), (long)(j + scaledY + 1 << 2)); double offsetYXY = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize + tileSize; double offsetXXY = ((double)this.nextInt(randomResolution) / randomResolution - half) * almostTileSize + tileSize; int advancedValueI = parentValues[i + 1 + (j + 0) * scaledWidth] & 255; int advancedValueIJ = parentValues[i + 1 + (j + 1) * scaledWidth] & 255; for(int innerX = 0; innerX < 4; ++innerX) { int index = ((j << 2) + innerX) * bitshiftedWidth + (i << 2); for(int innerY = 0; innerY < 4; ++innerY) { double baseDistance; double distanceY; double distanceX; double distanceXY; switch(zoomMode) { case CARTESIAN: baseDistance = ((double)innerX - offsetX) * ((double)innerX - offsetX) + ((double)innerY - offsetY) * ((double)innerY - offsetY); distanceY = ((double)innerX - offsetXY) * ((double)innerX - offsetXY) + ((double)innerY - offsetYY) * ((double)innerY - offsetYY); distanceX = ((double)innerX - offsetXX) * ((double)innerX - offsetXX) + ((double)innerY - offsetYX) * ((double)innerY - offsetYX); distanceXY = ((double)innerX - offsetXXY) * ((double)innerX - offsetXXY) + ((double)innerY - offsetYXY) * ((double)innerY - offsetYXY); break; case MANHATTAN: baseDistance = Math.abs(innerX - offsetX) + Math.abs(innerY - offsetY); distanceY = Math.abs(innerX - offsetXY) + Math.abs(innerY - offsetYY); distanceX = Math.abs(innerX - offsetXX) + Math.abs(innerY - offsetYX); distanceXY = Math.abs(innerX - offsetXXY) + Math.abs(innerY - offsetYXY); break; default: baseDistance = ((double)innerX - offsetX) * ((double)innerX - offsetX) + ((double)innerY - offsetY) * ((double)innerY - offsetY); distanceY = ((double)innerX - offsetXY) * ((double)innerX - offsetXY) + ((double)innerY - offsetYY) * ((double)innerY - offsetYY); distanceX = ((double)innerX - offsetXX) * ((double)innerX - offsetXX) + ((double)innerY - offsetYX) * ((double)innerY - offsetYX); distanceXY = ((double)innerX - offsetXXY) * ((double)innerX - offsetXXY) + ((double)innerY - offsetYXY) * ((double)innerY - offsetYXY); } if(baseDistance < distanceY && baseDistance < distanceX && baseDistance < distanceXY) { aint1[index++] = baseValue; } else if(distanceY < baseDistance && distanceY < distanceX && distanceY < distanceXY) { aint1[index++] = advancedValueI; } else if(distanceX < baseDistance && distanceX < distanceY && distanceX < distanceXY) { aint1[index++] = advancedValueJ; } else { aint1[index++] = advancedValueIJ; } } } baseValue = advancedValueI; advancedValueJ = advancedValueIJ; } } int[] aint2 = IntCache.getIntCache(width * length); for(i = 0; i < length; ++i) { System.arraycopy(aint1, (i + (y & 3)) * bitshiftedWidth + (x & 3), aint2, i * width, width); } return aint2; } @Override public void setZoom(int zoom) { this.zoom = zoom; parent.setZoom(zoom * 4); } }