Various minor
Fix transforms and mask help pages Closes #852 Add world and floor thickness to CFI Fix snow layers not affecting leaves
This commit is contained in:
parent
e6ea640d21
commit
4609b472fe
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,3 +30,4 @@ spigot-1.10
|
|||||||
wiki_permissions.md
|
wiki_permissions.md
|
||||||
/textures
|
/textures
|
||||||
*.iml
|
*.iml
|
||||||
|
/obj
|
@ -582,15 +582,28 @@ public class CFICommands extends MethodCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = {"thickness", "width", "floorthickness"},
|
aliases = {"thickness", "width", "worldthickness"},
|
||||||
usage = "<height>",
|
usage = "<height>",
|
||||||
desc = "Set the thickness of the generated world from the floor\n" +
|
desc = "Set the thickness of the generated world\n" +
|
||||||
|
" - A value of 0 is the default and will not modify the height"
|
||||||
|
)
|
||||||
|
@CommandPermissions("worldedit.anvil.cfi")
|
||||||
|
public void worldthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
|
||||||
|
assertSettings(fp).getGenerator().setWorldThickness(height);
|
||||||
|
msg("Set world thickness!").send(fp);
|
||||||
|
component(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
aliases = {"floorthickness", "floorheight", "floorwidth"},
|
||||||
|
usage = "<height>",
|
||||||
|
desc = "Set the thickness of the top layer\n" +
|
||||||
" - A value of 0 is the default and will only set the top block"
|
" - A value of 0 is the default and will only set the top block"
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.anvil.cfi")
|
@CommandPermissions("worldedit.anvil.cfi")
|
||||||
public void floorthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
|
public void floorthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
|
||||||
assertSettings(fp).getGenerator().setFloorThickness(height);
|
assertSettings(fp).getGenerator().setFloorThickness(height);
|
||||||
msg("Set world thickness!").send(fp);
|
msg("Set floor thickness!").send(fp);
|
||||||
component(fp);
|
component(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,6 +957,8 @@ public class CFICommands extends MethodCommands {
|
|||||||
.newline()
|
.newline()
|
||||||
.text("&7[&aFloorThickness&7]").suggestTip(alias() + " " + alias("floorthickness") + " 60").text(" - Floor thickness of entire map")
|
.text("&7[&aFloorThickness&7]").suggestTip(alias() + " " + alias("floorthickness") + " 60").text(" - Floor thickness of entire map")
|
||||||
.newline()
|
.newline()
|
||||||
|
.text("&7[&aWorldThickness&7]").suggestTip(alias() + " " + alias("worldthickness") + " 60").text(" - World thickness of entire map")
|
||||||
|
.newline()
|
||||||
.text("&7[&aSnow&7]").suggestTip(alias() + " " + alias("snow") + maskArgs).text(" - Set snow in the masked areas")
|
.text("&7[&aSnow&7]").suggestTip(alias() + " " + alias("snow") + maskArgs).text(" - Set snow in the masked areas")
|
||||||
.newline();
|
.newline();
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import com.sk89q.worldedit.WorldEdit;
|
|||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||||
|
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -25,6 +26,8 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract Dispatcher getDispatcher();
|
||||||
|
|
||||||
public List<String> suggestRemaining(String input, String... expected) throws InputParseException {
|
public List<String> suggestRemaining(String input, String... expected) throws InputParseException {
|
||||||
List<String> remainder = StringMan.split(input, ':');
|
List<String> remainder = StringMan.split(input, ':');
|
||||||
int len = remainder.size();
|
int len = remainder.size();
|
||||||
|
@ -43,7 +43,6 @@ public enum BBC {
|
|||||||
WORLDEDIT_ITERATIONS("&7You cannot iterate %current% times. The maximum number of iterations allowed is %max%.", "Info"),
|
WORLDEDIT_ITERATIONS("&7You cannot iterate %current% times. The maximum number of iterations allowed is %max%.", "Info"),
|
||||||
WORLDEDIT_UNSAFE("&7Access to that command has been blocked", "Info"),
|
WORLDEDIT_UNSAFE("&7Access to that command has been blocked", "Info"),
|
||||||
WORLDEDIT_DANGEROUS_WORLDEDIT("&cProcessed unsafe edit at %s0 by %s1", "Info"),
|
WORLDEDIT_DANGEROUS_WORLDEDIT("&cProcessed unsafe edit at %s0 by %s1", "Info"),
|
||||||
WORLDEDIT_BYPASS("&7&oTo bypass your restrictions use &c/wea", "Info"),
|
|
||||||
WORLDEDIT_EXTEND("&cYour edit may have extended outside your allowed region.", "Error"),
|
WORLDEDIT_EXTEND("&cYour edit may have extended outside your allowed region.", "Error"),
|
||||||
WORLDEDIT_TOGGLE_TIPS_ON("&7Disabled FAWE tips.", "Info"),
|
WORLDEDIT_TOGGLE_TIPS_ON("&7Disabled FAWE tips.", "Info"),
|
||||||
WORLDEDIT_TOGGLE_TIPS_OFF("&7Enabled FAWE tips.", "Info"),
|
WORLDEDIT_TOGGLE_TIPS_OFF("&7Enabled FAWE tips.", "Info"),
|
||||||
|
@ -91,6 +91,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
public final class CFIPrimtives implements Cloneable {
|
public final class CFIPrimtives implements Cloneable {
|
||||||
protected int waterHeight = 0;
|
protected int waterHeight = 0;
|
||||||
protected int floorThickness = 0;
|
protected int floorThickness = 0;
|
||||||
|
protected int worldThickness = 0;
|
||||||
protected boolean randomVariation = true;
|
protected boolean randomVariation = true;
|
||||||
protected int biomePriority = 0;
|
protected int biomePriority = 0;
|
||||||
protected byte waterId = BlockID.STATIONARY_WATER;
|
protected byte waterId = BlockID.STATIONARY_WATER;
|
||||||
@ -366,6 +367,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
this.primtives.floorThickness = floorThickness;
|
this.primtives.floorThickness = floorThickness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setWorldThickness(int height) {
|
||||||
|
this.primtives.worldThickness = height;
|
||||||
|
}
|
||||||
|
|
||||||
public void setWaterHeight(int waterHeight) {
|
public void setWaterHeight(int waterHeight) {
|
||||||
this.primtives.waterHeight = waterHeight;
|
this.primtives.waterHeight = waterHeight;
|
||||||
}
|
}
|
||||||
@ -546,13 +551,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addCaves() throws WorldEditException {
|
public void addCaves() throws WorldEditException {
|
||||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1));
|
||||||
addCaves(region);
|
addCaves(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void addSchems(Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
public void addSchems(Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1));
|
||||||
addSchems(region, mask, worldData, clipboards, rarity, rotate);
|
addSchems(region, mask, worldData, clipboards, rarity, rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,12 +662,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1));
|
||||||
addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDefaultOres(Mask mask) throws WorldEditException {
|
public void addDefaultOres(Mask mask) throws WorldEditException {
|
||||||
addOres(new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength())), mask);
|
addOres(new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1)), mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -921,7 +926,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||||
int index = z * getWidth() + x;
|
int index = z * getWidth() + x;
|
||||||
if (y < 0) return 0;
|
if (y < 0) return 0;
|
||||||
if (index < 0 || index >= getArea()) index = Math.floorMod(index, getArea());
|
if (index < 0 || index >= getArea() || x < 0 || x >= getWidth()) return 0;
|
||||||
int height = heights.getByte(index) & 0xFF;
|
int height = heights.getByte(index) & 0xFF;
|
||||||
if (y > height) {
|
if (y > height) {
|
||||||
if (y == height + 1) {
|
if (y == height + 1) {
|
||||||
@ -1824,7 +1829,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primtives.floorThickness != 0) {
|
if (primtives.floorThickness != 0 || primtives.worldThickness != 0) {
|
||||||
// Use biomes array as temporary buffer
|
// Use biomes array as temporary buffer
|
||||||
byte[] minArr = chunk.biomes;
|
byte[] minArr = chunk.biomes;
|
||||||
for (int z = csz; z <= cez; z++) {
|
for (int z = csz; z <= cez; z++) {
|
||||||
@ -1842,10 +1847,50 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
}
|
}
|
||||||
|
|
||||||
int minLayer = Math.max(0, (minY - primtives.floorThickness) >> 4);
|
int minLayer = Math.max(0, (minY - primtives.floorThickness) >> 4);
|
||||||
|
if (primtives.worldThickness != 0) {
|
||||||
for (int layer = 0; layer < minLayer; layer++) {
|
for (int layer = 0; layer < minLayer; layer++) {
|
||||||
chunk.ids[layer] = null;
|
chunk.ids[layer] = null;
|
||||||
chunk.data[layer] = null;
|
chunk.data[layer] = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (primtives.floorThickness != 0) {
|
||||||
|
for (int layer = minLayer; layer <= maxLayer; layer++) {
|
||||||
|
byte[] layerIds = chunk.ids[layer];
|
||||||
|
byte[] layerDatas = chunk.data[layer];
|
||||||
|
int startY = layer << 4;
|
||||||
|
int endY = startY + 15;
|
||||||
|
for (int z = csz; z <= cez; z++) {
|
||||||
|
index = (z & 15) << 4;
|
||||||
|
for (int x = csx; x <= cex; x++, index++) {
|
||||||
|
globalIndex = indexes[index];
|
||||||
|
int height = heightMap[index];
|
||||||
|
|
||||||
|
int min = (minArr[index] & 0xFF) - primtives.floorThickness;
|
||||||
|
int localMin = min - startY;
|
||||||
|
|
||||||
|
int max = height + 1;
|
||||||
|
if (min < startY) min = startY;
|
||||||
|
if (max > endY) max = endY + 1;
|
||||||
|
|
||||||
|
|
||||||
|
if (min < max) {
|
||||||
|
char floorCombined = floor[globalIndex];
|
||||||
|
final byte id = (byte) FaweCache.getId(floorCombined);
|
||||||
|
final int data = FaweCache.getData(floorCombined);
|
||||||
|
for (int y = min; y < max; y++) {
|
||||||
|
int floorIndex = index + ((y & 15) << 8);
|
||||||
|
layerIds[floorIndex] = id;
|
||||||
|
if (data != 0) {
|
||||||
|
chunk.setNibble(floorIndex, layerDatas, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (primtives.worldThickness != 0) {
|
||||||
for (int layer = minLayer; layer <= maxLayer; layer++) {
|
for (int layer = minLayer; layer <= maxLayer; layer++) {
|
||||||
byte[] layerIds = chunk.ids[layer];
|
byte[] layerIds = chunk.ids[layer];
|
||||||
byte[] layerDatas = chunk.data[layer];
|
byte[] layerDatas = chunk.data[layer];
|
||||||
@ -1875,6 +1920,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int layer = fillLayers; layer <= maxLayer; layer++) {
|
for (int layer = fillLayers; layer <= maxLayer; layer++) {
|
||||||
Arrays.fill(chunk.skyLight[layer], (byte) 255);
|
Arrays.fill(chunk.skyLight[layer], (byte) 255);
|
||||||
|
@ -123,6 +123,9 @@ public class MCAFile {
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the location header from disk
|
||||||
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
try {
|
try {
|
||||||
if (raf == null) {
|
if (raf == null) {
|
||||||
@ -403,7 +406,9 @@ public class MCAFile {
|
|||||||
if (raf.length() - offset < len) {
|
if (raf.length() - offset < len) {
|
||||||
raf.setLength(((offset + len + 4095) / 4096) * 4096);
|
raf.setLength(((offset + len + 4095) / 4096) * 4096);
|
||||||
}
|
}
|
||||||
|
// Length of remaining data
|
||||||
raf.writeInt(data.length + 1);
|
raf.writeInt(data.length + 1);
|
||||||
|
// Compression type
|
||||||
raf.write(2);
|
raf.write(2);
|
||||||
raf.write(data);
|
raf.write(data);
|
||||||
}
|
}
|
||||||
@ -458,24 +463,38 @@ public class MCAFile {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the chunk to the file
|
||||||
|
* @param pool
|
||||||
|
*/
|
||||||
public void flush(ForkJoinPool pool) {
|
public void flush(ForkJoinPool pool) {
|
||||||
synchronized (raf) {
|
synchronized (raf) {
|
||||||
|
// If the file is marked as deleted, nothing is written
|
||||||
if (isDeleted()) {
|
if (isDeleted()) {
|
||||||
clear();
|
clear();
|
||||||
file.delete();
|
file.delete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean wait;
|
|
||||||
|
boolean wait; // If the flush method needs to wait for the pool
|
||||||
if (pool == null) {
|
if (pool == null) {
|
||||||
wait = true;
|
wait = true;
|
||||||
pool = new ForkJoinPool();
|
pool = new ForkJoinPool();
|
||||||
} else wait = false;
|
} else wait = false;
|
||||||
|
|
||||||
|
// Chunks that need to be relocated
|
||||||
Int2ObjectOpenHashMap<byte[]> relocate = new Int2ObjectOpenHashMap<>();
|
Int2ObjectOpenHashMap<byte[]> relocate = new Int2ObjectOpenHashMap<>();
|
||||||
|
// The position of each chunk
|
||||||
final Int2ObjectOpenHashMap<Integer> offsetMap = new Int2ObjectOpenHashMap<>(); // Offset -> <byte cx, byte cz, short size>
|
final Int2ObjectOpenHashMap<Integer> offsetMap = new Int2ObjectOpenHashMap<>(); // Offset -> <byte cx, byte cz, short size>
|
||||||
|
// The data of each modified chunk
|
||||||
final Int2ObjectOpenHashMap<byte[]> compressedMap = new Int2ObjectOpenHashMap<>();
|
final Int2ObjectOpenHashMap<byte[]> compressedMap = new Int2ObjectOpenHashMap<>();
|
||||||
|
// The data of each chunk that needs to be moved
|
||||||
final Int2ObjectOpenHashMap<byte[]> append = new Int2ObjectOpenHashMap<>();
|
final Int2ObjectOpenHashMap<byte[]> append = new Int2ObjectOpenHashMap<>();
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
|
// Get the current time for the chunk timestamp
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// Load the chunks into the append or compressed map
|
||||||
for (MCAChunk chunk : getCachedChunks()) {
|
for (MCAChunk chunk : getCachedChunks()) {
|
||||||
if (chunk.isModified() || chunk.isDeleted()) {
|
if (chunk.isModified() || chunk.isDeleted()) {
|
||||||
modified = true;
|
modified = true;
|
||||||
@ -504,8 +523,12 @@ public class MCAFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If any changes were detected
|
||||||
if (modified) {
|
if (modified) {
|
||||||
file.setLastModified(now);
|
file.setLastModified(now);
|
||||||
|
|
||||||
|
// Load the offset data into the offset map
|
||||||
forEachChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
forEachChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Integer cx, Integer cz, Integer offset, Integer size) {
|
public void run(Integer cx, Integer cz, Integer offset, Integer size) {
|
||||||
@ -514,29 +537,41 @@ public class MCAFile {
|
|||||||
offsetMap.put((int) offset, (Integer) MathMan.pair(pair1, pair2));
|
offsetMap.put((int) offset, (Integer) MathMan.pair(pair1, pair2));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Wait for previous tasks
|
||||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
|
||||||
int start = 8192;
|
int start = 8192;
|
||||||
int written = start;
|
int written = start;
|
||||||
int end = 8192;
|
int end = 8192;
|
||||||
int nextOffset = 8192;
|
int nextOffset = 8192;
|
||||||
try {
|
try {
|
||||||
for (int count = 0; count < offsetMap.size(); count++) {
|
for (int count = 0; count < offsetMap.size(); count++) {
|
||||||
|
// Get the previous position of the next chunk
|
||||||
Integer loc = offsetMap.get(nextOffset);
|
Integer loc = offsetMap.get(nextOffset);
|
||||||
while (loc == null) {
|
while (loc == null) {
|
||||||
nextOffset += 4096;
|
nextOffset += 4096;
|
||||||
loc = offsetMap.get(nextOffset);
|
loc = offsetMap.get(nextOffset);
|
||||||
}
|
}
|
||||||
int offset = nextOffset;
|
int offset = nextOffset;
|
||||||
|
|
||||||
|
// Get the x/z from the paired location
|
||||||
short cxz = MathMan.unpairX(loc);
|
short cxz = MathMan.unpairX(loc);
|
||||||
int cx = MathMan.unpairShortX(cxz);
|
int cx = MathMan.unpairShortX(cxz);
|
||||||
int cz = MathMan.unpairShortY(cxz);
|
int cz = MathMan.unpairShortY(cxz);
|
||||||
|
|
||||||
|
// Get the size from the pair
|
||||||
int size = MathMan.unpairY(loc) << 12;
|
int size = MathMan.unpairY(loc) << 12;
|
||||||
|
|
||||||
nextOffset += size;
|
nextOffset += size;
|
||||||
end = Math.min(start + size, end);
|
end = Math.min(start + size, end);
|
||||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||||
byte[] newBytes = relocate.get(pair);
|
byte[] newBytes = relocate.get(pair);
|
||||||
|
|
||||||
|
// newBytes is null if the chunk isn't modified or marked for moving
|
||||||
if (newBytes == null) {
|
if (newBytes == null) {
|
||||||
MCAChunk cached = getCachedChunk(cx, cz);
|
MCAChunk cached = getCachedChunk(cx, cz);
|
||||||
|
// If the previous offset marks the current write position (start) then we only write the header
|
||||||
if (offset == start) {
|
if (offset == start) {
|
||||||
if (cached == null || !cached.isModified()) {
|
if (cached == null || !cached.isModified()) {
|
||||||
writeHeader(raf, cx, cz, start >> 12, size >> 12, true);
|
writeHeader(raf, cx, cz, start >> 12, size >> 12, true);
|
||||||
@ -547,6 +582,7 @@ public class MCAFile {
|
|||||||
newBytes = compressedMap.get(pair);
|
newBytes = compressedMap.get(pair);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// The chunk needs to be moved, fetch the data if necessary
|
||||||
newBytes = compressedMap.get(pair);
|
newBytes = compressedMap.get(pair);
|
||||||
if (newBytes == null) {
|
if (newBytes == null) {
|
||||||
if (cached == null || !cached.isDeleted()) {
|
if (cached == null || !cached.isDeleted()) {
|
||||||
@ -555,14 +591,19 @@ public class MCAFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newBytes == null) {
|
if (newBytes == null) {
|
||||||
writeHeader(raf, cx, cz, 0, 0, false);
|
writeHeader(raf, cx, cz, 0, 0, false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The length to be written (compressed data + 5 byte chunk header)
|
||||||
int len = newBytes.length + 5;
|
int len = newBytes.length + 5;
|
||||||
int oldSize = (size + 4095) >> 12;
|
int oldSize = (size + 4095) >> 12;
|
||||||
int newSize = (len + 4095) >> 12;
|
int newSize = (len + 4095) >> 12;
|
||||||
int nextOffset2 = end;
|
int nextOffset2 = end;
|
||||||
|
|
||||||
|
// If the current write position (start) + length of data to write (len) are longer than the position of the next chunk, we need to move the next chunks
|
||||||
while (start + len > end) {
|
while (start + len > end) {
|
||||||
Integer nextLoc = offsetMap.get(nextOffset2);
|
Integer nextLoc = offsetMap.get(nextOffset2);
|
||||||
if (nextLoc != null) {
|
if (nextLoc != null) {
|
||||||
@ -582,11 +623,16 @@ public class MCAFile {
|
|||||||
nextOffset2 += 4096;
|
nextOffset2 += 4096;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Write the chunk + chunk header
|
||||||
writeSafe(raf, start, newBytes);
|
writeSafe(raf, start, newBytes);
|
||||||
|
// Write the location data (beginning of file)
|
||||||
writeHeader(raf, cx, cz, start >> 12, newSize, true);
|
writeHeader(raf, cx, cz, start >> 12, newSize, true);
|
||||||
|
|
||||||
written = start + newBytes.length + 5;
|
written = start + newBytes.length + 5;
|
||||||
start += newSize << 12;
|
start += newSize << 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write all the chunks which need to be appended
|
||||||
if (!append.isEmpty()) {
|
if (!append.isEmpty()) {
|
||||||
for (Int2ObjectMap.Entry<byte[]> entry : append.int2ObjectEntrySet()) {
|
for (Int2ObjectMap.Entry<byte[]> entry : append.int2ObjectEntrySet()) {
|
||||||
int pair = entry.getIntKey();
|
int pair = entry.getIntKey();
|
||||||
@ -601,6 +647,7 @@ public class MCAFile {
|
|||||||
start += newSize << 12;
|
start += newSize << 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Round the file length, since the vanilla server doesn't like it for some reason
|
||||||
raf.setLength(4096 * ((written + 4095) / 4096));
|
raf.setLength(4096 * ((written + 4095) / 4096));
|
||||||
if (raf instanceof BufferedRandomAccessFile) {
|
if (raf instanceof BufferedRandomAccessFile) {
|
||||||
((BufferedRandomAccessFile) raf).flush();
|
((BufferedRandomAccessFile) raf).flush();
|
||||||
|
@ -123,11 +123,6 @@ public class DelegateTextureUtil extends TextureUtil {
|
|||||||
return TextureUtil.hueDistance(red1, green1, blue1, red2, green2, blue2);
|
return TextureUtil.hueDistance(red1, green1, blue1, red2, green2, blue2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColor(BufferedImage image) {
|
|
||||||
return parent.getColor(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDistance(BufferedImage image, int c1) {
|
public long getDistance(BufferedImage image, int c1) {
|
||||||
return parent.getDistance(image, c1);
|
return parent.getDistance(image, c1);
|
||||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.util;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
|
import com.boydti.fawe.util.image.ImageUtil;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
@ -59,7 +60,6 @@ public class TextureUtil {
|
|||||||
protected int[] validMixBiomeColors;
|
protected int[] validMixBiomeColors;
|
||||||
protected long[] validMixBiomeIds;
|
protected long[] validMixBiomeIds;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
|
* https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
|
||||||
*/
|
*/
|
||||||
@ -638,7 +638,7 @@ public class TextureUtil {
|
|||||||
ZipEntry textureEntry = zipFile.getEntry(path);
|
ZipEntry textureEntry = zipFile.getEntry(path);
|
||||||
try (InputStream is = zipFile.getInputStream(textureEntry)) {
|
try (InputStream is = zipFile.getInputStream(textureEntry)) {
|
||||||
BufferedImage image = ImageIO.read(is);
|
BufferedImage image = ImageIO.read(is);
|
||||||
int color = getColor(image);
|
int color = ImageUtil.getColor(image);
|
||||||
long distance = getDistance(image, color);
|
long distance = getDistance(image, color);
|
||||||
distanceMap.put((int) combined, (Long) distance);
|
distanceMap.put((int) combined, (Long) distance);
|
||||||
colorMap.put((int) combined, (Integer) color);
|
colorMap.put((int) combined, (Integer) color);
|
||||||
@ -1002,30 +1002,6 @@ public class TextureUtil {
|
|||||||
return (int) ((r * r + g * g + b * b) >> 25);
|
return (int) ((r * r + g * g + b * b) >> 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getColor(BufferedImage image) {
|
|
||||||
int width = image.getWidth();
|
|
||||||
int height = image.getHeight();
|
|
||||||
long totalRed = 0;
|
|
||||||
long totalGreen = 0;
|
|
||||||
long totalBlue = 0;
|
|
||||||
long totalAlpha = 0;
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
int color = image.getRGB(x, y);
|
|
||||||
totalRed += (color >> 16) & 0xFF;
|
|
||||||
totalGreen += (color >> 8) & 0xFF;
|
|
||||||
totalBlue += (color >> 0) & 0xFF;
|
|
||||||
totalAlpha += (color >> 24) & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int a = width * height;
|
|
||||||
int red = (int) (totalRed / a);
|
|
||||||
int green = (int) (totalGreen / a);
|
|
||||||
int blue = (int) (totalBlue / a);
|
|
||||||
int alpha = (int) (totalAlpha / a);
|
|
||||||
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDistance(BufferedImage image, int c1) {
|
public long getDistance(BufferedImage image, int c1) {
|
||||||
long totalDistSqr = 0;
|
long totalDistSqr = 0;
|
||||||
int width = image.getWidth();
|
int width = image.getWidth();
|
||||||
|
@ -68,6 +68,30 @@ public class ImageUtil {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getColor(BufferedImage image) {
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
long totalRed = 0;
|
||||||
|
long totalGreen = 0;
|
||||||
|
long totalBlue = 0;
|
||||||
|
long totalAlpha = 0;
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
int color = image.getRGB(x, y);
|
||||||
|
totalRed += (color >> 16) & 0xFF;
|
||||||
|
totalGreen += (color >> 8) & 0xFF;
|
||||||
|
totalBlue += (color >> 0) & 0xFF;
|
||||||
|
totalAlpha += (color >> 24) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int a = width * height;
|
||||||
|
int red = (int) (totalRed / a);
|
||||||
|
int green = (int) (totalGreen / a);
|
||||||
|
int blue = (int) (totalBlue / a);
|
||||||
|
int alpha = (int) (totalAlpha / a);
|
||||||
|
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||||
|
}
|
||||||
|
|
||||||
public static BufferedImage getImage(String arg) throws ParameterException {
|
public static BufferedImage getImage(String arg) throws ParameterException {
|
||||||
try {
|
try {
|
||||||
if (arg.startsWith("http")) {
|
if (arg.startsWith("http")) {
|
||||||
|
@ -2665,6 +2665,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
|||||||
if (dx2 + dz2 > radiusSq) {
|
if (dx2 + dz2 > radiusSq) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
outer:
|
||||||
for (int y = maxY; y >= 1; --y) {
|
for (int y = maxY; y >= 1; --y) {
|
||||||
final int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z));
|
final int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z));
|
||||||
if (id == BlockID.AIR) {
|
if (id == BlockID.AIR) {
|
||||||
@ -2678,7 +2679,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
|||||||
|
|
||||||
// Snow should not cover these blocks
|
// Snow should not cover these blocks
|
||||||
if (BlockType.isTranslucent(id)) {
|
if (BlockType.isTranslucent(id)) {
|
||||||
|
switch (id) {
|
||||||
|
case BlockID.LEAVES:
|
||||||
|
case BlockID.LEAVES2:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break outer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Too high?
|
// Too high?
|
||||||
|
@ -449,6 +449,7 @@ public class LocalSession {
|
|||||||
if (changeSet.isEmpty()) {
|
if (changeSet.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FawePlayer fp = editSession.getPlayer();
|
FawePlayer fp = editSession.getPlayer();
|
||||||
if (fp != null) {
|
if (fp != null) {
|
||||||
loadSessionHistoryFromDisk(fp.getUUID(), editSession.getWorld());
|
loadSessionHistoryFromDisk(fp.getUUID(), editSession.getWorld());
|
||||||
|
@ -32,6 +32,7 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
|
@ -26,6 +26,7 @@ import com.boydti.fawe.object.FawePlayer;
|
|||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
|
import com.boydti.fawe.util.image.ImageUtil;
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
@ -56,6 +57,7 @@ import com.sk89q.worldedit.util.command.binding.Text;
|
|||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParameterException;
|
import com.sk89q.worldedit.util.command.parametric.ParameterException;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -121,7 +123,7 @@ public class GenerationCommands extends MethodCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.generation.image")
|
@CommandPermissions("worldedit.generation.image")
|
||||||
@Logging(PLACEMENT)
|
@Logging(PLACEMENT)
|
||||||
public void image(Player player, LocalSession session, EditSession editSession, String arg, @Optional("true") boolean randomize, @Optional("100") int threshold) throws WorldEditException, ParameterException, IOException {
|
public void image(Player player, LocalSession session, EditSession editSession, String arg, @Optional("true") boolean randomize, @Optional("100") int threshold, @Optional Vector2D dimensions) throws WorldEditException, ParameterException, IOException {
|
||||||
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
|
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
|
||||||
URL url = new URL(arg);
|
URL url = new URL(arg);
|
||||||
if (!url.getHost().equalsIgnoreCase("i.imgur.com") && !url.getHost().equalsIgnoreCase("empcraft.com")) {
|
if (!url.getHost().equalsIgnoreCase("i.imgur.com") && !url.getHost().equalsIgnoreCase("empcraft.com")) {
|
||||||
@ -129,17 +131,22 @@ public class GenerationCommands extends MethodCommands {
|
|||||||
}
|
}
|
||||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||||
BufferedImage image = MainUtil.readImage(url);
|
BufferedImage image = MainUtil.readImage(url);
|
||||||
|
if (dimensions != null) {
|
||||||
|
image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(), RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
||||||
|
}
|
||||||
|
|
||||||
MutableBlockVector pos1 = new MutableBlockVector(player.getPosition());
|
MutableBlockVector pos1 = new MutableBlockVector(player.getPosition());
|
||||||
MutableBlockVector pos2 = new MutableBlockVector(pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1));
|
MutableBlockVector pos2 = new MutableBlockVector(pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1));
|
||||||
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
||||||
int[] count = new int[1];
|
int[] count = new int[1];
|
||||||
|
final BufferedImage finalImage = image;
|
||||||
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Vector pos) throws WorldEditException {
|
public boolean apply(Vector pos) throws WorldEditException {
|
||||||
try {
|
try {
|
||||||
int x = pos.getBlockX() - pos1.getBlockX();
|
int x = pos.getBlockX() - pos1.getBlockX();
|
||||||
int z = pos.getBlockZ() - pos1.getBlockZ();
|
int z = pos.getBlockZ() - pos1.getBlockZ();
|
||||||
int color = image.getRGB(x, z);
|
int color = finalImage.getRGB(x, z);
|
||||||
BaseBlock block = tu.getNearestBlock(color);
|
BaseBlock block = tu.getNearestBlock(color);
|
||||||
count[0]++;
|
count[0]++;
|
||||||
return editSession.setBlockFast(pos, block);
|
return editSession.setBlockFast(pos, block);
|
||||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.command;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweAPI;
|
import com.boydti.fawe.FaweAPI;
|
||||||
|
import com.boydti.fawe.command.FaweParser;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Commands;
|
import com.boydti.fawe.config.Commands;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
@ -48,6 +49,8 @@ import com.sk89q.worldedit.command.util.CreatureButcher;
|
|||||||
import com.sk89q.worldedit.command.util.EntityRemover;
|
import com.sk89q.worldedit.command.util.EntityRemover;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||||
|
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
@ -122,7 +125,7 @@ public class UtilityCommands extends MethodCommands {
|
|||||||
"More Info: https://git.io/vSPmA"
|
"More Info: https://git.io/vSPmA"
|
||||||
)
|
)
|
||||||
public void patterns(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void patterns(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
displayModifierHelp(player, args);
|
displayModifierHelp(player, HashTagPatternParser.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -137,7 +140,7 @@ public class UtilityCommands extends MethodCommands {
|
|||||||
"More Info: https://git.io/v9r4K"
|
"More Info: https://git.io/v9r4K"
|
||||||
)
|
)
|
||||||
public void masks(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void masks(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
displayModifierHelp(player, args);
|
displayModifierHelp(player, DefaultMaskParser.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -151,17 +154,17 @@ public class UtilityCommands extends MethodCommands {
|
|||||||
"More Info: https://git.io/v9KHO"
|
"More Info: https://git.io/v9KHO"
|
||||||
)
|
)
|
||||||
public void transforms(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public void transforms(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
displayModifierHelp(player, args);
|
displayModifierHelp(player, DefaultTransformParser.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayModifierHelp(Player player, CommandContext args) {
|
private void displayModifierHelp(Player player, Class<? extends FaweParser> clazz, CommandContext args) {
|
||||||
|
FaweParser parser = FaweAPI.getParser(clazz);
|
||||||
if (args.argsLength() == 0) {
|
if (args.argsLength() == 0) {
|
||||||
String base = getCommand().aliases()[0];
|
String base = getCommand().aliases()[0];
|
||||||
UsageMessage msg = new UsageMessage(getCallable(), (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + base, args.getLocals());
|
UsageMessage msg = new UsageMessage(getCallable(), (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + base, args.getLocals());
|
||||||
msg.newline().paginate(base, 0, 1).send(player);
|
msg.newline().paginate(base, 0, 1).send(player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HashTagPatternParser parser = FaweAPI.getParser(HashTagPatternParser.class);
|
|
||||||
if (parser != null) {
|
if (parser != null) {
|
||||||
CommandMapping mapping = parser.getDispatcher().get(args.getString(0));
|
CommandMapping mapping = parser.getDispatcher().get(args.getString(0));
|
||||||
if (mapping != null) {
|
if (mapping != null) {
|
||||||
|
@ -38,6 +38,7 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
this.register(new MaskCommands(worldEdit));
|
this.register(new MaskCommands(worldEdit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Dispatcher getDispatcher() {
|
public Dispatcher getDispatcher() {
|
||||||
return dispatcher;
|
return dispatcher;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
|||||||
this.register(new TransformCommands(worldEdit));
|
this.register(new TransformCommands(worldEdit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Dispatcher getDispatcher() {
|
public Dispatcher getDispatcher() {
|
||||||
return dispatcher;
|
return dispatcher;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
this.register(new PatternCommands(worldEdit));
|
this.register(new PatternCommands(worldEdit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Dispatcher getDispatcher() {
|
public Dispatcher getDispatcher() {
|
||||||
return dispatcher;
|
return dispatcher;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,7 @@ public interface Extent extends InputExtent, OutputExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
public default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||||
|
y = Math.max(minY, Math.min(maxY, y));
|
||||||
int clearanceAbove = maxY - y;
|
int clearanceAbove = maxY - y;
|
||||||
int clearanceBelow = y - minY;
|
int clearanceBelow = y - minY;
|
||||||
int clearance = Math.min(clearanceAbove, clearanceBelow);
|
int clearance = Math.min(clearanceAbove, clearanceBelow);
|
||||||
|
@ -179,6 +179,7 @@ public class HeightMap {
|
|||||||
int zr = z + originZ;
|
int zr = z + originZ;
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
int curHeight = this.data[index];
|
int curHeight = this.data[index];
|
||||||
|
if (curHeight == -1) continue;
|
||||||
int newHeight = Math.min(maxY4, data[index++]);
|
int newHeight = Math.min(maxY4, data[index++]);
|
||||||
int curBlock = (curHeight) >> 3;
|
int curBlock = (curHeight) >> 3;
|
||||||
int newBlock = (newHeight + 7) >> 3;
|
int newBlock = (newHeight + 7) >> 3;
|
||||||
@ -255,6 +256,7 @@ public class HeightMap {
|
|||||||
int zr = z + originZ;
|
int zr = z + originZ;
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
int curHeight = this.data[index];
|
int curHeight = this.data[index];
|
||||||
|
if (curHeight == -1) continue;
|
||||||
int newHeight = Math.min(maxY, data[index++]);
|
int newHeight = Math.min(maxY, data[index++]);
|
||||||
int xr = x + originX;
|
int xr = x + originX;
|
||||||
|
|
||||||
|
@ -363,6 +363,32 @@ public class BundledBlockData {
|
|||||||
return legacyMap[id];
|
return legacyMap[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName(BaseBlock block) {
|
||||||
|
BlockEntry entry = legacyMap[block.getId()];
|
||||||
|
if (entry != null) {
|
||||||
|
String name = entry.id;
|
||||||
|
if (block.getData() == 0) return name;
|
||||||
|
StringBuilder append = new StringBuilder();
|
||||||
|
Map<String, FaweState> states = entry.states;
|
||||||
|
FaweState variants = states.get("variant");
|
||||||
|
if (variants == null) variants = states.get("color");
|
||||||
|
if (variants == null && !states.isEmpty()) variants = states.entrySet().iterator().next().getValue();
|
||||||
|
if (variants != null) {
|
||||||
|
for (Map.Entry<String, FaweStateValue> variant : variants.valueMap().entrySet()) {
|
||||||
|
FaweStateValue state = variant.getValue();
|
||||||
|
if (state.isSet(block)) {
|
||||||
|
append.append(append.length() == 0 ? ":" : "|");
|
||||||
|
append.append(variant.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (append.length() == 0) return name + ":" + block.getData();
|
||||||
|
return name + append;
|
||||||
|
}
|
||||||
|
if (block.getData() == 0) return Integer.toString(block.getId());
|
||||||
|
return block.getId() + ":" + block.getData();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the given string ID to a legacy numeric ID.
|
* Convert the given string ID to a legacy numeric ID.
|
||||||
*
|
*
|
||||||
|
@ -42,7 +42,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':core')
|
compile project(':core')
|
||||||
compile 'org.spongepowered:spongeapi:7.0.0-SNAPSHOT'
|
compile 'org.spongepowered:spongeapi:7.1.0-SNAPSHOT'
|
||||||
compile name: 'worldedit-sponge-6.1.9-SNAPSHOT-dist'
|
compile name: 'worldedit-sponge-6.1.9-SNAPSHOT-dist'
|
||||||
compile name: 'worldedit-core-6.1.9-SNAPSHOT-dist'
|
compile name: 'worldedit-core-6.1.9-SNAPSHOT-dist'
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user