mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-25 03:55:35 +01:00
water height
This commit is contained in:
parent
94e5a931ec
commit
b756f93361
@ -13,6 +13,7 @@ import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
@ -43,10 +44,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
private final char[] floor;
|
||||
private final char[] main;
|
||||
private char[] overlay;
|
||||
private int waterHeight = 0;
|
||||
private TextureUtil textureUtil;
|
||||
private boolean randomVariation = true;
|
||||
private int biomePriority = 0;
|
||||
|
||||
private byte waterId = BlockID.STATIONARY_WATER;
|
||||
private boolean modifiedMain = false;
|
||||
|
||||
public HeightMapMCAGenerator(BufferedImage img, File regionFolder) {
|
||||
@ -78,6 +80,14 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
|
||||
public void setWaterHeight(int waterHeight) {
|
||||
this.waterHeight = waterHeight;
|
||||
}
|
||||
|
||||
public void setWaterId(int waterId) {
|
||||
this.waterId = (byte) waterId;
|
||||
}
|
||||
|
||||
public void setTextureRandomVariation(boolean randomVariation) {
|
||||
this.randomVariation = randomVariation;
|
||||
}
|
||||
@ -214,6 +224,9 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (y > waterHeight) {
|
||||
return FaweCache.CACHE_BLOCK[waterId << 4];
|
||||
}
|
||||
return FaweCache.CACHE_BLOCK[0];
|
||||
} else if (y == height) {
|
||||
return FaweCache.CACHE_BLOCK[floor[index]];
|
||||
@ -630,180 +643,203 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
|
||||
@Override
|
||||
public MCAChunk write(MCAChunk chunk, int csx, int cex, int csz, int cez) {
|
||||
int cx = chunk.getX();
|
||||
int cz = chunk.getZ();
|
||||
int[] indexes = indexStore.get();
|
||||
for (int i = 0; i < chunk.ids.length; i++) {
|
||||
byte[] idsArray = chunk.ids[i];
|
||||
if (idsArray != null) {
|
||||
Arrays.fill(idsArray, (byte) 0);
|
||||
Arrays.fill(chunk.data[i], (byte) 0);
|
||||
try {
|
||||
int cx = chunk.getX();
|
||||
int cz = chunk.getZ();
|
||||
int[] indexes = indexStore.get();
|
||||
for (int i = 0; i < chunk.ids.length; i++) {
|
||||
byte[] idsArray = chunk.ids[i];
|
||||
if (idsArray != null) {
|
||||
Arrays.fill(idsArray, (byte) 0);
|
||||
Arrays.fill(chunk.data[i], (byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
int index = 0;
|
||||
int maxY = 0;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int[] heightMap = chunk.getHeightMapArray();
|
||||
int globalIndex;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
globalIndex = z * getWidth() + csx;
|
||||
for (int x = csx; x <= cex; x++, index++, globalIndex++) {
|
||||
indexes[index] = globalIndex;
|
||||
chunk.biomes[index] = biomes[globalIndex];
|
||||
int height = heights[globalIndex] & 0xFF;
|
||||
heightMap[index] = height;
|
||||
maxY = Math.max(maxY, height);
|
||||
minY = Math.min(minY, height);
|
||||
int index = 0;
|
||||
int maxY = 0;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int[] heightMap = chunk.getHeightMapArray();
|
||||
int globalIndex;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
globalIndex = z * getWidth() + csx;
|
||||
for (int x = csx; x <= cex; x++, index++, globalIndex++) {
|
||||
indexes[index] = globalIndex;
|
||||
chunk.biomes[index] = biomes[globalIndex];
|
||||
int height = heights[globalIndex] & 0xFF;
|
||||
heightMap[index] = height;
|
||||
maxY = Math.max(maxY, height);
|
||||
minY = Math.min(minY, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean hasOverlay = this.overlay != null;
|
||||
if (hasOverlay) {
|
||||
maxY++;
|
||||
}
|
||||
int maxLayer = maxY >> 4;
|
||||
int fillLayers = Math.max(0, (minY - 1)) >> 4;
|
||||
for (int layer = 0; layer <= maxLayer; layer++) {
|
||||
if (chunk.ids[layer] == null) {
|
||||
chunk.ids[layer] = new byte[4096];
|
||||
chunk.data[layer] = new byte[2048];
|
||||
chunk.skyLight[layer] = new byte[2048];
|
||||
chunk.blockLight[layer] = new byte[2048];
|
||||
boolean hasOverlay = this.overlay != null;
|
||||
if (hasOverlay) {
|
||||
maxY++;
|
||||
}
|
||||
}
|
||||
if (modifiedMain) { // If the main block is modified, we can't short circuit this
|
||||
for (int layer = 0; layer < fillLayers; layer++) {
|
||||
index = 0;
|
||||
int maxLayer = maxY >> 4;
|
||||
int fillLayers = Math.max(0, (minY - 1)) >> 4;
|
||||
for (int layer = 0; layer <= maxLayer; layer++) {
|
||||
if (chunk.ids[layer] == null) {
|
||||
chunk.ids[layer] = new byte[4096];
|
||||
chunk.data[layer] = new byte[2048];
|
||||
chunk.skyLight[layer] = new byte[2048];
|
||||
chunk.blockLight[layer] = new byte[2048];
|
||||
}
|
||||
}
|
||||
if (modifiedMain) { // If the main block is modified, we can't short circuit this
|
||||
for (int layer = 0; layer < fillLayers; layer++) {
|
||||
index = 0;
|
||||
byte[] layerIds = chunk.ids[layer];
|
||||
byte[] layerDatas = chunk.data[layer];
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
for (int x = csx; x <= cex; x++, index++) {
|
||||
globalIndex = indexes[index];
|
||||
char mainCombined = main[globalIndex];
|
||||
byte id = (byte) FaweCache.getId(mainCombined);
|
||||
int data = FaweCache.getData(mainCombined);
|
||||
if (data != 0) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
int mainIndex = index + (y << 8);
|
||||
chunk.setNibble(mainIndex, layerDatas, data);
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < 16; y++) {
|
||||
layerIds[index + (y << 8)] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int layer = 0; layer < fillLayers; layer++) {
|
||||
Arrays.fill(chunk.ids[layer], (byte) 1);
|
||||
}
|
||||
}
|
||||
if (waterHeight != 0) {
|
||||
maxY = Math.max(maxY, waterHeight);
|
||||
int maxWaterLayer = ((waterHeight + 15) >> 4);
|
||||
for (int layer = 0; layer < maxWaterLayer; layer++) {
|
||||
boolean fillAll = (layer << 4) + 15 <= waterHeight;
|
||||
byte[] ids = chunk.ids[layer];
|
||||
if (ids == null) {
|
||||
chunk.ids[layer] = ids = new byte[4096];
|
||||
chunk.data[layer] = new byte[2048];
|
||||
chunk.skyLight[layer] = new byte[2048];
|
||||
chunk.blockLight[layer] = new byte[2048];
|
||||
Arrays.fill(chunk.skyLight[layer], (byte) 255);
|
||||
}
|
||||
if (fillAll) {
|
||||
Arrays.fill(ids, waterId);
|
||||
} else {
|
||||
int maxIndex = maxWaterLayer << 8;
|
||||
Arrays.fill(ids, 0, maxIndex, waterId);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int layer = fillLayers; layer <= maxLayer; layer++) {
|
||||
Arrays.fill(chunk.skyLight[layer], (byte) 255);
|
||||
byte[] layerIds = chunk.ids[layer];
|
||||
byte[] layerDatas = chunk.data[layer];
|
||||
index = 0;
|
||||
int startY = layer << 4;
|
||||
int endY = startY + 15;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
for (int x = csx; x <= cex; x++, index++) {
|
||||
globalIndex = indexes[index];
|
||||
int height = heightMap[index];
|
||||
int diff;
|
||||
if (height > endY) {
|
||||
diff = 16;
|
||||
} else if (height >= startY) {
|
||||
diff = height - startY;
|
||||
char floorCombined = floor[globalIndex];
|
||||
int id = FaweCache.getId(floorCombined);
|
||||
int floorIndex = index + ((height & 15) << 8);
|
||||
layerIds[floorIndex] = (byte) id;
|
||||
int data = FaweCache.getData(floorCombined);
|
||||
if (data != 0) {
|
||||
chunk.setNibble(floorIndex, layerDatas, data);
|
||||
}
|
||||
if (hasOverlay && height >= startY - 1 && height < endY) {
|
||||
char overlayCombined = overlay[globalIndex];
|
||||
id = FaweCache.getId(overlayCombined);
|
||||
int overlayIndex = index + (((height + 1) & 15) << 8);
|
||||
layerIds[overlayIndex] = (byte) id;
|
||||
data = FaweCache.getData(overlayCombined);
|
||||
if (data != 0) {
|
||||
chunk.setNibble(overlayIndex, layerDatas, data);
|
||||
}
|
||||
}
|
||||
} else if (hasOverlay && height == startY - 1) {
|
||||
char overlayCombined = overlay[globalIndex];
|
||||
int id = FaweCache.getId(overlayCombined);
|
||||
int overlayIndex = index + (((height + 1) & 15) << 8);
|
||||
layerIds[overlayIndex] = (byte) id;
|
||||
int data = FaweCache.getData(overlayCombined);
|
||||
if (data != 0) {
|
||||
chunk.setNibble(overlayIndex, layerDatas, data);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
char mainCombined = main[globalIndex];
|
||||
byte id = (byte) FaweCache.getId(mainCombined);
|
||||
int data = FaweCache.getData(mainCombined);
|
||||
if (data != 0) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int y = 0; y < diff; y++) {
|
||||
int mainIndex = index + (y << 8);
|
||||
chunk.setNibble(mainIndex, layerDatas, data);
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int y = 0; y < diff; y++) {
|
||||
layerIds[index + (y << 8)] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int layer = 0; layer < fillLayers; layer++) {
|
||||
Arrays.fill(chunk.ids[layer], (byte) 1);
|
||||
int maxYMod = 15 + (maxLayer << 4);
|
||||
for (int layer = (maxY >> 4) + 1; layer < 16; layer++) {
|
||||
chunk.ids[layer] = null;
|
||||
chunk.data[layer] = null;
|
||||
}
|
||||
}
|
||||
for (int layer = fillLayers; layer <= maxLayer; layer++) {
|
||||
Arrays.fill(chunk.skyLight[layer], (byte) 255);
|
||||
byte[] layerIds = chunk.ids[layer];
|
||||
byte[] layerDatas = chunk.data[layer];
|
||||
index = 0;
|
||||
int startY = layer << 4;
|
||||
int endY = startY + 15;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
for (int x = csx; x <= cex; x++, index++) {
|
||||
globalIndex = indexes[index];
|
||||
int height = heightMap[index];
|
||||
int diff;
|
||||
if (height > endY) {
|
||||
diff = 16;
|
||||
} else if (height >= startY) {
|
||||
diff = height - startY;
|
||||
char floorCombined = floor[globalIndex];
|
||||
int id = FaweCache.getId(floorCombined);
|
||||
int floorIndex = index + ((height & 15) << 8);
|
||||
layerIds[floorIndex] = (byte) id;
|
||||
int data = FaweCache.getData(floorCombined);
|
||||
if (data != 0) {
|
||||
chunk.setNibble(floorIndex, layerDatas, data);
|
||||
}
|
||||
if (hasOverlay && height >= startY - 1 && height < endY) {
|
||||
char overlayCombined = overlay[globalIndex];
|
||||
id = FaweCache.getId(overlayCombined);
|
||||
int overlayIndex = index + (((height + 1) & 15) << 8);
|
||||
layerIds[overlayIndex] = (byte) id;
|
||||
data = FaweCache.getData(overlayCombined);
|
||||
if (data != 0) {
|
||||
chunk.setNibble(overlayIndex, layerDatas, data);
|
||||
{ // Bedrock
|
||||
byte[] layerIds = chunk.ids[0];
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
for (int x = csx; x <= cex; x++) {
|
||||
layerIds[index++] = (byte) 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
int chunkPair = MathMan.pair((short) cx, (short) cz);
|
||||
char[][][] localBlocks = blocks.get(chunkPair);
|
||||
if (localBlocks != null) {
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
int by = layer << 4;
|
||||
int ty = by + 15;
|
||||
index = 0;
|
||||
for (int y = by; y <= ty; y++, index += 256) {
|
||||
char[][] yBlocks = localBlocks[y];
|
||||
if (yBlocks != null) {
|
||||
if (chunk.ids[layer] == null) {
|
||||
chunk.ids[layer] = new byte[4096];
|
||||
chunk.data[layer] = new byte[2048];
|
||||
chunk.skyLight[layer] = new byte[2048];
|
||||
chunk.blockLight[layer] = new byte[2048];
|
||||
}
|
||||
}
|
||||
} else if (hasOverlay && height == startY - 1) {
|
||||
char overlayCombined = overlay[globalIndex];
|
||||
int id = FaweCache.getId(overlayCombined);
|
||||
int overlayIndex = index + (((height + 1) & 15) << 8);
|
||||
layerIds[overlayIndex] = (byte) id;
|
||||
int data = FaweCache.getData(overlayCombined);
|
||||
if (data != 0) {
|
||||
chunk.setNibble(overlayIndex, layerDatas, data);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
char mainCombined = main[globalIndex];
|
||||
byte id = (byte) FaweCache.getId(mainCombined);
|
||||
int data = FaweCache.getData(mainCombined);
|
||||
if (data != 0) {
|
||||
for (int y = 0; y < diff; y++) {
|
||||
int mainIndex = index + (y << 8);
|
||||
chunk.setNibble(mainIndex, layerDatas, data);
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < diff; y++) {
|
||||
layerIds[index + (y << 8)] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int maxYMod = 15 + (maxLayer << 4);
|
||||
for (int layer = (maxY >> 4) + 1; layer < 16; layer++) {
|
||||
chunk.ids[layer] = null;
|
||||
chunk.data[layer] = null;
|
||||
}
|
||||
index = 0;
|
||||
{ // Bedrock
|
||||
byte[] layerIds = chunk.ids[0];
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
for (int x = csx; x <= cex; x++) {
|
||||
layerIds[index++] = (byte) 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
int chunkPair = MathMan.pair((short) cx, (short) cz);
|
||||
char[][][] localBlocks = blocks.get(chunkPair);
|
||||
if (localBlocks != null) {
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
int by = layer << 4;
|
||||
int ty = by + 15;
|
||||
index = 0;
|
||||
for (int y = by; y <= ty; y++, index += 256) {
|
||||
char[][] yBlocks = localBlocks[y];
|
||||
if (yBlocks != null) {
|
||||
if (chunk.ids[layer] == null) {
|
||||
chunk.ids[layer] = new byte[4096];
|
||||
chunk.data[layer] = new byte[2048];
|
||||
chunk.skyLight[layer] = new byte[2048];
|
||||
chunk.blockLight[layer] = new byte[2048];
|
||||
}
|
||||
byte[] idsLayer = chunk.ids[layer];
|
||||
byte[] dataLayer = chunk.data[layer];
|
||||
for (int z = 0; z < yBlocks.length; z++) {
|
||||
char[] zBlocks = yBlocks[z];
|
||||
if (zBlocks != null) {
|
||||
int zIndex = index + (z << 4);
|
||||
for (int x = 0; x < zBlocks.length; x++, zIndex++) {
|
||||
char combined = zBlocks[x];
|
||||
if (combined == 0) continue;
|
||||
int id = FaweCache.getId(combined);
|
||||
if (!FaweCache.hasData(id)) {
|
||||
chunk.setIdUnsafe(idsLayer, zIndex, (byte) id);
|
||||
} else {
|
||||
chunk.setBlockUnsafe(idsLayer, dataLayer, zIndex, (byte) id, FaweCache.getData(combined));
|
||||
byte[] idsLayer = chunk.ids[layer];
|
||||
byte[] dataLayer = chunk.data[layer];
|
||||
for (int z = 0; z < yBlocks.length; z++) {
|
||||
char[] zBlocks = yBlocks[z];
|
||||
if (zBlocks != null) {
|
||||
int zIndex = index + (z << 4);
|
||||
for (int x = 0; x < zBlocks.length; x++, zIndex++) {
|
||||
char combined = zBlocks[x];
|
||||
if (combined == 0) continue;
|
||||
int id = FaweCache.getId(combined);
|
||||
if (!FaweCache.hasData(id)) {
|
||||
chunk.setIdUnsafe(idsLayer, zIndex, (byte) id);
|
||||
} else {
|
||||
chunk.setBlockUnsafe(idsLayer, dataLayer, zIndex, (byte) id, FaweCache.getData(combined));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -811,6 +847,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
@ -145,6 +145,8 @@ public class CreateFromImage extends Command {
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi ore[s]");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi schem <mask> <schem> <rarity> <rotate>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi height <image-url|height>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi waterheight <height>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi waterid <number-id>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi color <image-url>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi glass <image-url>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi biomeColor <image-url>");
|
||||
@ -304,6 +306,30 @@ public class CreateFromImage extends Command {
|
||||
player.sendMessage("Set glass color, what's next?");
|
||||
return;
|
||||
}
|
||||
case "waterheight":
|
||||
case "setwaterheight": {
|
||||
// roughness
|
||||
// blocks
|
||||
if (argList.size() != 2) {
|
||||
C.COMMAND_SYNTAX.send(player, "/2 cfi " + argList.get(0) + " <height>");
|
||||
return;
|
||||
}
|
||||
generator.setWaterHeight(Integer.parseInt(argList.get(1)));
|
||||
player.sendMessage("Set water height, what's next?");
|
||||
return;
|
||||
}
|
||||
case "waterid":
|
||||
case "setwaterid": {
|
||||
// roughness
|
||||
// blocks
|
||||
if (argList.size() != 2) {
|
||||
C.COMMAND_SYNTAX.send(player, "/2 cfi " + argList.get(0) + " <id>");
|
||||
return;
|
||||
}
|
||||
generator.setWaterId(Integer.parseInt(argList.get(1)));
|
||||
player.sendMessage("Set water id, what's next?");
|
||||
return;
|
||||
}
|
||||
case "height":
|
||||
case "setheight": {
|
||||
if (argList.size() != 2) {
|
||||
|
Loading…
Reference in New Issue
Block a user