Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-08 04:20:06 +01:00
Dieser Commit ist enthalten in:
Ursprung
905fbf5a0b
Commit
ff94a1e5ed
@ -9,25 +9,14 @@ import com.boydti.fawe.object.number.MutableLong;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class MCAChunk extends FaweChunk<Void> {
|
||||
@ -88,9 +77,6 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
}
|
||||
|
||||
public void write(NBTOutputStream nbtOut) throws IOException {
|
||||
|
||||
|
||||
|
||||
nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND);
|
||||
nbtOut.writeLazyCompoundTag("Level", out -> {
|
||||
out.writeNamedTag("V", (byte) 1);
|
||||
@ -107,7 +93,7 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
out.writeNamedEmptyList("TileEntities");
|
||||
} else {
|
||||
out.writeNamedTag("TileEntities", new ListTag(CompoundTag.class,
|
||||
new ArrayList<>(tiles.values())));
|
||||
new ArrayList<>(tiles.values())));
|
||||
}
|
||||
out.writeNamedTag("InhabitedTime", inhabitedTime);
|
||||
out.writeNamedTag("LastUpdate", lastUpdate);
|
||||
@ -116,9 +102,12 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
}
|
||||
out.writeNamedTag("HeightMap", heightMap);
|
||||
out.writeNamedTagName("Sections", NBTConstants.TYPE_LIST);
|
||||
nbtOut.writeByte(NBTConstants.TYPE_COMPOUND);
|
||||
int len = (int) Arrays.stream(ids).filter(Objects::nonNull).count();
|
||||
nbtOut.writeInt(len);
|
||||
nbtOut.getOutputStream().writeByte(NBTConstants.TYPE_COMPOUND);
|
||||
int len = 0;
|
||||
for (int[] id : ids) {
|
||||
if (id != null) len++;
|
||||
}
|
||||
nbtOut.getOutputStream().writeInt(len);
|
||||
for (int layer = 0; layer < ids.length; layer++) {
|
||||
int[] idLayer = ids[layer];
|
||||
if (idLayer == null) {
|
||||
@ -436,9 +425,9 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
blockLight = new byte[16][];
|
||||
NBTStreamer streamer = new NBTStreamer(nis);
|
||||
streamer.addReader(".Level.InhabitedTime",
|
||||
(BiConsumer<Integer, Long>) (index, value) -> inhabitedTime = value);
|
||||
(BiConsumer<Integer, Long>) (index, value) -> inhabitedTime = value);
|
||||
streamer.addReader(".Level.LastUpdate",
|
||||
(BiConsumer<Integer, Long>) (index, value) -> lastUpdate = value);
|
||||
(BiConsumer<Integer, Long>) (index, value) -> lastUpdate = value);
|
||||
streamer.addReader(".Level.Sections.#", (BiConsumer<Integer, CompoundTag>) (index, tag) -> {
|
||||
int layer = tag.getByte("Y");
|
||||
ids[layer] = tag.getIntArray("Blocks");
|
||||
@ -446,31 +435,31 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
blockLight[layer] = tag.getByteArray("BlockLight");
|
||||
});
|
||||
streamer.addReader(".Level.TileEntities.#",
|
||||
(BiConsumer<Integer, CompoundTag>) (index, tile) -> {
|
||||
int x1 = tile.getInt("x") & 15;
|
||||
int y = tile.getInt("y");
|
||||
int z1 = tile.getInt("z") & 15;
|
||||
short pair = MathMan.tripleBlockCoord(x1, y, z1);
|
||||
tiles.put(pair, tile);
|
||||
});
|
||||
(BiConsumer<Integer, CompoundTag>) (index, tile) -> {
|
||||
int x1 = tile.getInt("x") & 15;
|
||||
int y = tile.getInt("y");
|
||||
int z1 = tile.getInt("z") & 15;
|
||||
short pair = MathMan.tripleBlockCoord(x1, y, z1);
|
||||
tiles.put(pair, tile);
|
||||
});
|
||||
streamer.addReader(".Level.Entities.#",
|
||||
(BiConsumer<Integer, CompoundTag>) (index, entityTag) -> {
|
||||
if (entities == null) {
|
||||
entities = new HashMap<>();
|
||||
}
|
||||
long least = entityTag.getLong("UUIDLeast");
|
||||
long most = entityTag.getLong("UUIDMost");
|
||||
entities.put(new UUID(most, least), entityTag);
|
||||
});
|
||||
(BiConsumer<Integer, CompoundTag>) (index, entityTag) -> {
|
||||
if (entities == null) {
|
||||
entities = new HashMap<>();
|
||||
}
|
||||
long least = entityTag.getLong("UUIDLeast");
|
||||
long most = entityTag.getLong("UUIDMost");
|
||||
entities.put(new UUID(most, least), entityTag);
|
||||
});
|
||||
streamer.addReader(".Level.Biomes",
|
||||
(BiConsumer<Integer, byte[]>) (index, value) -> biomes = value);
|
||||
(BiConsumer<Integer, byte[]>) (index, value) -> biomes = value);
|
||||
streamer.addReader(".Level.HeightMap",
|
||||
(BiConsumer<Integer, int[]>) (index, value) -> heightMap = value);
|
||||
(BiConsumer<Integer, int[]>) (index, value) -> heightMap = value);
|
||||
if (readPos) {
|
||||
streamer.addReader(".Level.xPos",
|
||||
(BiConsumer<Integer, Integer>) (index, value) -> MCAChunk.this.setLoc(getParent(), value, getZ()));
|
||||
(BiConsumer<Integer, Integer>) (index, value) -> MCAChunk.this.setLoc(getParent(), value, getZ()));
|
||||
streamer.addReader(".Level.zPos",
|
||||
(BiConsumer<Integer, Integer>) (index, value) -> MCAChunk.this.setLoc(getParent(), getX(), value));
|
||||
(BiConsumer<Integer, Integer>) (index, value) -> MCAChunk.this.setLoc(getParent(), getX(), value));
|
||||
}
|
||||
streamer.readFully();
|
||||
}
|
||||
@ -610,14 +599,14 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
public BiomeType[] getBiomeArray() {
|
||||
BiomeType[] arr = new BiomeType[256];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = BiomeTypes.register(biomes[i]);
|
||||
arr[i] = BiomeTypes.get(biomes[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return BiomeTypes.register(biomes[(x & 15) + ((z & 15) << 4)]);
|
||||
return BiomeTypes.get(biomes[(x & 15) + ((z & 15) << 4)]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -804,4 +793,4 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
public FaweChunk call() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
}
|
||||
}
|
@ -41,7 +41,8 @@ public class FaweTimer implements Runnable {
|
||||
if (tick < lastGetTPSTick + tickInterval) {
|
||||
return lastGetTPSValue;
|
||||
}
|
||||
double total = Arrays.stream(history).sum();
|
||||
double total = 0;
|
||||
for (double v : history) total += v;
|
||||
lastGetTPSValue = total / history.length;
|
||||
lastGetTPSTick = tick;
|
||||
return lastGetTPSValue;
|
||||
|
@ -408,7 +408,6 @@ public class PlatformManager {
|
||||
}
|
||||
|
||||
try {
|
||||
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
|
||||
switch (event.getInputType()) {
|
||||
case PRIMARY: {
|
||||
if (getConfiguration().navigationWandMaxDistance > 0 && player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().navigationWand)) {
|
||||
@ -426,7 +425,7 @@ public class PlatformManager {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Tool tool = session.getTool(player);
|
||||
if (tool instanceof DoubleActionTraceTool && tool.canUse(player)) {
|
||||
FawePlayer<?> fp = FawePlayer.wrap(player);
|
||||
fp.runAsyncIfFree(() -> reset((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session));
|
||||
@ -450,7 +449,7 @@ public class PlatformManager {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Tool tool = session.getTool(player);
|
||||
if (tool instanceof TraceTool && tool.canUse(player)) {
|
||||
FawePlayer<?> fp = FawePlayer.wrap(player);
|
||||
//todo this needs to be fixed so the event is canceled after actPrimary is used and returns true
|
||||
|
@ -62,7 +62,9 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reads schematic files that are compatible with MCEdit and other editors.
|
||||
* @deprecated Use SchematicStreamer
|
||||
*/
|
||||
@Deprecated
|
||||
public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
|
||||
@ -355,6 +357,10 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private String convertBlockEntityId(String id) {
|
||||
switch (id) {
|
||||
case "Chest":
|
||||
return "chest";
|
||||
case "Sign":
|
||||
return "sign";
|
||||
case "Cauldron":
|
||||
return "brewing_stand";
|
||||
case "Control":
|
||||
|
@ -125,49 +125,22 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
}
|
||||
|
||||
private Clipboard reader(UUID uuid) throws IOException {
|
||||
NamedTag rootTag = inputStream.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
throw new IOException("Tag 'Schematic' does not exist or is not first");
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
|
||||
int version = requireTag(schematic, "Version", IntTag.class).getValue();
|
||||
final Platform platform = WorldEdit.getInstance().getPlatformManager()
|
||||
.queryCapability(Capability.WORLD_EDITING);
|
||||
int liveDataVersion = platform.getDataVersion();
|
||||
|
||||
if (version == 1) {
|
||||
dataVersion = 1631; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1-
|
||||
fixer = platform.getDataFixer();
|
||||
return readVersion1(uuid);
|
||||
} else if (version == 2) {
|
||||
dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
||||
if (dataVersion > liveDataVersion) {
|
||||
log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.",
|
||||
dataVersion, liveDataVersion);
|
||||
} else if (dataVersion < liveDataVersion) {
|
||||
fixer = platform.getDataFixer();
|
||||
if (fixer != null) {
|
||||
log.info("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.",
|
||||
dataVersion, liveDataVersion);
|
||||
} else {
|
||||
log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.",
|
||||
dataVersion, liveDataVersion);
|
||||
}
|
||||
}
|
||||
|
||||
BlockArrayClipboard clip = readVersion1(uuid);
|
||||
return readVersion2(clip, schematicTag);
|
||||
}
|
||||
|
||||
throw new IOException("This schematic version is currently not supported");
|
||||
private String fix(String palettePart) {
|
||||
if (fixer == null || dataVersion == -1) return palettePart;
|
||||
return fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, palettePart, dataVersion);
|
||||
}
|
||||
|
||||
private BlockArrayClipboard readVersion1(UUID uuid) throws IOException {
|
||||
private CompoundTag fixBlockEntity(CompoundTag tag) {
|
||||
if (fixer == null || dataVersion == -1) return tag;
|
||||
return fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, tag, dataVersion);
|
||||
}
|
||||
|
||||
private CompoundTag fixEntity(CompoundTag tag) {
|
||||
if (fixer == null || dataVersion == -1) return tag;
|
||||
return fixer.fixUp(DataFixer.FixTypes.ENTITY, tag, dataVersion);
|
||||
}
|
||||
|
||||
private Clipboard reader(UUID uuid) throws IOException {
|
||||
width = height = length = offsetX = offsetY = offsetZ = Integer.MIN_VALUE;
|
||||
|
||||
final BlockArrayClipboard clipboard = new BlockArrayClipboard(new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(0, 0, 0)), fc);
|
||||
@ -176,6 +149,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
|
||||
|
||||
NBTStreamer streamer = new NBTStreamer(inputStream);
|
||||
streamer.addReader("Schematic.DataVersion", (BiConsumer<Integer, Short>) (i, v) -> dataVersion = v);
|
||||
streamer.addReader("Schematic.Width", (BiConsumer<Integer, Short>) (i, v) -> width = v);
|
||||
streamer.addReader("Schematic.Height", (BiConsumer<Integer, Short>) (i, v) -> height = v);
|
||||
streamer.addReader("Schematic.Length", (BiConsumer<Integer, Short>) (i, v) -> length = v);
|
||||
@ -188,7 +162,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
for (Map.Entry<String, Tag> entry : v.entrySet()) {
|
||||
BlockState state = null;
|
||||
try {
|
||||
state = BlockState.get(entry.getKey());
|
||||
String palettePart = fix(entry.getKey());
|
||||
state = BlockState.get(palettePart);
|
||||
} catch (InputParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -196,6 +171,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
palette[index] = (char) state.getOrdinal();
|
||||
}
|
||||
});
|
||||
|
||||
/// readBiomes
|
||||
|
||||
streamer.addReader("Schematic.BlockData.#", new NBTStreamer.LazyReader() {
|
||||
@Override
|
||||
public void accept(Integer arrayLen, DataInputStream dis) {
|
||||
@ -224,21 +202,40 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
int x = pos[0];
|
||||
int y = pos[1];
|
||||
int z = pos[2];
|
||||
Map<String, Tag> values = value.getValue();
|
||||
Tag id = values.get("Id");
|
||||
if (id != null) {
|
||||
values.put("x", new IntTag(x));
|
||||
values.put("y", new IntTag(y));
|
||||
values.put("z", new IntTag(z));
|
||||
values.put("id", id);
|
||||
}
|
||||
values.remove("Id");
|
||||
values.remove("Pos");
|
||||
value = fixBlockEntity(value);
|
||||
fc.setTile(x, y, z, value);
|
||||
});
|
||||
streamer.addReader("Schematic.Entities.#", (BiConsumer<Integer, CompoundTag>) (index, compound) -> {
|
||||
if (fc == null) {
|
||||
setupClipboard(0, uuid);
|
||||
}
|
||||
String id = compound.getString("id");
|
||||
if (id.isEmpty()) {
|
||||
return;
|
||||
Map<String, Tag> value = compound.getValue();
|
||||
StringTag id = (StringTag) value.get("Id");
|
||||
if (id == null) {
|
||||
id = (StringTag) value.get("id");
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
value.put("id", id);
|
||||
value.remove("Id");
|
||||
}
|
||||
|
||||
ListTag positionTag = compound.getListTag("Pos");
|
||||
ListTag directionTag = compound.getListTag("Rotation");
|
||||
EntityType type = EntityTypes.parse(id);
|
||||
EntityType type = EntityTypes.parse(id.getValue());
|
||||
if (type != null) {
|
||||
compound.getValue().put("Id", new StringTag(type.getId()));
|
||||
compound = fixEntity(compound);
|
||||
BaseEntity state = new BaseEntity(type, compound);
|
||||
fc.createEntity(clipboard, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state);
|
||||
} else {
|
||||
@ -274,7 +271,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
try (FaweInputStream fis = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(biomesOut.toByteArrays())))) {
|
||||
int volume = width * length;
|
||||
for (int index = 0; index < volume; index++) {
|
||||
fc.setBiome(index, BiomeTypes.register(fis.read()));
|
||||
fc.setBiome(index, BiomeTypes.get(fis.read()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,17 +280,6 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
private Clipboard readVersion2(BlockArrayClipboard version1, CompoundTag schematicTag) throws IOException {
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (schematic.containsKey("BiomeData")) {
|
||||
readBiomes(version1, schematic);
|
||||
}
|
||||
if (schematic.containsKey("Entities")) {
|
||||
readEntities(version1, schematic);
|
||||
}
|
||||
return version1;
|
||||
}
|
||||
|
||||
private void readBiomes(BlockArrayClipboard clipboard, Map<String, Tag> schematic) throws IOException {
|
||||
ByteArrayTag dataTag = requireTag(schematic, "BiomeData", ByteArrayTag.class);
|
||||
IntTag maxTag = requireTag(schematic, "BiomePaletteMax", IntTag.class);
|
||||
@ -309,7 +295,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
if (fixer != null) {
|
||||
key = fixer.fixUp(DataFixer.FixTypes.BIOME, key, dataVersion);
|
||||
}
|
||||
BiomeType biome = BiomeTypes.register(key);
|
||||
BiomeType biome = BiomeTypes.get(key);
|
||||
if (biome == null) {
|
||||
log.warn("Unknown biome type :" + key +
|
||||
" in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
||||
@ -352,37 +338,6 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
}
|
||||
|
||||
private void readEntities(BlockArrayClipboard clipboard, Map<String, Tag> schematic) throws IOException {
|
||||
List<Tag> entList = requireTag(schematic, "Entities", ListTag.class).getValue();
|
||||
if (entList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (Tag et : entList) {
|
||||
if (!(et instanceof CompoundTag)) {
|
||||
continue;
|
||||
}
|
||||
CompoundTag entityTag = (CompoundTag) et;
|
||||
Map<String, Tag> tags = entityTag.getValue();
|
||||
String id = requireTag(tags, "Id", StringTag.class).getValue();
|
||||
entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build();
|
||||
|
||||
if (fixer != null) {
|
||||
entityTag = fixer.fixUp(DataFixer.FixTypes.ENTITY, entityTag, dataVersion);
|
||||
}
|
||||
|
||||
EntityType entityType = EntityTypes.get(id);
|
||||
if (entityType != null) {
|
||||
Location location = NBTConversions.toLocation(clipboard,
|
||||
requireTag(tags, "Pos", ListTag.class),
|
||||
requireTag(tags, "Rotation", ListTag.class));
|
||||
BaseEntity state = new BaseEntity(entityType, entityTag);
|
||||
clipboard.createEntity(location, state);
|
||||
} else {
|
||||
log.warn("Unknown entity when pasting schematic: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
inputStream.close();
|
||||
|
@ -25,8 +25,10 @@ import com.boydti.fawe.util.IOUtil;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
@ -107,7 +109,8 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
|
||||
final DataOutput rawStream = outputStream.getOutputStream();
|
||||
outputStream.writeLazyCompoundTag("Schematic", out -> {
|
||||
out.writeNamedTag("Version", 1);
|
||||
out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion());
|
||||
out.writeNamedTag("Version", CURRENT_VERSION);
|
||||
out.writeNamedTag("Width", (short) width);
|
||||
out.writeNamedTag("Height", (short) height);
|
||||
out.writeNamedTag("Length", (short) length);
|
||||
@ -224,6 +227,11 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
out.writeNamedEmptyList("TileEntities");
|
||||
}
|
||||
|
||||
if (clipboard.hasBiomes()) {
|
||||
writeBiomes(clipboard, out);
|
||||
}
|
||||
|
||||
TODO optimize
|
||||
List<Tag> entities = new ArrayList<>();
|
||||
for (Entity entity : clipboard.getEntities()) {
|
||||
BaseEntity state = entity.getState();
|
||||
@ -238,7 +246,8 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
}
|
||||
|
||||
// Store our location data, overwriting any
|
||||
values.put("id", new StringTag(state.getType().getId()));
|
||||
values.remove("id");
|
||||
values.put("Id", new StringTag(state.getType().getId()));
|
||||
values.put("Pos", writeVector(entity.getLocation()));
|
||||
values.put("Rotation", writeRotation(entity.getLocation()));
|
||||
|
||||
@ -251,20 +260,11 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
} else {
|
||||
out.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities));
|
||||
}
|
||||
|
||||
// version 2 stuff
|
||||
if (clipboard.hasBiomes()) {
|
||||
writeBiomes(clipboard, out);
|
||||
}
|
||||
|
||||
if (!clipboard.getEntities().isEmpty()) {
|
||||
writeEntities(clipboard, out);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void writeBiomes(Clipboard clipboard, NBTOutputStream schematic) throws IOException {
|
||||
TODO optimize
|
||||
BlockVector3 min = clipboard.getMinimumPoint();
|
||||
int width = clipboard.getRegion().getWidth();
|
||||
int length = clipboard.getRegion().getLength();
|
||||
|
@ -94,11 +94,19 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
}
|
||||
|
||||
private static long[] adapt(Direction... dirs) {
|
||||
return Arrays.stream(dirs).mapToLong(dir -> 1L << dir.ordinal()).toArray();
|
||||
long[] arr = new long[dirs.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = 1L << dirs[i].ordinal();
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private static long[] adapt(Long... dirs) {
|
||||
return Arrays.stream(dirs).mapToLong(dir -> dir).toArray();
|
||||
long[] arr = new long[dirs.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = dirs[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private static long[] getDirections(AbstractProperty property) {
|
||||
@ -506,37 +514,4 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
||||
return super.setBlock(x, y, z, transformInverse(block));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new value with the transformed direction.
|
||||
*
|
||||
* @param allowedStates the allowed states
|
||||
* @param transform the transform
|
||||
* @param oldDirection the old direction to transform
|
||||
* @return a new state or null if none could be found
|
||||
*/
|
||||
@Nullable
|
||||
private static Vector3 getNewStateValue(List<Direction> allowedStates, Transform transform, Vector3 oldDirection) {
|
||||
Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize();
|
||||
Vector3 newValue = null;
|
||||
double closest = -2;
|
||||
boolean found = false;
|
||||
|
||||
for (Direction v : allowedStates) {
|
||||
double dot = v.toVector().normalize().dot(newDirection);
|
||||
if (dot >= closest) {
|
||||
closest = dot;
|
||||
newValue = v.toVector();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return newValue;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import java.util.List;
|
||||
*/
|
||||
public class CombinedRegionFunction implements RegionFunction {
|
||||
|
||||
private final List<RegionFunction> functions = new ArrayList<>();
|
||||
private RegionFunction[] functions;
|
||||
|
||||
/**
|
||||
* Create a combined region function.
|
||||
@ -49,7 +49,7 @@ public class CombinedRegionFunction implements RegionFunction {
|
||||
*/
|
||||
public CombinedRegionFunction(Collection<RegionFunction> functions) {
|
||||
checkNotNull(functions);
|
||||
this.functions.addAll(functions);
|
||||
this.functions = functions.toArray(new RegionFunction[functions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +58,7 @@ public class CombinedRegionFunction implements RegionFunction {
|
||||
* @param function an array of functions to match
|
||||
*/
|
||||
public CombinedRegionFunction(RegionFunction... function) {
|
||||
this(Arrays.asList(checkNotNull(function)));
|
||||
this.functions = function;
|
||||
}
|
||||
|
||||
public static CombinedRegionFunction combine(RegionFunction function, RegionFunction add) {
|
||||
@ -82,7 +82,9 @@ public class CombinedRegionFunction implements RegionFunction {
|
||||
*/
|
||||
public void add(Collection<RegionFunction> functions) {
|
||||
checkNotNull(functions);
|
||||
this.functions.addAll(functions);
|
||||
ArrayList<RegionFunction> functionsList = new ArrayList<>(Arrays.asList(this.functions));
|
||||
functionsList.addAll(functions);
|
||||
this.functions = functionsList.toArray(new RegionFunction[functionsList.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,11 +100,9 @@ public class CombinedRegionFunction implements RegionFunction {
|
||||
public boolean apply(BlockVector3 position) throws WorldEditException {
|
||||
boolean ret = false;
|
||||
for (RegionFunction function : functions) {
|
||||
if (function.apply(position)) {
|
||||
ret = true;
|
||||
}
|
||||
ret |= (function.apply(position));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -80,14 +80,7 @@ public class Naturalizer implements LayerFunction {
|
||||
}
|
||||
|
||||
private boolean naturalize(BlockVector3 position, int depth) throws WorldEditException {
|
||||
BlockState block = editSession.getBlock(position);
|
||||
BlockState targetBlock = getTargetBlock(depth);
|
||||
|
||||
if (block.equalsFuzzy(targetBlock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return editSession.setBlock(position, targetBlock);
|
||||
return editSession.setBlock(position, getTargetBlock(depth));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,7 +110,7 @@ public class BlockTypeMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return types[getExtent().getBlock(vector).getInternalId()];
|
||||
return types[getExtent().getBlock(vector).getBlockType().getInternalId()];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -15,7 +15,7 @@ public class SingleBlockTypeMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return getExtent().getBlock(vector).getInternalId() == internalId;
|
||||
return getExtent().getBlock(vector).getBlockType().getInternalId() == internalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,12 +3,15 @@ package com.sk89q.worldedit.function.operation;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
public class BackwardsExtentBlockCopy implements Operation {
|
||||
private final Region region;
|
||||
@ -16,7 +19,8 @@ public class BackwardsExtentBlockCopy implements Operation {
|
||||
private final RegionFunction function;
|
||||
private final BlockVector3 origin;
|
||||
|
||||
// private Vector mutable = new MutableBlockVector3();
|
||||
private MutableBlockVector3 mutBV3 = new MutableBlockVector3();
|
||||
private MutableVector3 mutV3 = new MutableVector3();
|
||||
|
||||
BackwardsExtentBlockCopy(Region region, BlockVector3 origin, Transform transform, RegionFunction function) {
|
||||
this.region = region;
|
||||
@ -56,7 +60,14 @@ public class BackwardsExtentBlockCopy implements Operation {
|
||||
}
|
||||
|
||||
private BlockVector3 transform(Transform transform, BlockVector3 pt) {
|
||||
return transform.apply(Vector3.at(pt.getBlockX() - origin.getBlockX(), pt.getBlockY() - origin.getBlockY(), pt.getBlockZ() - origin.getBlockZ())).toBlockPoint().add(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ());
|
||||
mutV3.mutX(((pt.getBlockX() - origin.getBlockX())));
|
||||
mutV3.mutY(((pt.getBlockY() - origin.getBlockY())));
|
||||
mutV3.mutZ(((pt.getBlockZ() - origin.getBlockZ())));
|
||||
Vector3 tmp = transform.apply(mutV3);
|
||||
mutBV3.mutX((tmp.getBlockX() + origin.getBlockX()));
|
||||
mutBV3.mutY((tmp.getBlockY() + origin.getBlockY()));
|
||||
mutBV3.mutZ((tmp.getBlockZ() + origin.getBlockZ()));
|
||||
return mutBV3;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,7 +75,7 @@ public class ForwardExtentCopy implements Operation {
|
||||
private int repetitions = 1;
|
||||
private Mask sourceMask = Masks.alwaysTrue();
|
||||
private boolean removingEntities;
|
||||
private boolean copyingEntities = true; // default to true for backwards compatibility, sort of
|
||||
private boolean copyingEntities = true; // default to true for backwards compatibility, sort of // No, it's not for compatibility, it makes sense for entities to be copied and people will get annoyed if it doesn't
|
||||
private boolean copyingBiomes;
|
||||
private RegionFunction sourceFunction = null;
|
||||
private Transform transform = new Identity();
|
||||
|
@ -27,6 +27,8 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
*/
|
||||
public final class Operations {
|
||||
|
||||
private static final RunContext context = new RunContext();
|
||||
|
||||
private Operations() {
|
||||
}
|
||||
|
||||
@ -38,7 +40,7 @@ public final class Operations {
|
||||
*/
|
||||
public static void complete(Operation op) throws WorldEditException {
|
||||
while (op != null) {
|
||||
op = op.resume(new RunContext());
|
||||
op = op.resume(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +54,7 @@ public final class Operations {
|
||||
public static void completeLegacy(Operation op) throws MaxChangedBlocksException {
|
||||
while (op != null) {
|
||||
try {
|
||||
op = op.resume(new RunContext());
|
||||
op = op.resume(context);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
throw e;
|
||||
} catch (WorldEditException e) {
|
||||
@ -71,7 +73,7 @@ public final class Operations {
|
||||
public static void completeBlindly(Operation op) {
|
||||
while (op != null) {
|
||||
try {
|
||||
op = op.resume(new RunContext());
|
||||
op = op.resume(context);
|
||||
} catch (WorldEditException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Link;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -28,6 +30,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
/**
|
||||
* Returns a {@link BlockStateHolder} for a given position.
|
||||
*/
|
||||
@Link(clazz = UtilityCommands.class, value = "patterns")
|
||||
public interface Pattern {
|
||||
|
||||
/**
|
||||
|
@ -20,28 +20,60 @@
|
||||
package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Removes the waterlogged state from blocks if possible. If not possible, returns air.
|
||||
*/
|
||||
public class WaterloggedRemover extends AbstractExtentPattern {
|
||||
|
||||
private static SoftReference<BlockState[]> cache = new SoftReference<>(null);
|
||||
|
||||
private synchronized BlockState[] getRemap() {
|
||||
BlockState[] remap = this.cache.get();
|
||||
if (remap != null) return remap;
|
||||
this.cache = new SoftReference<>(remap = new BlockState[BlockTypes.states.length]);
|
||||
|
||||
// init
|
||||
for (int i = 0; i < remap.length; i++) {
|
||||
BlockState state = remap[i];
|
||||
BlockType type = state.getBlockType();
|
||||
if (!type.hasProperty(PropertyKey.WATERLOGGED)) {
|
||||
continue;
|
||||
}
|
||||
if (state.getState(PropertyKey.WATERLOGGED) == Boolean.TRUE) {
|
||||
remap[i] = state.with(PropertyKey.WATERLOGGED, false);
|
||||
}
|
||||
}
|
||||
return remap;
|
||||
}
|
||||
|
||||
private final BlockState[] remap;
|
||||
|
||||
public WaterloggedRemover(Extent extent) {
|
||||
super(extent);
|
||||
this.remap = getRemap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(BlockVector3 position) {
|
||||
BaseBlock block = getExtent().getFullBlock(position);
|
||||
@SuppressWarnings("unchecked")
|
||||
Property<Object> prop = (Property<Object>) block.getBlockType().getPropertyMap().getOrDefault("waterlogged", null);
|
||||
if (prop != null) {
|
||||
return block.with(prop, false);
|
||||
BlockState newState = remap[block.getOrdinal()];
|
||||
if (newState != null) {
|
||||
return newState.toBaseBlock(block.getNbtData());
|
||||
}
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
}
|
||||
}
|
||||
}
|
@ -39,7 +39,9 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class to apply region functions to {@link com.sk89q.worldedit.regions.Region}.
|
||||
* @deprecated let the queue iterate, not the region function which lacks any kind of optimizations / parallelism
|
||||
*/
|
||||
@Deprecated
|
||||
public class RegionVisitor implements Operation {
|
||||
|
||||
public final Region region;
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.math;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
|
||||
import java.util.Comparator;
|
||||
@ -47,26 +48,18 @@ public class BlockVector2 {
|
||||
* cdef
|
||||
* </pre>
|
||||
*/
|
||||
public static final Comparator<BlockVector2> COMPARING_GRID_ARRANGEMENT =
|
||||
Comparator.comparingInt(BlockVector2::getZ).thenComparingInt(BlockVector2::getX);
|
||||
public static final Comparator<BlockVector2> COMPARING_GRID_ARRANGEMENT = (a, b) -> {
|
||||
return ComparisonChain.start()
|
||||
.compare(a.getBlockZ(), b.getBlockZ())
|
||||
.compare(a.getBlockX(), b.getBlockX())
|
||||
.result();
|
||||
};
|
||||
|
||||
public static BlockVector2 at(double x, double z) {
|
||||
return at((int) Math.floor(x), (int) Math.floor(z));
|
||||
}
|
||||
|
||||
public static BlockVector2 at(int x, int z) {
|
||||
switch (x) {
|
||||
case 0:
|
||||
if (z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new BlockVector2(x, z);
|
||||
}
|
||||
|
||||
@ -349,27 +342,6 @@ public class BlockVector2 {
|
||||
return divide(n, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift all components right.
|
||||
*
|
||||
* @param x the value to shift x by
|
||||
* @param z the value to shift z by
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector2 shr(int x, int z) {
|
||||
return at(this.x >> x, this.z >> z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift all components right by {@code n}.
|
||||
*
|
||||
* @param n the value to shift by
|
||||
* @return a new vector
|
||||
*/
|
||||
public BlockVector2 shr(int n) {
|
||||
return shr(n, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the vector.
|
||||
*
|
||||
@ -519,8 +491,8 @@ public class BlockVector2 {
|
||||
*/
|
||||
public BlockVector2 getMinimum(BlockVector2 v2) {
|
||||
return new BlockVector2(
|
||||
Math.min(x, v2.x),
|
||||
Math.min(z, v2.z)
|
||||
Math.min(x, v2.x),
|
||||
Math.min(z, v2.z)
|
||||
);
|
||||
}
|
||||
|
||||
@ -532,8 +504,8 @@ public class BlockVector2 {
|
||||
*/
|
||||
public BlockVector2 getMaximum(BlockVector2 v2) {
|
||||
return new BlockVector2(
|
||||
Math.max(x, v2.x),
|
||||
Math.max(z, v2.z)
|
||||
Math.max(x, v2.x),
|
||||
Math.max(z, v2.z)
|
||||
);
|
||||
}
|
||||
|
||||
@ -599,4 +571,5 @@ public class BlockVector2 {
|
||||
public String toString() {
|
||||
return "(" + x + ", " + z + ")";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -44,20 +44,6 @@ public class BlockVector3 {
|
||||
}
|
||||
|
||||
public static BlockVector3 at(int x, int y, int z) {
|
||||
// switch for efficiency on typical cases
|
||||
// in MC y is rarely 0/1 on selections
|
||||
switch (y) {
|
||||
case 0:
|
||||
if (x == 0 && z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (x == 1 && z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new BlockVector3(x, y, z);
|
||||
}
|
||||
|
||||
|
@ -33,19 +33,6 @@ public class Vector2 {
|
||||
public static final Vector2 ONE = new Vector2(1, 1);
|
||||
|
||||
public static Vector2 at(double x, double z) {
|
||||
int xTrunc = (int) x;
|
||||
switch (xTrunc) {
|
||||
case 0:
|
||||
if (x == 0 && z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (x == 1 && z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new Vector2(x, z);
|
||||
}
|
||||
|
||||
|
@ -39,21 +39,6 @@ public class Vector3 {
|
||||
public static final Vector3 ONE = new Vector3(1, 1, 1);
|
||||
|
||||
public static Vector3 at(double x, double y, double z) {
|
||||
// switch for efficiency on typical cases
|
||||
// in MC y is rarely 0/1 on selections
|
||||
int yTrunc = (int) y;
|
||||
switch (yTrunc) {
|
||||
case 0:
|
||||
if (x == 0 && y == 0 && z == 0) {
|
||||
return ZERO;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (x == 1 && y == 1 && z == 1) {
|
||||
return ONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new Vector3(x, y, z);
|
||||
}
|
||||
|
||||
@ -651,9 +636,9 @@ public class Vector3 {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String x = "" + getX();
|
||||
String y = "" + getY();
|
||||
String z = "" + getZ();
|
||||
String x = (getX() == getBlockX() ? "" + getBlockX() : "" + getX());
|
||||
String y = (getY() == getBlockY() ? "" + getBlockY() : "" + getY());
|
||||
String z = (getZ() == getBlockZ() ? "" + getBlockZ() : "" + getZ());
|
||||
return "(" + x + ", " + y + ", " + z + ")";
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class BiomeType implements RegistryItem, Keyed {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
return this.internalId; // stop changing this
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -280,11 +280,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int ret = toImmutableState().hashCode() << 3;
|
||||
if (hasNbtData()) {
|
||||
ret += getNbtData().hashCode();
|
||||
}
|
||||
return ret;
|
||||
return blockState.hashCode(); // stop changing this
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -280,17 +280,16 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
|
||||
|
||||
@Override
|
||||
public boolean equalsFuzzy(BlockStateHolder<?> o) {
|
||||
if (null == o) {
|
||||
return false;
|
||||
}
|
||||
if (this == o) {
|
||||
// Added a reference equality check for speediness
|
||||
return true;
|
||||
}
|
||||
|
||||
if (o.getClass() == BlockState.class) {
|
||||
return o.getOrdinal() == this.getOrdinal();
|
||||
}
|
||||
if (null == o) {
|
||||
return false;
|
||||
}
|
||||
return o.equalsFuzzy(this);
|
||||
}
|
||||
|
||||
|
@ -99,6 +99,18 @@ public class BlockType implements FawePattern, Keyed {
|
||||
}
|
||||
}
|
||||
|
||||
public BlockState withProperties(String properties) { //
|
||||
int id = getInternalId();
|
||||
for (String keyPair : properties.split(",")) {
|
||||
String[] split = keyPair.split("=");
|
||||
String name = split[0];
|
||||
String value = split[1];
|
||||
AbstractProperty btp = settings.propertiesMap.get(name);
|
||||
id = btp.modify(id, btp.getValueFor(value));
|
||||
}
|
||||
return withStateId(id);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public BlockState withPropertyId(int propertyId) {
|
||||
if (settings.stateOrdinals == null) return settings.defaultState;
|
||||
@ -140,11 +152,7 @@ public class BlockType implements FawePattern, Keyed {
|
||||
* @return The property
|
||||
*/
|
||||
public <V> Property<V> getProperty(String name) {
|
||||
// Assume it works, CCE later at runtime if not.
|
||||
@SuppressWarnings("unchecked")
|
||||
Property<V> property = (Property<V>) getPropertyMap().get(name);
|
||||
checkArgument(property != null, "%s has no property named %s", this, name);
|
||||
return property;
|
||||
return (Property<V>) this.settings.propertiesMap.get(name); // stop changing this (performance)
|
||||
}
|
||||
|
||||
public boolean hasProperty(PropertyKey key) {
|
||||
@ -269,12 +277,12 @@ public class BlockType implements FawePattern, Keyed {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
return settings.internalId; // stop changing this to WEs bad hashcode
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BlockType && this.id.equals(((BlockType) obj).id);
|
||||
return obj == this; // stop changing this to a shitty string comparison
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.world.entity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
public class EntityTypes {
|
||||
|
||||
@ -133,71 +134,113 @@ public class EntityTypes {
|
||||
return EntityType.REGISTRY.get(id);
|
||||
}
|
||||
|
||||
public static EntityType parse(String id) {
|
||||
private static String convertEntityId(String id) {
|
||||
if (id.startsWith("minecraft:")) id = id.substring(10);
|
||||
switch (id) {
|
||||
case "FallingSand": return EntityTypes.FALLING_BLOCK;
|
||||
case "FireworksRocketEntity": return EntityTypes.FIREWORK_ROCKET;
|
||||
case "LavaSlime": return EntityTypes.MAGMA_CUBE;
|
||||
case "MinecartChest": return EntityTypes.CHEST_MINECART;
|
||||
case "MinecartCommandBlock": return EntityTypes.COMMAND_BLOCK_MINECART;
|
||||
case "MinecartFurnace": return EntityTypes.FURNACE_MINECART;
|
||||
case "MinecartHopper": return EntityTypes.HOPPER_MINECART;
|
||||
case "MinecartRideable": return EntityTypes.MINECART;
|
||||
case "MinecartSpawner": return EntityTypes.SPAWNER_MINECART;
|
||||
case "MinecartTNT": return EntityTypes.TNT_MINECART;
|
||||
case "MushroomCow": return EntityTypes.MOOSHROOM;
|
||||
case "PigZombie": return EntityTypes.ZOMBIE_PIGMAN;
|
||||
case "PrimedTnt": return EntityTypes.TNT;
|
||||
case "SnowMan": return EntityTypes.SNOW_GOLEM;
|
||||
case "ThrownEgg": return EntityTypes.EGG;
|
||||
case "ThrownEnderpearl": return EntityTypes.ENDER_PEARL;
|
||||
case "ThrownExpBottle": return EntityTypes.EXPERIENCE_BOTTLE;
|
||||
case "ThrownPotion": return EntityTypes.POTION;
|
||||
case "WitherBoss": return EntityTypes.WITHER;
|
||||
case "XPOrb": return EntityTypes.EXPERIENCE_ORB;
|
||||
default:
|
||||
switch(id) {
|
||||
case "AreaEffectCloud": return "area_effect_cloud";
|
||||
case "ArmorStand": return "armor_stand";
|
||||
case "CaveSpider": return "cave_spider";
|
||||
case "MinecartChest": return "chest_minecart";
|
||||
case "DragonFireball": return "dragon_fireball";
|
||||
case "ThrownEgg": return "egg";
|
||||
case "EnderDragon": return "ender_dragon";
|
||||
case "ThrownEnderpearl": return "ender_pearl";
|
||||
case "FallingSand": return "falling_block";
|
||||
case "FireworksRocketEntity": return "fireworks_rocket";
|
||||
case "MinecartFurnace": return "furnace_minecart";
|
||||
case "MinecartHopper": return "hopper_minecart";
|
||||
case "EntityHorse": return "horse";
|
||||
case "ItemFrame": return "item_frame";
|
||||
case "LeashKnot": return "leash_knot";
|
||||
case "LightningBolt": return "lightning_bolt";
|
||||
case "LavaSlime": return "magma_cube";
|
||||
case "MinecartRideable": return "minecart";
|
||||
case "MushroomCow": return "mooshroom";
|
||||
case "Ozelot": return "ocelot";
|
||||
case "PolarBear": return "polar_bear";
|
||||
case "ThrownPotion": return "potion";
|
||||
case "ShulkerBullet": return "shulker_bullet";
|
||||
case "SmallFireball": return "small_fireball";
|
||||
case "MinecartSpawner": return "spawner_minecart";
|
||||
case "SpectralArrow": return "spectral_arrow";
|
||||
case "PrimedTnt": return "tnt";
|
||||
case "MinecartTNT": return "tnt_minecart";
|
||||
case "VillagerGolem": return "villager_golem";
|
||||
case "WitherBoss": return "wither";
|
||||
case "WitherSkull": return "wither_skull";
|
||||
case "PigZombie": return "zombie_pigman";
|
||||
case "XPOrb": return "experience_orb";
|
||||
case "ThrownExpBottle": return "experience_bottle";
|
||||
case "EyeOfEnderSignal": return "eye_of_ender";
|
||||
case "EnderCrystal": return "end_crystal";
|
||||
case "MinecartCommandBlock": return "command_block_minecart";
|
||||
case "SnowMan": return "snow_golem";
|
||||
case "areaeffectcloud": return "area_effect_cloud";
|
||||
case "armorstand": return "armor_stand";
|
||||
case "cavespider": return "cave_spider";
|
||||
case "minecartchest": return "chest_minecart";
|
||||
case "dragonfireball": return "dragon_fireball";
|
||||
case "thrownegg": return "egg";
|
||||
case "enderdragon": return "ender_dragon";
|
||||
case "thrownenderpearl": return "ender_pearl";
|
||||
case "fallingsand": return "falling_block";
|
||||
case "fireworksrocketentity": return "fireworks_rocket";
|
||||
case "minecartfurnace": return "furnace_minecart";
|
||||
case "minecarthopper": return "hopper_minecart";
|
||||
case "entityhorse": return "horse";
|
||||
case "itemframe": return "item_frame";
|
||||
case "leashknot": return "leash_knot";
|
||||
case "lightningbolt": return "lightning_bolt";
|
||||
case "lavaslime": return "magma_cube";
|
||||
case "minecartrideable": return "minecart";
|
||||
case "mushroomcow": return "mooshroom";
|
||||
case "ozelot": return "ocelot";
|
||||
case "polarbear": return "polar_bear";
|
||||
case "thrownpotion": return "potion";
|
||||
case "shulkerbullet": return "shulker_bullet";
|
||||
case "smallfireball": return "small_fireball";
|
||||
case "minecartspawner": return "spawner_minecart";
|
||||
case "spectralarrow": return "spectral_arrow";
|
||||
case "primedtnt": return "tnt";
|
||||
case "minecarttnt": return "tnt_minecart";
|
||||
case "villagergolem": return "villager_golem";
|
||||
case "witherboss": return "wither";
|
||||
case "witherskull": return "wither_skull";
|
||||
case "pigzombie": return "zombie_pigman";
|
||||
case "xporb":
|
||||
case "xp_orb":
|
||||
return "experience_orb";
|
||||
case "thrownexpbottle":
|
||||
case "xp_bottle":
|
||||
return "experience_bottle";
|
||||
case "eyeofendersignal":
|
||||
case "eye_of_ender_signal":
|
||||
return "eye_of_ender";
|
||||
case "endercrystal":
|
||||
case "ender_crystal":
|
||||
return "end_crystal";
|
||||
case "fireworks_rocket": return "firework_rocket";
|
||||
case "minecartcommandblock":
|
||||
case "commandblock_minecart":
|
||||
return "command_block_minecart";
|
||||
case "snowman":
|
||||
return "snow_golem";
|
||||
case "villager_golem": return "iron_golem";
|
||||
case "evocation_fangs": return "evoker_fangs";
|
||||
case "evocation_illager": return "evoker";
|
||||
case "vindication_illager": return "vindicator";
|
||||
case "illusion_illager": return "illusioner";
|
||||
default: {
|
||||
if (Character.isUpperCase(id.charAt(0))) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < id.length(); i++) {
|
||||
char c = id.charAt(i);
|
||||
if (Character.isUpperCase(c)) {
|
||||
c = Character.toLowerCase(c);
|
||||
if (i != 0) result.append('_');
|
||||
}
|
||||
result.append(c);
|
||||
}
|
||||
return parse(result.toString());
|
||||
}
|
||||
switch (id.toLowerCase()) {
|
||||
case "xp_orb":
|
||||
return EntityTypes.EXPERIENCE_ORB;
|
||||
case "xp_bottle":
|
||||
return EntityTypes.EXPERIENCE_BOTTLE;
|
||||
case "eye_of_ender_signal":
|
||||
return EntityTypes.EYE_OF_ENDER;
|
||||
case "ender_crystal":
|
||||
return EntityTypes.END_CRYSTAL;
|
||||
case "fireworks_rocket":
|
||||
return EntityTypes.FIREWORK_ROCKET;
|
||||
case "commandblock_minecart":
|
||||
return EntityTypes.COMMAND_BLOCK_MINECART;
|
||||
case "snowman":
|
||||
return EntityTypes.SNOW_GOLEM;
|
||||
case "villager_golem":
|
||||
return EntityTypes.IRON_GOLEM;
|
||||
case "evocation_fangs":
|
||||
return EntityTypes.EVOKER_FANGS;
|
||||
case "evocation_illager":
|
||||
return EntityTypes.EVOKER;
|
||||
case "vindication_illager":
|
||||
return EntityTypes.VINDICATOR;
|
||||
case "illusion_illager":
|
||||
return EntityTypes.ILLUSIONER;
|
||||
default:
|
||||
return get(id);
|
||||
return convertEntityId(id.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType parse(String id) {
|
||||
return get(convertEntityId(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren