Various
Optimize for 1.12 Refactor commands / style / cleanup Brush saving/loading Tweak / improve ChunkListener
This commit is contained in:
parent
de26c22f05
commit
b9c056c879
@ -5,6 +5,7 @@ dependencies {
|
|||||||
compile project(':core')
|
compile project(':core')
|
||||||
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
|
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
|
||||||
compile 'org.bukkit.craftbukkitv1_11:Craftbukkit:1.11'
|
compile 'org.bukkit.craftbukkitv1_11:Craftbukkit:1.11'
|
||||||
|
compile 'org.bukkit.craftbukkitv1_12_P2:Craftbukkit:1.12'
|
||||||
compile 'net.milkbowl.vault:VaultAPI:1.5'
|
compile 'net.milkbowl.vault:VaultAPI:1.5'
|
||||||
compile 'com.massivecraft:factions:2.8.0'
|
compile 'com.massivecraft:factions:2.8.0'
|
||||||
compile 'com.drtshock:factions:1.6.9.5'
|
compile 'com.drtshock:factions:1.6.9.5'
|
||||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
|||||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
||||||
import com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10;
|
import com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10;
|
||||||
import com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11;
|
import com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11;
|
||||||
|
import com.boydti.fawe.bukkit.v1_12.BukkitQueue_1_12;
|
||||||
import com.boydti.fawe.bukkit.v1_7.BukkitQueue17;
|
import com.boydti.fawe.bukkit.v1_7.BukkitQueue17;
|
||||||
import com.boydti.fawe.bukkit.v1_8.BukkitQueue18R3;
|
import com.boydti.fawe.bukkit.v1_8.BukkitQueue18R3;
|
||||||
import com.boydti.fawe.bukkit.v1_9.BukkitQueue_1_9_R1;
|
import com.boydti.fawe.bukkit.v1_9.BukkitQueue_1_9_R1;
|
||||||
@ -76,6 +77,7 @@ public class BukkitMain extends JavaPlugin {
|
|||||||
v1_9_R2,
|
v1_9_R2,
|
||||||
v1_10_R1,
|
v1_10_R1,
|
||||||
v1_11_R1,
|
v1_11_R1,
|
||||||
|
v1_12_R1,
|
||||||
NONE,
|
NONE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +93,8 @@ public class BukkitMain extends JavaPlugin {
|
|||||||
return new BukkitQueue_1_10(world);
|
return new BukkitQueue_1_10(world);
|
||||||
case v1_11_R1:
|
case v1_11_R1:
|
||||||
return new BukkitQueue_1_11(world);
|
return new BukkitQueue_1_11(world);
|
||||||
|
case v1_12_R1:
|
||||||
|
return new BukkitQueue_1_12(world);
|
||||||
default:
|
default:
|
||||||
case NONE:
|
case NONE:
|
||||||
return new BukkitQueue_All(world);
|
return new BukkitQueue_All(world);
|
||||||
@ -109,6 +113,8 @@ public class BukkitMain extends JavaPlugin {
|
|||||||
return new BukkitQueue_1_10(world);
|
return new BukkitQueue_1_10(world);
|
||||||
case v1_11_R1:
|
case v1_11_R1:
|
||||||
return new BukkitQueue_1_11(world);
|
return new BukkitQueue_1_11(world);
|
||||||
|
case v1_12_R1:
|
||||||
|
return new BukkitQueue_1_12(world);
|
||||||
default:
|
default:
|
||||||
case NONE:
|
case NONE:
|
||||||
return new BukkitQueue_All(world);
|
return new BukkitQueue_All(world);
|
||||||
|
@ -5,12 +5,11 @@ import com.boydti.fawe.bukkit.FaweBukkit;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
@ -23,7 +22,8 @@ import org.bukkit.event.entity.ItemSpawnEvent;
|
|||||||
|
|
||||||
public class ChunkListener implements Listener {
|
public class ChunkListener implements Listener {
|
||||||
|
|
||||||
int rateLimit = 0;
|
private int rateLimit = 0;
|
||||||
|
private int[] badLimit = new int[]{Settings.IMP.TICK_LIMITER.PHYSICS, Settings.IMP.TICK_LIMITER.FALLING, Settings.IMP.TICK_LIMITER.ITEMS};
|
||||||
|
|
||||||
public ChunkListener() {
|
public ChunkListener() {
|
||||||
if (Settings.IMP.TICK_LIMITER.ENABLED) {
|
if (Settings.IMP.TICK_LIMITER.ENABLED) {
|
||||||
@ -34,10 +34,14 @@ public class ChunkListener implements Listener {
|
|||||||
rateLimit--;
|
rateLimit--;
|
||||||
physicsFreeze = false;
|
physicsFreeze = false;
|
||||||
itemFreeze = false;
|
itemFreeze = false;
|
||||||
counter.clear();
|
|
||||||
lastZ = Integer.MIN_VALUE;
|
lastZ = Integer.MIN_VALUE;
|
||||||
for (Long badChunk : badChunks) {
|
|
||||||
counter.put(badChunk, new int[]{Settings.IMP.TICK_LIMITER.PHYSICS, Settings.IMP.TICK_LIMITER.ITEMS, Settings.IMP.TICK_LIMITER.FALLING});
|
counter.clear();
|
||||||
|
for (Long2ObjectMap.Entry<Boolean> entry : badChunks.long2ObjectEntrySet()) {
|
||||||
|
long key = entry.getLongKey();
|
||||||
|
int x = MathMan.unpairIntX(key);
|
||||||
|
int z = MathMan.unpairIntY(key);
|
||||||
|
counter.put(key, badLimit);
|
||||||
}
|
}
|
||||||
badChunks.clear();
|
badChunks.clear();
|
||||||
}
|
}
|
||||||
@ -48,7 +52,7 @@ public class ChunkListener implements Listener {
|
|||||||
public static boolean physicsFreeze = false;
|
public static boolean physicsFreeze = false;
|
||||||
public static boolean itemFreeze = false;
|
public static boolean itemFreeze = false;
|
||||||
|
|
||||||
private HashSet<Long> badChunks = new HashSet<>();
|
private Long2ObjectOpenHashMap<Boolean> badChunks = new Long2ObjectOpenHashMap<>();
|
||||||
private Long2ObjectOpenHashMap<int[]> counter = new Long2ObjectOpenHashMap<>();
|
private Long2ObjectOpenHashMap<int[]> counter = new Long2ObjectOpenHashMap<>();
|
||||||
private int lastX = Integer.MIN_VALUE, lastZ = Integer.MIN_VALUE;
|
private int lastX = Integer.MIN_VALUE, lastZ = Integer.MIN_VALUE;
|
||||||
private int[] lastCount;
|
private int[] lastCount;
|
||||||
@ -100,11 +104,12 @@ public class ChunkListener implements Listener {
|
|||||||
if (y != lastPhysY) {
|
if (y != lastPhysY) {
|
||||||
lastPhysY = y;
|
lastPhysY = y;
|
||||||
if (++count[0] == Settings.IMP.TICK_LIMITER.PHYSICS) {
|
if (++count[0] == Settings.IMP.TICK_LIMITER.PHYSICS) {
|
||||||
badChunks.add(MathMan.pairInt(cx, cz));
|
cancelNearby(cx, cz);
|
||||||
if (rateLimit <= 0) {
|
if (rateLimit <= 0) {
|
||||||
rateLimit = 120;
|
rateLimit = 20;
|
||||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled physics lag source at " + block.getLocation());
|
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled physics lag source at " + block.getLocation());
|
||||||
}
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -112,24 +117,41 @@ public class ChunkListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cancelNearby(int cx, int cz) {
|
||||||
|
cancel(cx, cz);
|
||||||
|
cancel(cx + 1, cz);
|
||||||
|
cancel(cx - 1, cz);
|
||||||
|
cancel(cx, cz + 1);
|
||||||
|
cancel(cx, cz - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancel(int cx, int cz) {
|
||||||
|
long key = MathMan.pairInt(cx, cz);
|
||||||
|
badChunks.put(key, (Boolean) true);
|
||||||
|
counter.put(key, badLimit);
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onBlockChange(EntityChangeBlockEvent event) {
|
public void onBlockChange(EntityChangeBlockEvent event) {
|
||||||
if (physicsFreeze) {
|
if (physicsFreeze) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Material to = event.getTo();
|
Block block = event.getBlock();
|
||||||
if (to == Material.AIR) {
|
int x = block.getX();
|
||||||
Block block = event.getBlock();
|
int z = block.getZ();
|
||||||
int x = block.getX();
|
int cx = x >> 4;
|
||||||
int z = block.getZ();
|
int cz = z >> 4;
|
||||||
int cx = x >> 4;
|
int[] count = getCount(cx, cz);
|
||||||
int cz = z >> 4;
|
if (count[1] >= Settings.IMP.TICK_LIMITER.FALLING) {
|
||||||
int[] count = getCount(cx, cz);
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
|
||||||
if (++count[1] >= Settings.IMP.TICK_LIMITER.FALLING) {
|
if (++count[1] >= Settings.IMP.TICK_LIMITER.FALLING) {
|
||||||
if (count[1] == Settings.IMP.TICK_LIMITER.FALLING) {
|
cancelNearby(cx, cz);
|
||||||
count[0] = Settings.IMP.TICK_LIMITER.PHYSICS;
|
if (rateLimit <= 0) {
|
||||||
badChunks.add(MathMan.pairInt(cx, cz));
|
rateLimit = 20;
|
||||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled falling block lag source at " + block.getLocation());
|
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled falling block lag source at " + block.getLocation());
|
||||||
}
|
}
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
@ -148,15 +170,16 @@ public class ChunkListener implements Listener {
|
|||||||
int cx = loc.getBlockX() >> 4;
|
int cx = loc.getBlockX() >> 4;
|
||||||
int cz = loc.getBlockZ() >> 4;
|
int cz = loc.getBlockZ() >> 4;
|
||||||
int[] count = getCount(cx, cz);
|
int[] count = getCount(cx, cz);
|
||||||
|
if (count[2] >= Settings.IMP.TICK_LIMITER.ITEMS) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (++count[2] >= Settings.IMP.TICK_LIMITER.ITEMS) {
|
if (++count[2] >= Settings.IMP.TICK_LIMITER.ITEMS) {
|
||||||
if (count[2] == Settings.IMP.TICK_LIMITER.ITEMS) {
|
cleanup(loc.getChunk());
|
||||||
count[0] = Settings.IMP.TICK_LIMITER.PHYSICS;
|
cancelNearby(cx, cz);
|
||||||
cleanup(loc.getChunk());
|
if (rateLimit <= 0) {
|
||||||
badChunks.add(MathMan.pairInt(cx, cz));
|
rateLimit = 20;
|
||||||
if (rateLimit <= 0) {
|
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled item lag source at " + loc);
|
||||||
rateLimit = 120;
|
|
||||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled item lag source at " + loc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
|
@ -10,7 +10,6 @@ import com.boydti.fawe.object.FawePlayer;
|
|||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||||
import com.boydti.fawe.object.number.LongAdder;
|
|
||||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
@ -35,6 +34,7 @@ import java.util.Iterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import net.minecraft.server.v1_11_R1.BiomeBase;
|
import net.minecraft.server.v1_11_R1.BiomeBase;
|
||||||
import net.minecraft.server.v1_11_R1.BiomeCache;
|
import net.minecraft.server.v1_11_R1.BiomeCache;
|
||||||
import net.minecraft.server.v1_11_R1.Block;
|
import net.minecraft.server.v1_11_R1.Block;
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.v1_11;
|
|
||||||
|
|
||||||
import com.boydti.fawe.object.FaweInputStream;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
|
||||||
import com.boydti.fawe.util.MathMan;
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.server.v1_11_R1.Block;
|
|
||||||
import net.minecraft.server.v1_11_R1.Chunk;
|
|
||||||
import net.minecraft.server.v1_11_R1.ChunkSection;
|
|
||||||
import net.minecraft.server.v1_11_R1.Entity;
|
|
||||||
import net.minecraft.server.v1_11_R1.ExceptionWorldConflict;
|
|
||||||
import net.minecraft.server.v1_11_R1.IAsyncChunkSaver;
|
|
||||||
import net.minecraft.server.v1_11_R1.IChunkLoader;
|
|
||||||
import net.minecraft.server.v1_11_R1.MinecraftKey;
|
|
||||||
import net.minecraft.server.v1_11_R1.NBTCompressedStreamTools;
|
|
||||||
import net.minecraft.server.v1_11_R1.NBTReadLimiter;
|
|
||||||
import net.minecraft.server.v1_11_R1.NBTTagCompound;
|
|
||||||
import net.minecraft.server.v1_11_R1.NBTTagList;
|
|
||||||
import net.minecraft.server.v1_11_R1.NextTickListEntry;
|
|
||||||
import net.minecraft.server.v1_11_R1.NibbleArray;
|
|
||||||
import net.minecraft.server.v1_11_R1.TileEntity;
|
|
||||||
import net.minecraft.server.v1_11_R1.World;
|
|
||||||
|
|
||||||
public class FaweChunkLoader implements IChunkLoader, IAsyncChunkSaver {
|
|
||||||
|
|
||||||
private final File folder;
|
|
||||||
private Long2ObjectMap<Long> hashes = new Long2ObjectOpenHashMap<>();
|
|
||||||
|
|
||||||
public FaweChunkLoader(File folder) {
|
|
||||||
this.folder = folder;
|
|
||||||
System.out.println(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeNextIO (save)
|
|
||||||
@Override
|
|
||||||
public boolean c() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadChunk
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Chunk a(World world, int x, int z) throws IOException {
|
|
||||||
long pair = MathMan.pairInt(x, z);
|
|
||||||
Long hash = hashes.get(pair);
|
|
||||||
if (hash == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
File file = new File(folder, hash.toString());
|
|
||||||
int length = (int) file.length();
|
|
||||||
try (FaweInputStream in = MainUtil.getCompressedIS(new FileInputStream(file), Math.min(length, 8192))) {
|
|
||||||
NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a(in, NBTReadLimiter.a);
|
|
||||||
return readChunkFromNBT(world, nbttagcompound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Chunk readChunkFromNBT(World world, NBTTagCompound nbttagcompound) {
|
|
||||||
int i = nbttagcompound.getInt("xPos");
|
|
||||||
int j = nbttagcompound.getInt("zPos");
|
|
||||||
Chunk chunk = new Chunk(world, i, j);
|
|
||||||
chunk.a(nbttagcompound.getIntArray("HeightMap"));
|
|
||||||
chunk.d(nbttagcompound.getBoolean("TerrainPopulated"));
|
|
||||||
chunk.e(nbttagcompound.getBoolean("LightPopulated"));
|
|
||||||
chunk.c(nbttagcompound.getLong("InhabitedTime"));
|
|
||||||
NBTTagList nbttaglist = nbttagcompound.getList("Sections", 10);
|
|
||||||
ChunkSection[] achunksection = new ChunkSection[16];
|
|
||||||
boolean flag1 = world.worldProvider.m();
|
|
||||||
|
|
||||||
for(int k = 0; k < nbttaglist.size(); ++k) {
|
|
||||||
NBTTagCompound nbttagcompound1 = nbttaglist.get(k);
|
|
||||||
byte b0 = nbttagcompound1.getByte("Y");
|
|
||||||
ChunkSection chunksection = new ChunkSection(b0 << 4, flag1);
|
|
||||||
byte[] abyte = nbttagcompound1.getByteArray("Blocks");
|
|
||||||
NibbleArray nibblearray = new NibbleArray(nbttagcompound1.getByteArray("Data"));
|
|
||||||
NibbleArray nibblearray1 = nbttagcompound1.hasKeyOfType("Add", 7) ? new NibbleArray(nbttagcompound1.getByteArray("Add")):null;
|
|
||||||
chunksection.getBlocks().a(abyte, nibblearray, nibblearray1);
|
|
||||||
chunksection.a(new NibbleArray(nbttagcompound1.getByteArray("BlockLight")));
|
|
||||||
if(flag1) {
|
|
||||||
chunksection.b(new NibbleArray(nbttagcompound1.getByteArray("SkyLight")));
|
|
||||||
}
|
|
||||||
|
|
||||||
chunksection.recalcBlockCounts();
|
|
||||||
achunksection[b0] = chunksection;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk.a(achunksection);
|
|
||||||
if(nbttagcompound.hasKeyOfType("Biomes", 7)) {
|
|
||||||
chunk.a(nbttagcompound.getByteArray("Biomes"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// saveChunk
|
|
||||||
@Override
|
|
||||||
public void a(World world, Chunk chunk) throws IOException, ExceptionWorldConflict {
|
|
||||||
try {
|
|
||||||
NBTTagCompound exception = new NBTTagCompound();
|
|
||||||
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
||||||
exception.set("Level", nbttagcompound1);
|
|
||||||
exception.setInt("DataVersion", 819);
|
|
||||||
this.writeChunkToNBT(chunk, world, nbttagcompound1);
|
|
||||||
// this.a(chunk.k(), exception);
|
|
||||||
} catch (Exception var5) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeChunkToNBT(Chunk chunk, World world, NBTTagCompound nbttagcompound) {
|
|
||||||
nbttagcompound.setInt("xPos", chunk.locX);
|
|
||||||
nbttagcompound.setInt("zPos", chunk.locZ);
|
|
||||||
nbttagcompound.setLong("LastUpdate", world.getTime());
|
|
||||||
nbttagcompound.setIntArray("HeightMap", chunk.r());
|
|
||||||
nbttagcompound.setBoolean("TerrainPopulated", chunk.isDone());
|
|
||||||
nbttagcompound.setBoolean("LightPopulated", chunk.v());
|
|
||||||
nbttagcompound.setLong("InhabitedTime", chunk.x());
|
|
||||||
ChunkSection[] achunksection = chunk.getSections();
|
|
||||||
NBTTagList nbttaglist = new NBTTagList();
|
|
||||||
boolean flag = world.worldProvider.m();
|
|
||||||
ChunkSection[] achunksection1 = achunksection;
|
|
||||||
int i = achunksection.length;
|
|
||||||
|
|
||||||
NBTTagCompound nbttagcompound1;
|
|
||||||
for(int nbttaglist1 = 0; nbttaglist1 < i; ++nbttaglist1) {
|
|
||||||
ChunkSection iterator = achunksection1[nbttaglist1];
|
|
||||||
if(iterator != Chunk.a) {
|
|
||||||
nbttagcompound1 = new NBTTagCompound();
|
|
||||||
nbttagcompound1.setByte("Y", (byte)(iterator.getYPosition() >> 4 & 255));
|
|
||||||
byte[] nbttaglist2 = new byte[4096];
|
|
||||||
NibbleArray list = new NibbleArray();
|
|
||||||
NibbleArray nibblearray1 = iterator.getBlocks().exportData(nbttaglist2, list);
|
|
||||||
nbttagcompound1.setByteArray("Blocks", nbttaglist2);
|
|
||||||
nbttagcompound1.setByteArray("Data", list.asBytes());
|
|
||||||
if(nibblearray1 != null) {
|
|
||||||
nbttagcompound1.setByteArray("Add", nibblearray1.asBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
nbttagcompound1.setByteArray("BlockLight", iterator.getEmittedLightArray().asBytes());
|
|
||||||
if(flag) {
|
|
||||||
nbttagcompound1.setByteArray("SkyLight", iterator.getSkyLightArray().asBytes());
|
|
||||||
} else {
|
|
||||||
nbttagcompound1.setByteArray("SkyLight", new byte[iterator.getEmittedLightArray().asBytes().length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
nbttaglist.add(nbttagcompound1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nbttagcompound.set("Sections", nbttaglist);
|
|
||||||
nbttagcompound.setByteArray("Biomes", chunk.getBiomeIndex());
|
|
||||||
chunk.g(false);
|
|
||||||
NBTTagList var22 = new NBTTagList();
|
|
||||||
|
|
||||||
Iterator var23;
|
|
||||||
for(i = 0; i < chunk.getEntitySlices().length; ++i) {
|
|
||||||
var23 = chunk.getEntitySlices()[i].iterator();
|
|
||||||
|
|
||||||
while(var23.hasNext()) {
|
|
||||||
Entity var24 = (Entity)var23.next();
|
|
||||||
nbttagcompound1 = new NBTTagCompound();
|
|
||||||
if(var24.d(nbttagcompound1)) {
|
|
||||||
chunk.g(true);
|
|
||||||
var22.add(nbttagcompound1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nbttagcompound.set("Entities", var22);
|
|
||||||
NBTTagList var25 = new NBTTagList();
|
|
||||||
var23 = chunk.getTileEntities().values().iterator();
|
|
||||||
|
|
||||||
while(var23.hasNext()) {
|
|
||||||
TileEntity var26 = (TileEntity)var23.next();
|
|
||||||
nbttagcompound1 = var26.save(new NBTTagCompound());
|
|
||||||
var25.add(nbttagcompound1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nbttagcompound.set("TileEntities", var25);
|
|
||||||
List var27 = world.a(chunk, false);
|
|
||||||
if(var27 != null) {
|
|
||||||
long k = world.getTime();
|
|
||||||
NBTTagList nbttaglist3 = new NBTTagList();
|
|
||||||
Iterator iterator1 = var27.iterator();
|
|
||||||
|
|
||||||
while(iterator1.hasNext()) {
|
|
||||||
NextTickListEntry nextticklistentry = (NextTickListEntry)iterator1.next();
|
|
||||||
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
|
|
||||||
MinecraftKey minecraftkey = (MinecraftKey) Block.REGISTRY.b(nextticklistentry.a());
|
|
||||||
nbttagcompound2.setString("i", minecraftkey == null?"":minecraftkey.toString());
|
|
||||||
nbttagcompound2.setInt("x", nextticklistentry.a.getX());
|
|
||||||
nbttagcompound2.setInt("y", nextticklistentry.a.getY());
|
|
||||||
nbttagcompound2.setInt("z", nextticklistentry.a.getZ());
|
|
||||||
nbttagcompound2.setInt("t", (int)(nextticklistentry.b - k));
|
|
||||||
nbttagcompound2.setInt("p", nextticklistentry.c);
|
|
||||||
nbttaglist3.add(nbttagcompound2);
|
|
||||||
}
|
|
||||||
|
|
||||||
nbttagcompound.set("TileTicks", nbttaglist3);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// saveExtraChunkData
|
|
||||||
@Override
|
|
||||||
public void b(World world, Chunk chunk) throws IOException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// chunkTick
|
|
||||||
@Override
|
|
||||||
public void a() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// saveExtraData
|
|
||||||
@Override
|
|
||||||
public void b() {
|
|
||||||
// try {
|
|
||||||
// this.savingExtraData = true;
|
|
||||||
//
|
|
||||||
// while(true) {
|
|
||||||
// if(this.writeNextIO()) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } finally {
|
|
||||||
// this.savingExtraData = false;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// isChunkGeneratedAt
|
|
||||||
@Override
|
|
||||||
public boolean a(int x, int z) {
|
|
||||||
return hashes.containsKey(MathMan.pairInt(x, z));
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,499 @@
|
|||||||
|
package com.boydti.fawe.bukkit.v1_12;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
|
import com.boydti.fawe.example.CharFaweChunk;
|
||||||
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
|
import com.boydti.fawe.util.MainUtil;
|
||||||
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.ListTag;
|
||||||
|
import com.sk89q.jnbt.LongTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import net.minecraft.server.v1_12_R1.Block;
|
||||||
|
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||||
|
import net.minecraft.server.v1_12_R1.ChunkSection;
|
||||||
|
import net.minecraft.server.v1_12_R1.DataBits;
|
||||||
|
import net.minecraft.server.v1_12_R1.DataPalette;
|
||||||
|
import net.minecraft.server.v1_12_R1.DataPaletteBlock;
|
||||||
|
import net.minecraft.server.v1_12_R1.DataPaletteGlobal;
|
||||||
|
import net.minecraft.server.v1_12_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityTypes;
|
||||||
|
import net.minecraft.server.v1_12_R1.IBlockData;
|
||||||
|
import net.minecraft.server.v1_12_R1.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_12_R1.TileEntity;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftChunk;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
|
public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||||
|
|
||||||
|
public DataPaletteBlock[] sectionPalettes;
|
||||||
|
|
||||||
|
public static Map<String, Class<? extends Entity>> entityKeys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
|
||||||
|
*
|
||||||
|
* @param parent
|
||||||
|
* @param x
|
||||||
|
* @param z
|
||||||
|
*/
|
||||||
|
public BukkitChunk_1_12(FaweQueue parent, int x, int z) {
|
||||||
|
super(parent, x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitChunk_1_12(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||||
|
super(parent, x, z, ids, count, air, heightMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeBiomes(byte[] biomes) {
|
||||||
|
this.biomes = Arrays.copyOf(biomes, biomes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storeTile(TileEntity tile, BlockPosition pos) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
CompoundTag nativeTag = getParent().getTag(tile);
|
||||||
|
setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storeEntity(Entity ent) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
if (ent instanceof EntityPlayer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int x = ((int) Math.round(ent.locX) & 15);
|
||||||
|
int z = ((int) Math.round(ent.locZ) & 15);
|
||||||
|
int y = ((int) Math.round(ent.locY) & 0xFF);
|
||||||
|
int i = FaweCache.CACHE_I[y][z][x];
|
||||||
|
int j = FaweCache.CACHE_J[y][z][x];
|
||||||
|
String id = EntityTypes.b(ent);
|
||||||
|
if (id != null) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
ent.save(tag); // readEntityIntoTag
|
||||||
|
CompoundTag nativeTag = (CompoundTag) getParent().methodToNative.invoke(getParent().adapter, tag);
|
||||||
|
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||||
|
map.put("Id", new StringTag(id));
|
||||||
|
setEntity(nativeTag);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharFaweChunk copy(boolean shallow) {
|
||||||
|
BukkitChunk_1_12 copy;
|
||||||
|
if (shallow) {
|
||||||
|
copy = new BukkitChunk_1_12(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||||
|
copy.biomes = biomes;
|
||||||
|
copy.chunk = chunk;
|
||||||
|
} else {
|
||||||
|
copy = new BukkitChunk_1_12(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||||
|
copy.biomes = biomes;
|
||||||
|
copy.chunk = chunk;
|
||||||
|
copy.biomes = biomes.clone();
|
||||||
|
copy.chunk = chunk;
|
||||||
|
}
|
||||||
|
if (sectionPalettes != null) {
|
||||||
|
copy.sectionPalettes = new DataPaletteBlock[16];
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < sectionPalettes.length; i++) {
|
||||||
|
DataPaletteBlock current = sectionPalettes[i];
|
||||||
|
if (current == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Clone palette
|
||||||
|
DataPalette currentPalette = (DataPalette) BukkitQueue_1_12.fieldPalette.get(current);
|
||||||
|
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||||
|
current.a(128, null);
|
||||||
|
}
|
||||||
|
DataPaletteBlock paletteBlock = newDataPaletteBlock();
|
||||||
|
currentPalette = (DataPalette) BukkitQueue_1_12.fieldPalette.get(current);
|
||||||
|
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||||
|
throw new RuntimeException("Palette must be global!");
|
||||||
|
}
|
||||||
|
BukkitQueue_1_12.fieldPalette.set(paletteBlock, currentPalette);
|
||||||
|
// Clone size
|
||||||
|
BukkitQueue_1_12.fieldSize.set(paletteBlock, BukkitQueue_1_12.fieldSize.get(current));
|
||||||
|
// Clone palette
|
||||||
|
DataBits currentBits = (DataBits) BukkitQueue_1_12.fieldBits.get(current);
|
||||||
|
DataBits newBits = new DataBits(1, 0);
|
||||||
|
for (Field field : DataBits.class.getDeclaredFields()) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object currentValue = field.get(currentBits);
|
||||||
|
if (currentValue instanceof long[]) {
|
||||||
|
currentValue = ((long[]) currentValue).clone();
|
||||||
|
}
|
||||||
|
field.set(newBits, currentValue);
|
||||||
|
}
|
||||||
|
BukkitQueue_1_12.fieldBits.set(paletteBlock, newBits);
|
||||||
|
copy.sectionPalettes[i] = paletteBlock;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
MainUtil.handleError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Chunk getNewChunk() {
|
||||||
|
return ((BukkitQueue_1_12) getParent()).getWorld().getChunkAt(getX(), getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataPaletteBlock newDataPaletteBlock() {
|
||||||
|
try {
|
||||||
|
return new DataPaletteBlock();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
try {
|
||||||
|
Constructor<DataPaletteBlock> constructor = DataPaletteBlock.class.getDeclaredConstructor(IBlockData[].class);
|
||||||
|
return constructor.newInstance((Object) null);
|
||||||
|
} catch (Throwable e2) {
|
||||||
|
throw new RuntimeException(e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void optimize() {
|
||||||
|
if (sectionPalettes != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char[][] arrays = getCombinedIdArrays();
|
||||||
|
IBlockData lastBlock = null;
|
||||||
|
char lastChar = Character.MAX_VALUE;
|
||||||
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
|
if (getCount(layer) > 0) {
|
||||||
|
if (sectionPalettes == null) {
|
||||||
|
sectionPalettes = new DataPaletteBlock[16];
|
||||||
|
}
|
||||||
|
DataPaletteBlock palette = newDataPaletteBlock();
|
||||||
|
char[] blocks = getIdArray(layer);
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
char combinedId = blocks[FaweCache.CACHE_J[y][z][x]];
|
||||||
|
if (combinedId > 1) {
|
||||||
|
palette.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
getChunk().load(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeEntity(Entity entity) {
|
||||||
|
entity.b(false);
|
||||||
|
entity.die();
|
||||||
|
entity.valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FaweChunk call() {
|
||||||
|
try {
|
||||||
|
BukkitChunk_1_12_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_12_Copy(getParent(), getX(), getZ()) : null;
|
||||||
|
final Chunk chunk = this.getChunk();
|
||||||
|
final World world = chunk.getWorld();
|
||||||
|
int bx = this.getX() << 4;
|
||||||
|
int bz = this.getZ() << 4;
|
||||||
|
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||||
|
net.minecraft.server.v1_12_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||||
|
nmsChunk.f(true); // Set Modified
|
||||||
|
nmsChunk.mustSave = true;
|
||||||
|
net.minecraft.server.v1_12_R1.World nmsWorld = nmsChunk.world;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
final Collection<Entity>[] entities = (Collection<Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
|
||||||
|
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||||
|
// Set heightmap
|
||||||
|
getParent().setHeightMap(this, heightMap);
|
||||||
|
// Remove entities
|
||||||
|
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||||
|
if (!entsToRemove.isEmpty()) {
|
||||||
|
for (int i = 0; i < entities.length; i++) {
|
||||||
|
Collection<Entity> ents = entities[i];
|
||||||
|
if (!ents.isEmpty()) {
|
||||||
|
Iterator<Entity> iter = ents.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Entity entity = iter.next();
|
||||||
|
if (entsToRemove.contains(entity.getUniqueID())) {
|
||||||
|
if (copy != null) {
|
||||||
|
copy.storeEntity(entity);
|
||||||
|
}
|
||||||
|
removeEntity(entity);
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < entities.length; i++) {
|
||||||
|
int count = this.getCount(i);
|
||||||
|
if (count == 0) {
|
||||||
|
continue;
|
||||||
|
} else if (count >= 4096) {
|
||||||
|
Collection<Entity> ents = entities[i];
|
||||||
|
if (!ents.isEmpty()) {
|
||||||
|
if (copy != null) {
|
||||||
|
for (Entity entity : ents) {
|
||||||
|
copy.storeEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized (BukkitQueue_0.class) {
|
||||||
|
ents.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Collection<Entity> ents = entities[i];
|
||||||
|
if (!ents.isEmpty()) {
|
||||||
|
char[] array = this.getIdArray(i);
|
||||||
|
if (array == null) continue;
|
||||||
|
Iterator<Entity> iter = ents.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Entity entity = iter.next();
|
||||||
|
if (entity instanceof EntityPlayer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int x = ((int) Math.round(entity.locX) & 15);
|
||||||
|
int z = ((int) Math.round(entity.locZ) & 15);
|
||||||
|
int y = (int) Math.round(entity.locY);
|
||||||
|
if (y < 0 || y > 255) continue;
|
||||||
|
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||||
|
if (copy != null) {
|
||||||
|
copy.storeEntity(entity);
|
||||||
|
}
|
||||||
|
iter.remove();
|
||||||
|
removeEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set entities
|
||||||
|
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||||
|
Set<UUID> createdEntities = new HashSet<>();
|
||||||
|
if (!entitiesToSpawn.isEmpty()) {
|
||||||
|
synchronized (BukkitQueue_0.class) {
|
||||||
|
for (CompoundTag nativeTag : entitiesToSpawn) {
|
||||||
|
Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
|
||||||
|
StringTag idTag = (StringTag) entityTagMap.get("Id");
|
||||||
|
ListTag posTag = (ListTag) entityTagMap.get("Pos");
|
||||||
|
ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
|
||||||
|
if (idTag == null || posTag == null || rotTag == null) {
|
||||||
|
Fawe.debug("Unknown entity tag: " + nativeTag);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
double x = posTag.getDouble(0);
|
||||||
|
double y = posTag.getDouble(1);
|
||||||
|
double z = posTag.getDouble(2);
|
||||||
|
float yaw = rotTag.getFloat(0);
|
||||||
|
float pitch = rotTag.getFloat(1);
|
||||||
|
String id = idTag.getValue();
|
||||||
|
if (entityKeys == null) {
|
||||||
|
entityKeys = new HashMap<>();
|
||||||
|
for (MinecraftKey key : EntityTypes.a()) {
|
||||||
|
String currentId = EntityTypes.a(key);
|
||||||
|
Class<? extends Entity> clazz = EntityTypes.b.get(key);
|
||||||
|
entityKeys.put(currentId, clazz);
|
||||||
|
entityKeys.put(key.getKey(), clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Class<? extends Entity> clazz = entityKeys.get(id);
|
||||||
|
if (clazz != null) {
|
||||||
|
Entity entity = EntityTypes.a(clazz, nmsWorld);
|
||||||
|
if (entity != null) {
|
||||||
|
UUID uuid = entity.getUniqueID();
|
||||||
|
entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
|
||||||
|
entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
|
||||||
|
if (nativeTag != null) {
|
||||||
|
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_12.methodFromNative.invoke(BukkitQueue_1_12.adapter, nativeTag);
|
||||||
|
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||||
|
tag.remove(name);
|
||||||
|
}
|
||||||
|
entity.f(tag);
|
||||||
|
}
|
||||||
|
entity.setLocation(x, y, z, yaw, pitch);
|
||||||
|
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||||
|
createdEntities.add(entity.getUniqueID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Trim tiles
|
||||||
|
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||||
|
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||||
|
BlockPosition pos = tile.getKey();
|
||||||
|
int lx = pos.getX() & 15;
|
||||||
|
int ly = pos.getY();
|
||||||
|
int lz = pos.getZ() & 15;
|
||||||
|
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||||
|
char[] array = this.getIdArray(j);
|
||||||
|
if (array == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||||
|
if (array[k] != 0) {
|
||||||
|
if (toRemove == null) {
|
||||||
|
toRemove = new HashMap<>();
|
||||||
|
}
|
||||||
|
if (copy != null) {
|
||||||
|
copy.storeTile(tile.getValue(), tile.getKey());
|
||||||
|
}
|
||||||
|
toRemove.put(tile.getKey(), tile.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toRemove != null) {
|
||||||
|
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||||
|
BlockPosition bp = entry.getKey();
|
||||||
|
TileEntity tile = entry.getValue();
|
||||||
|
tiles.remove(bp);
|
||||||
|
tile.z();
|
||||||
|
nmsWorld.s(bp);
|
||||||
|
tile.invalidateBlockCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// Set blocks
|
||||||
|
for (int j = 0; j < sections.length; j++) {
|
||||||
|
int count = this.getCount(j);
|
||||||
|
if (count == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int countAir = this.getAir(j);
|
||||||
|
final char[] array = this.getIdArray(j);
|
||||||
|
if (array == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ChunkSection section = sections[j];
|
||||||
|
if (copy != null) {
|
||||||
|
copy.storeSection(section, j);
|
||||||
|
}
|
||||||
|
if (section == null) {
|
||||||
|
if (count == countAir) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
|
||||||
|
section = sections[j] = getParent().newChunkSection(j << 4, flag, null);
|
||||||
|
getParent().setPalette(section, this.sectionPalettes[j]);
|
||||||
|
getParent().setCount(0, count - this.getAir(j), section);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
sections[j] = getParent().newChunkSection(j << 4, flag, array);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (count >= 4096) {
|
||||||
|
if (countAir >= 4096) {
|
||||||
|
sections[j] = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
|
||||||
|
getParent().setPalette(section, this.sectionPalettes[j]);
|
||||||
|
getParent().setCount(0, count - this.getAir(j), section);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
sections[j] = getParent().newChunkSection(j << 4, flag, array);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int by = j << 4;
|
||||||
|
DataPaletteBlock nibble = section.getBlocks();
|
||||||
|
int nonEmptyBlockCount = 0;
|
||||||
|
IBlockData existing;
|
||||||
|
for (int y = 0; y < 16; y++) {
|
||||||
|
short[][] i1 = FaweCache.CACHE_J[y];
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
short[] i2 = i1[z];
|
||||||
|
for (int x= 0; x < 16; x++) {
|
||||||
|
char combinedId = array[i2[x]];
|
||||||
|
switch (combinedId) {
|
||||||
|
case 0:
|
||||||
|
continue;
|
||||||
|
case 1:
|
||||||
|
existing = nibble.a(x, y, z);
|
||||||
|
if (existing != BukkitQueue_1_12.air) {
|
||||||
|
if (existing.d() > 0) {
|
||||||
|
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||||
|
}
|
||||||
|
nonEmptyBlockCount--;
|
||||||
|
}
|
||||||
|
nibble.setBlock(x, y, z, BukkitQueue_1_12.air);
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
existing = nibble.a(x, y, z);
|
||||||
|
if (existing != BukkitQueue_1_12.air) {
|
||||||
|
if (existing.d() > 0) {
|
||||||
|
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nonEmptyBlockCount++;
|
||||||
|
}
|
||||||
|
nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||||
|
}
|
||||||
|
// Set biomes
|
||||||
|
if (this.biomes != null) {
|
||||||
|
if (copy != null) {
|
||||||
|
copy.storeBiomes(nmsChunk.getBiomeIndex());
|
||||||
|
}
|
||||||
|
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||||
|
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||||
|
if (this.biomes[i] != 0) {
|
||||||
|
currentBiomes[i] = this.biomes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set tiles
|
||||||
|
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||||
|
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||||
|
CompoundTag nativeTag = entry.getValue();
|
||||||
|
short blockHash = entry.getKey();
|
||||||
|
int x = (blockHash >> 12 & 0xF) + bx;
|
||||||
|
int y = (blockHash & 0xFF);
|
||||||
|
int z = (blockHash >> 8 & 0xF) + bz;
|
||||||
|
BlockPosition pos = new BlockPosition(x, y, z); // Set pos
|
||||||
|
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||||
|
if (tileEntity != null) {
|
||||||
|
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_12.methodFromNative.invoke(BukkitQueue_1_12.adapter, nativeTag);
|
||||||
|
tileEntity.a(tag); // ReadTagIntoTile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Change task
|
||||||
|
if (copy != null) {
|
||||||
|
getParent().getChangeTask().run(copy, this);
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
MainUtil.handleError(e);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.boydti.fawe.bukkit.v1_12;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
|
import net.minecraft.server.v1_12_R1.ChunkSection;
|
||||||
|
import net.minecraft.server.v1_12_R1.DataPaletteBlock;
|
||||||
|
import net.minecraft.server.v1_12_R1.NibbleArray;
|
||||||
|
|
||||||
|
public class BukkitChunk_1_12_Copy extends BukkitChunk_1_12 {
|
||||||
|
public final byte[][] idsBytes;
|
||||||
|
public final byte[][] datasBytes;
|
||||||
|
|
||||||
|
public BukkitChunk_1_12_Copy(FaweQueue parent, int x, int z) {
|
||||||
|
super(parent, x, z);
|
||||||
|
idsBytes = new byte[16][];
|
||||||
|
datasBytes = new byte[16][];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(int i, byte[] ids, byte[] data) {
|
||||||
|
this.idsBytes[i] = ids;
|
||||||
|
this.datasBytes[i] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean storeSection(ChunkSection section, int layer) throws IllegalAccessException {
|
||||||
|
if (section == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DataPaletteBlock blocks = section.getBlocks();
|
||||||
|
byte[] ids = new byte[4096];
|
||||||
|
NibbleArray data = new NibbleArray();
|
||||||
|
blocks.exportData(ids, data);
|
||||||
|
set(layer, ids, data.asBytes());
|
||||||
|
short solid = (short) getParent().fieldNonEmptyBlockCount.getInt(section);
|
||||||
|
count[layer] = solid;
|
||||||
|
air[layer] = (short) (4096 - solid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[][] getCombinedIdArrays() {
|
||||||
|
for (int i = 0; i < ids.length; i++) {
|
||||||
|
getIdArray(i);
|
||||||
|
}
|
||||||
|
return super.getCombinedIdArrays();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getIdArray(int i) {
|
||||||
|
char[] combined = this.ids[i];
|
||||||
|
if (combined != null) {
|
||||||
|
return combined;
|
||||||
|
}
|
||||||
|
byte[] idsBytesArray = idsBytes[i];
|
||||||
|
if (idsBytesArray == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] datasBytesArray = datasBytes[i];
|
||||||
|
|
||||||
|
idsBytes[i] = null;
|
||||||
|
datasBytes[i] = null;
|
||||||
|
|
||||||
|
this.ids[i] = combined = new char[4096];
|
||||||
|
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
|
||||||
|
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + (datasBytesArray[j] & 15));
|
||||||
|
}
|
||||||
|
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
|
||||||
|
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + ((datasBytesArray[j] >> 4) & 15));
|
||||||
|
}
|
||||||
|
return combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlock(int x, int y, int z, int id) {
|
||||||
|
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlock(int x, int y, int z, int id, int data) {
|
||||||
|
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,803 @@
|
|||||||
|
package com.boydti.fawe.bukkit.v1_12;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.bukkit.BukkitPlayer;
|
||||||
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
|
import com.boydti.fawe.example.CharFaweChunk;
|
||||||
|
import com.boydti.fawe.object.FaweChunk;
|
||||||
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
|
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||||
|
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||||
|
import com.boydti.fawe.util.MainUtil;
|
||||||
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
|
import com.boydti.fawe.util.TaskManager;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
import net.minecraft.server.v1_12_R1.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_12_R1.BiomeCache;
|
||||||
|
import net.minecraft.server.v1_12_R1.Block;
|
||||||
|
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||||
|
import net.minecraft.server.v1_12_R1.ChunkProviderGenerate;
|
||||||
|
import net.minecraft.server.v1_12_R1.ChunkProviderServer;
|
||||||
|
import net.minecraft.server.v1_12_R1.ChunkSection;
|
||||||
|
import net.minecraft.server.v1_12_R1.DataPaletteBlock;
|
||||||
|
import net.minecraft.server.v1_12_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityTracker;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityTypes;
|
||||||
|
import net.minecraft.server.v1_12_R1.EnumDifficulty;
|
||||||
|
import net.minecraft.server.v1_12_R1.EnumGamemode;
|
||||||
|
import net.minecraft.server.v1_12_R1.EnumSkyBlock;
|
||||||
|
import net.minecraft.server.v1_12_R1.IBlockData;
|
||||||
|
import net.minecraft.server.v1_12_R1.IDataManager;
|
||||||
|
import net.minecraft.server.v1_12_R1.MinecraftServer;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_12_R1.NibbleArray;
|
||||||
|
import net.minecraft.server.v1_12_R1.PacketDataSerializer;
|
||||||
|
import net.minecraft.server.v1_12_R1.PacketPlayOutMapChunk;
|
||||||
|
import net.minecraft.server.v1_12_R1.PacketPlayOutMultiBlockChange;
|
||||||
|
import net.minecraft.server.v1_12_R1.PlayerChunk;
|
||||||
|
import net.minecraft.server.v1_12_R1.PlayerChunkMap;
|
||||||
|
import net.minecraft.server.v1_12_R1.RegionFile;
|
||||||
|
import net.minecraft.server.v1_12_R1.RegionFileCache;
|
||||||
|
import net.minecraft.server.v1_12_R1.ServerNBTManager;
|
||||||
|
import net.minecraft.server.v1_12_R1.TileEntity;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldChunkManager;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldData;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldManager;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldServer;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldSettings;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldType;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.WorldCreator;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftChunk;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
|
||||||
|
public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R1.Chunk, ChunkSection[], ChunkSection> {
|
||||||
|
|
||||||
|
protected static IBlockData air;
|
||||||
|
protected static Field fieldBits;
|
||||||
|
protected static Field fieldPalette;
|
||||||
|
protected static Field fieldSize;
|
||||||
|
protected static Method getEntitySlices;
|
||||||
|
protected static Field fieldTickingBlockCount;
|
||||||
|
protected static Field fieldNonEmptyBlockCount;
|
||||||
|
protected static Field fieldSection;
|
||||||
|
protected static Field fieldBiomes;
|
||||||
|
protected static Field fieldChunkGenerator;
|
||||||
|
protected static Field fieldSeed;
|
||||||
|
protected static Field fieldBiomeCache;
|
||||||
|
protected static Field fieldBiomes2;
|
||||||
|
protected static Field fieldGenLayer1;
|
||||||
|
protected static Field fieldGenLayer2;
|
||||||
|
protected static MutableGenLayer genLayer;
|
||||||
|
protected static ChunkSection emptySection;
|
||||||
|
|
||||||
|
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE + 1];
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
emptySection = new ChunkSection(0, true);
|
||||||
|
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||||
|
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||||
|
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||||
|
fieldSection.setAccessible(true);
|
||||||
|
fieldTickingBlockCount.setAccessible(true);
|
||||||
|
fieldNonEmptyBlockCount.setAccessible(true);
|
||||||
|
|
||||||
|
fieldBiomes = ChunkProviderGenerate.class.getDeclaredField("D");
|
||||||
|
fieldBiomes.setAccessible(true);
|
||||||
|
fieldChunkGenerator = ChunkProviderServer.class.getDeclaredField("chunkGenerator");
|
||||||
|
fieldChunkGenerator.setAccessible(true);
|
||||||
|
fieldSeed = WorldData.class.getDeclaredField("e");
|
||||||
|
fieldSeed.setAccessible(true);
|
||||||
|
fieldBiomeCache = WorldChunkManager.class.getDeclaredField("d");
|
||||||
|
fieldBiomeCache.setAccessible(true);
|
||||||
|
fieldBiomes2 = WorldChunkManager.class.getDeclaredField("e");
|
||||||
|
fieldBiomes2.setAccessible(true);
|
||||||
|
fieldGenLayer1 = WorldChunkManager.class.getDeclaredField("b") ;
|
||||||
|
fieldGenLayer2 = WorldChunkManager.class.getDeclaredField("c") ;
|
||||||
|
fieldGenLayer1.setAccessible(true);
|
||||||
|
fieldGenLayer2.setAccessible(true);
|
||||||
|
|
||||||
|
fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
|
||||||
|
fieldPalette.setAccessible(true);
|
||||||
|
fieldSize = DataPaletteBlock.class.getDeclaredField("e");
|
||||||
|
fieldSize.setAccessible(true);
|
||||||
|
|
||||||
|
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||||
|
fieldAir.setAccessible(true);
|
||||||
|
air = (IBlockData) fieldAir.get(null);
|
||||||
|
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||||
|
fieldBits.setAccessible(true);
|
||||||
|
getEntitySlices = net.minecraft.server.v1_12_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||||
|
getEntitySlices.setAccessible(true);
|
||||||
|
setupAdapter(new FaweAdapter_1_12());
|
||||||
|
Fawe.debug("Using adapter: " + adapter);
|
||||||
|
Fawe.debug("=========================================");
|
||||||
|
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||||
|
try {
|
||||||
|
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||||
|
} catch (Throwable ignore) {}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitQueue_1_12(final com.sk89q.worldedit.world.World world) {
|
||||||
|
super(world);
|
||||||
|
getImpWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitQueue_1_12(final String world) {
|
||||||
|
super(world);
|
||||||
|
getImpWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkSection[] getSections(net.minecraft.server.v1_12_R1.Chunk chunk) {
|
||||||
|
return chunk.getSections();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.server.v1_12_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||||
|
ChunkProviderServer provider = ((CraftWorld) world).getHandle().getChunkProviderServer();
|
||||||
|
if (generate) {
|
||||||
|
return provider.getOrLoadChunkAt(x, z);
|
||||||
|
} else {
|
||||||
|
return provider.loadChunk(x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||||
|
net.minecraft.server.v1_12_R1.Chunk chunk = ((CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||||
|
if (chunk != null) {
|
||||||
|
return chunk.getSections();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.server.v1_12_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||||
|
return ((CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||||
|
return chunkSections[cy];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveChunk(net.minecraft.server.v1_12_R1.Chunk chunk) {
|
||||||
|
chunk.f(true); // Set Modified
|
||||||
|
chunk.mustSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||||
|
if (biome != null) {
|
||||||
|
try {
|
||||||
|
if (seed == null) {
|
||||||
|
seed = world.getSeed();
|
||||||
|
}
|
||||||
|
nmsWorld.worldData.getSeed();
|
||||||
|
boolean result;
|
||||||
|
ChunkProviderGenerate generator = new ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||||
|
Biome bukkitBiome = adapter.getBiome(biome.getId());
|
||||||
|
BiomeBase base = BiomeBase.getBiome(biome.getId());
|
||||||
|
fieldBiomes.set(generator, new BiomeBase[]{base});
|
||||||
|
boolean cold = base.getTemperature() <= 1;
|
||||||
|
net.minecraft.server.v1_12_R1.ChunkGenerator existingGenerator = nmsWorld.getChunkProviderServer().chunkGenerator;
|
||||||
|
long existingSeed = world.getSeed();
|
||||||
|
{
|
||||||
|
if (genLayer == null) genLayer = new MutableGenLayer(seed);
|
||||||
|
genLayer.set(biome.getId());
|
||||||
|
Object existingGenLayer1 = fieldGenLayer1.get(nmsWorld.getWorldChunkManager());
|
||||||
|
Object existingGenLayer2 = fieldGenLayer2.get(nmsWorld.getWorldChunkManager());
|
||||||
|
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||||
|
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||||
|
|
||||||
|
fieldSeed.set(nmsWorld.worldData, seed);
|
||||||
|
|
||||||
|
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||||
|
|
||||||
|
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||||
|
|
||||||
|
result = getWorld().regenerateChunk(x, z);
|
||||||
|
|
||||||
|
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||||
|
|
||||||
|
fieldSeed.set(nmsWorld.worldData, existingSeed);
|
||||||
|
|
||||||
|
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), existingGenLayer1);
|
||||||
|
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), existingGenLayer2);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.regenerateChunk(world, x, z, biome, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setMCA(Runnable whileLocked, final RegionWrapper allowed, boolean unload) {
|
||||||
|
try {
|
||||||
|
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||||
|
@Override
|
||||||
|
public void run(Object value) {
|
||||||
|
try {
|
||||||
|
synchronized (RegionFileCache.class) {
|
||||||
|
ArrayDeque<net.minecraft.server.v1_12_R1.Chunk> chunks = new ArrayDeque<>();
|
||||||
|
World world = getWorld();
|
||||||
|
world.setKeepSpawnInMemory(false);
|
||||||
|
ChunkProviderServer provider = nmsWorld.getChunkProviderServer();
|
||||||
|
if (unload) { // Unload chunks
|
||||||
|
int bcx = (allowed.minX >> 9) << 5;
|
||||||
|
int bcz = (allowed.minZ >> 9) << 5;
|
||||||
|
int tcx = 31 + (allowed.maxX >> 9) << 5;
|
||||||
|
int tcz = 31 + (allowed.maxZ >> 9) << 5;
|
||||||
|
Iterator<net.minecraft.server.v1_12_R1.Chunk> iter = provider.a().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
net.minecraft.server.v1_12_R1.Chunk chunk = iter.next();
|
||||||
|
int cx = chunk.locX;
|
||||||
|
int cz = chunk.locZ;
|
||||||
|
if (cx >= bcx && cx <= tcx && cz >= bcz && cz <= tcz) {
|
||||||
|
chunks.add(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (net.minecraft.server.v1_12_R1.Chunk chunk : chunks) {
|
||||||
|
provider.unloadChunk(chunk, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
provider.c();
|
||||||
|
|
||||||
|
if (unload) { // Unload regions
|
||||||
|
Map<File, RegionFile> map = RegionFileCache.a;
|
||||||
|
Iterator<Map.Entry<File, RegionFile>> iter = map.entrySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Map.Entry<File, RegionFile> entry = iter.next();
|
||||||
|
RegionFile regionFile = entry.getValue();
|
||||||
|
regionFile.c();
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
whileLocked.run();
|
||||||
|
// Load the chunks again
|
||||||
|
if (unload) {
|
||||||
|
for (net.minecraft.server.v1_12_R1.Chunk chunk : chunks) {
|
||||||
|
chunk = provider.loadChunk(chunk.locX, chunk.locZ);
|
||||||
|
if (chunk != null) {
|
||||||
|
sendChunk(chunk, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||||
|
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||||
|
if (craftChunk != null) {
|
||||||
|
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||||
|
for (int i = 0; i < heightMap.length; i++) {
|
||||||
|
int newHeight = heightMap[i] & 0xFF;
|
||||||
|
int currentHeight = otherMap[i];
|
||||||
|
if (newHeight > currentHeight) {
|
||||||
|
otherMap[i] = newHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean next(int amount, long time) {
|
||||||
|
return super.next(amount, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
|
||||||
|
section.getSkyLightArray().a(x & 15, y & 15, z & 15, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
|
||||||
|
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public World createWorld(final WorldCreator creator) {
|
||||||
|
final String name = creator.name();
|
||||||
|
ChunkGenerator generator = creator.generator();
|
||||||
|
final CraftServer server = (CraftServer) Bukkit.getServer();
|
||||||
|
final MinecraftServer console = server.getServer();
|
||||||
|
final File folder = new File(server.getWorldContainer(), name);
|
||||||
|
final World world = server.getWorld(name);
|
||||||
|
final WorldType type = WorldType.getType(creator.type().getName());
|
||||||
|
final boolean generateStructures = creator.generateStructures();
|
||||||
|
if (world != null) {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
if (folder.exists() && !folder.isDirectory()) {
|
||||||
|
throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder");
|
||||||
|
}
|
||||||
|
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||||
|
@Override
|
||||||
|
public void run(Object value) {
|
||||||
|
try {
|
||||||
|
Field field = CraftServer.class.getDeclaredField("worlds");
|
||||||
|
field.setAccessible(true);
|
||||||
|
Map<Object, Object> existing = (Map<Object, Object>) field.get(server);
|
||||||
|
if (!existing.getClass().getName().contains("SynchronizedMap")) {
|
||||||
|
field.set(server, Collections.synchronizedMap(existing));
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (generator == null) {
|
||||||
|
generator = server.getGenerator(name);
|
||||||
|
}
|
||||||
|
int dimension = 10 + console.worlds.size();
|
||||||
|
boolean used = false;
|
||||||
|
do {
|
||||||
|
for (final WorldServer ws : console.worlds) {
|
||||||
|
used = (ws.dimension == dimension);
|
||||||
|
if (used) {
|
||||||
|
++dimension;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (used);
|
||||||
|
final boolean hardcore = false;
|
||||||
|
final IDataManager sdm = new ServerNBTManager(server.getWorldContainer(), name, true, server.getHandle().getServer().dataConverterManager);
|
||||||
|
WorldData worlddata = sdm.getWorldData();
|
||||||
|
final WorldSettings worldSettings;
|
||||||
|
if (worlddata == null) {
|
||||||
|
worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(server.getDefaultGameMode().getValue()), generateStructures, hardcore, type);
|
||||||
|
worldSettings.setGeneratorSettings(creator.generatorSettings());
|
||||||
|
worlddata = new WorldData(worldSettings, name);
|
||||||
|
} else {
|
||||||
|
worldSettings = null;
|
||||||
|
}
|
||||||
|
worlddata.checkName(name);
|
||||||
|
final WorldServer internal = (WorldServer)new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b();
|
||||||
|
startSet(true); // Temporarily allow async chunk load since the world isn't added yet
|
||||||
|
if (worldSettings != null) {
|
||||||
|
internal.a(worldSettings);
|
||||||
|
}
|
||||||
|
endSet(true);
|
||||||
|
internal.scoreboard = server.getScoreboardManager().getMainScoreboard().getHandle();
|
||||||
|
internal.tracker = new EntityTracker(internal);
|
||||||
|
internal.addIWorldAccess(new WorldManager(console, internal));
|
||||||
|
internal.worldData.setDifficulty(EnumDifficulty.EASY);
|
||||||
|
internal.setSpawnFlags(true, true);
|
||||||
|
if (generator != null) {
|
||||||
|
internal.getWorld().getPopulators().addAll(generator.getDefaultPopulators(internal.getWorld()));
|
||||||
|
}
|
||||||
|
// Add the world
|
||||||
|
return TaskManager.IMP.sync(new RunnableVal<World>() {
|
||||||
|
@Override
|
||||||
|
public void run(World value) {
|
||||||
|
console.worlds.add(internal);
|
||||||
|
server.getPluginManager().callEvent(new WorldInitEvent(internal.getWorld()));
|
||||||
|
server.getPluginManager().callEvent(new WorldLoadEvent(internal.getWorld()));
|
||||||
|
this.value = internal.getWorld();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCombinedId4Data(ChunkSection lastSection, int x, int y, int z) {
|
||||||
|
DataPaletteBlock dataPalette = lastSection.getBlocks();
|
||||||
|
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||||
|
Block block = ibd.getBlock();
|
||||||
|
int id = Block.getId(block);
|
||||||
|
if (FaweCache.hasData(id)) {
|
||||||
|
return (id << 4) + block.toLegacyData(ibd);
|
||||||
|
} else {
|
||||||
|
return id << 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBiome(net.minecraft.server.v1_12_R1.Chunk chunk, int x, int z) {
|
||||||
|
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity(ChunkSection section, int x, int y, int z) {
|
||||||
|
DataPaletteBlock dataPalette = section.getBlocks();
|
||||||
|
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||||
|
return ibd.c();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBrightness(ChunkSection section, int x, int y, int z) {
|
||||||
|
DataPaletteBlock dataPalette = section.getBlocks();
|
||||||
|
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||||
|
return ibd.d();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
|
||||||
|
DataPaletteBlock dataPalette = section.getBlocks();
|
||||||
|
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||||
|
return MathMan.pair16(ibd.c(), ibd.d());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
net.minecraft.server.v1_12_R1.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||||
|
if (chunk != null) {
|
||||||
|
sendChunk(chunk, bitMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||||
|
try {
|
||||||
|
PlayerChunkMap playerManager = ((CraftWorld) getWorld()).getHandle().getPlayerChunkMap();
|
||||||
|
boolean watching = false;
|
||||||
|
boolean[] watchingArr = new boolean[players.length];
|
||||||
|
for (int i = 0; i < players.length; i++) {
|
||||||
|
EntityPlayer player = ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle();
|
||||||
|
if (playerManager.a(player, chunk.getX(), chunk.getZ())) {
|
||||||
|
watchingArr[i] = true;
|
||||||
|
watching = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!watching) return;
|
||||||
|
final LongAdder size = new LongAdder();
|
||||||
|
if (chunk instanceof VisualChunk) {
|
||||||
|
size.add(((VisualChunk) chunk).size());
|
||||||
|
} else if (chunk instanceof CharFaweChunk) {
|
||||||
|
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||||
|
} else {
|
||||||
|
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||||
|
@Override
|
||||||
|
public void run(int localX, int y, int localZ, int combined) {
|
||||||
|
size.add(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (size.intValue() == 0) return;
|
||||||
|
PacketPlayOutMultiBlockChange packet = new PacketPlayOutMultiBlockChange();
|
||||||
|
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||||
|
final PacketDataSerializer buffer = new PacketDataSerializer(byteBuf);
|
||||||
|
buffer.writeInt(chunk.getX());
|
||||||
|
buffer.writeInt(chunk.getZ());
|
||||||
|
buffer.d(size.intValue());
|
||||||
|
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||||
|
@Override
|
||||||
|
public void run(int localX, int y, int localZ, int combined) {
|
||||||
|
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||||
|
if (combined < 16) combined = 0;
|
||||||
|
buffer.writeShort(index);
|
||||||
|
buffer.d(combined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
packet.a(buffer);
|
||||||
|
for (int i = 0; i < players.length; i++) {
|
||||||
|
if (watchingArr[i]) ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle().playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshChunk(FaweChunk fc) {
|
||||||
|
net.minecraft.server.v1_12_R1.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||||
|
if (chunk != null) {
|
||||||
|
sendChunk(chunk, fc.getBitMask());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(net.minecraft.server.v1_12_R1.Chunk nmsChunk, int mask) {
|
||||||
|
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||||
|
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||||
|
PlayerChunk playerChunk = chunkMap.getChunk(nmsChunk.locX, nmsChunk.locZ);
|
||||||
|
if (playerChunk == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (playerChunk.c.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mask == 0) {
|
||||||
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65535);
|
||||||
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
|
player.playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Send chunks
|
||||||
|
boolean empty = false;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||||
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
|
player.playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
mask = 255;
|
||||||
|
}
|
||||||
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, mask);
|
||||||
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
|
player.playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasEntities(net.minecraft.server.v1_12_R1.Chunk nmsChunk) {
|
||||||
|
try {
|
||||||
|
final Collection<Entity>[] entities = (Collection<Entity>[]) getEntitySlices.invoke(nmsChunk);
|
||||||
|
for (int i = 0; i < entities.length; i++) {
|
||||||
|
Collection<Entity> slice = entities[i];
|
||||||
|
if (slice != null && !slice.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignore) {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||||
|
if (mode != RelightMode.NONE) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
ChunkSection section = sections[i];
|
||||||
|
if (section != null) {
|
||||||
|
section.a(new NibbleArray()); // Emitted
|
||||||
|
if (sky) {
|
||||||
|
section.b(new NibbleArray()); // Skylight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFullbright(ChunkSection[] sections) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
ChunkSection section = sections[i];
|
||||||
|
if (section != null) {
|
||||||
|
byte[] bytes = section.getSkyLightArray().asBytes();
|
||||||
|
Arrays.fill(bytes, (byte) 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(ChunkSection section, int x, int y, int z) {
|
||||||
|
return section.b(x & 15, y & 15, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
|
||||||
|
return section.c(x & 15, y & 15, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void relightBlock(int x, int y, int z) {
|
||||||
|
pos.c(x, y, z);
|
||||||
|
nmsWorld.c(EnumSkyBlock.BLOCK, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void relightSky(int x, int y, int z) {
|
||||||
|
pos.c(x, y, z);
|
||||||
|
nmsWorld.c(EnumSkyBlock.SKY, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void relight(int x, int y, int z) {
|
||||||
|
pos.c(x, y, z);
|
||||||
|
nmsWorld.w(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected WorldServer nmsWorld;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public World getImpWorld() {
|
||||||
|
World world = super.getImpWorld();
|
||||||
|
if (world != null) {
|
||||||
|
this.nmsWorld = ((CraftWorld) world).getHandle();
|
||||||
|
return super.getImpWorld();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||||
|
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||||
|
return (int) fieldNonEmptyBlockCount.get(section);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
fieldSection.set(section, palette);
|
||||||
|
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
|
||||||
|
try {
|
||||||
|
if (array == null) {
|
||||||
|
return new ChunkSection(y2, flag);
|
||||||
|
} else {
|
||||||
|
return new ChunkSection(y2, flag, array);
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
try {
|
||||||
|
if (array == null) {
|
||||||
|
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, IBlockData[].class);
|
||||||
|
return constructor.newInstance(y2, flag, (IBlockData[]) null);
|
||||||
|
} else {
|
||||||
|
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, char[].class, IBlockData[].class);
|
||||||
|
return constructor.newInstance(y2, flag, array, (IBlockData[]) null);
|
||||||
|
}
|
||||||
|
} catch (Throwable e2) {
|
||||||
|
throw new RuntimeException(e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BukkitChunk_1_12 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||||
|
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
|
||||||
|
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
||||||
|
// Copy blocks
|
||||||
|
BukkitChunk_1_12_Copy previous = new BukkitChunk_1_12_Copy(this, fs.getX(), fs.getZ());
|
||||||
|
for (int layer = 0; layer < sections.length; layer++) {
|
||||||
|
if (fs.getCount(layer) != 0 || all) {
|
||||||
|
ChunkSection section = sections[layer];
|
||||||
|
if (section != null) {
|
||||||
|
DataPaletteBlock blocks = section.getBlocks();
|
||||||
|
byte[] ids = new byte[4096];
|
||||||
|
NibbleArray data = new NibbleArray();
|
||||||
|
blocks.exportData(ids, data);
|
||||||
|
previous.set(layer, ids, data.asBytes());
|
||||||
|
short solid = (short) fieldNonEmptyBlockCount.getInt(section);
|
||||||
|
previous.count[layer] = solid;
|
||||||
|
previous.air[layer] = (short) (4096 - solid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Copy tiles
|
||||||
|
if (tiles != null) {
|
||||||
|
for (Map.Entry<BlockPosition, TileEntity> entry : tiles.entrySet()) {
|
||||||
|
TileEntity tile = entry.getValue();
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
BlockPosition pos = entry.getKey();
|
||||||
|
CompoundTag nativeTag = getTag(tile);
|
||||||
|
previous.setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Copy entities
|
||||||
|
if (entities != null) {
|
||||||
|
for (Collection<Entity> entityList : entities) {
|
||||||
|
for (Entity ent : entityList) {
|
||||||
|
if (ent instanceof EntityPlayer || (!createdEntities.isEmpty() && createdEntities.contains(ent.getUniqueID()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int x = ((int) Math.round(ent.locX) & 15);
|
||||||
|
int z = ((int) Math.round(ent.locZ) & 15);
|
||||||
|
int y = ((int) Math.round(ent.locY) & 0xFF);
|
||||||
|
int i = FaweCache.CACHE_I[y][z][x];
|
||||||
|
char[] array = fs.getIdArray(i);
|
||||||
|
if (array == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int j = FaweCache.CACHE_J[y][z][x];
|
||||||
|
if (array[j] != 0) {
|
||||||
|
String id = EntityTypes.b(ent);
|
||||||
|
if (id != null) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
ent.save(tag); // readEntityIntoTag
|
||||||
|
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(adapter, tag);
|
||||||
|
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||||
|
map.put("Id", new StringTag(id));
|
||||||
|
previous.setEntity(nativeTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getTileEntity(net.minecraft.server.v1_12_R1.Chunk chunk, int x, int y, int z) {
|
||||||
|
Map<BlockPosition, TileEntity> tiles = chunk.getTileEntities();
|
||||||
|
pos.c(x, y, z);
|
||||||
|
TileEntity tile = tiles.get(pos);
|
||||||
|
return tile != null ? getTag(tile) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundTag getTag(TileEntity tile) {
|
||||||
|
try {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
tile.save(tag); // readTagIntoEntity
|
||||||
|
return (CompoundTag) methodToNative.invoke(adapter, tag);
|
||||||
|
} catch (Exception e) {
|
||||||
|
MainUtil.handleError(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||||
|
net.minecraft.server.v1_12_R1.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||||
|
c.mustSave = false;
|
||||||
|
if (chunk.isLoaded()) {
|
||||||
|
chunk.unload(false, false);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BukkitChunk_1_12 getFaweChunk(int x, int z) {
|
||||||
|
return new BukkitChunk_1_12(this, x, z);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,333 @@
|
|||||||
|
package com.boydti.fawe.bukkit.v1_12;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.sk89q.jnbt.ByteArrayTag;
|
||||||
|
import com.sk89q.jnbt.ByteTag;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.DoubleTag;
|
||||||
|
import com.sk89q.jnbt.EndTag;
|
||||||
|
import com.sk89q.jnbt.FloatTag;
|
||||||
|
import com.sk89q.jnbt.IntArrayTag;
|
||||||
|
import com.sk89q.jnbt.IntTag;
|
||||||
|
import com.sk89q.jnbt.ListTag;
|
||||||
|
import com.sk89q.jnbt.LongTag;
|
||||||
|
import com.sk89q.jnbt.NBTConstants;
|
||||||
|
import com.sk89q.jnbt.ShortTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import net.minecraft.server.v1_12_R1.BiomeBase;
|
||||||
|
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||||
|
import net.minecraft.server.v1_12_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityTypes;
|
||||||
|
import net.minecraft.server.v1_12_R1.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTBase;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagByte;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagByteArray;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagDouble;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagEnd;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagFloat;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagInt;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagIntArray;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagList;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagLong;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagShort;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagString;
|
||||||
|
import net.minecraft.server.v1_12_R1.TileEntity;
|
||||||
|
import net.minecraft.server.v1_12_R1.World;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldServer;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.block.CraftBlock;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
|
public final class FaweAdapter_1_12 implements BukkitImplAdapter
|
||||||
|
{
|
||||||
|
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||||
|
private final Field nbtListTagListField;
|
||||||
|
private final Method nbtCreateTagMethod;
|
||||||
|
|
||||||
|
public FaweAdapter_1_12() throws NoSuchFieldException, NoSuchMethodException {
|
||||||
|
this.nbtListTagListField = NBTTagList.class.getDeclaredField("list");
|
||||||
|
this.nbtListTagListField.setAccessible(true);
|
||||||
|
|
||||||
|
this.nbtCreateTagMethod = NBTBase.class.getDeclaredMethod("createTag", new Class[] { Byte.TYPE });
|
||||||
|
this.nbtCreateTagMethod.setAccessible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readTagIntoTileEntity(NBTTagCompound tag, TileEntity tileEntity)
|
||||||
|
{
|
||||||
|
tileEntity.a(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readTileEntityIntoTag(TileEntity tileEntity, NBTTagCompound tag)
|
||||||
|
{
|
||||||
|
tileEntity.save(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getEntityId(Entity entity)
|
||||||
|
{
|
||||||
|
return EntityTypes.b(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static Entity createEntityFromId(String id, World world)
|
||||||
|
{
|
||||||
|
return EntityTypes.a(new MinecraftKey(id), world);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readTagIntoEntity(NBTTagCompound tag, Entity entity)
|
||||||
|
{
|
||||||
|
entity.f(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readEntityIntoTag(Entity entity, NBTTagCompound tag)
|
||||||
|
{
|
||||||
|
entity.save(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockId(Material material)
|
||||||
|
{
|
||||||
|
return material.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterial(int id)
|
||||||
|
{
|
||||||
|
return Material.getMaterial(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBiomeId(Biome biome)
|
||||||
|
{
|
||||||
|
BiomeBase mcBiome = CraftBlock.biomeToBiomeBase(biome);
|
||||||
|
return mcBiome != null ? BiomeBase.a(mcBiome) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome getBiome(int id)
|
||||||
|
{
|
||||||
|
BiomeBase mcBiome = BiomeBase.getBiome(id);
|
||||||
|
return CraftBlock.biomeBaseToBiome(mcBiome);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseBlock getBlock(Location location)
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull(location);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = (CraftWorld)location.getWorld();
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
|
||||||
|
Block bukkitBlock = location.getBlock();
|
||||||
|
BaseBlock block = new BaseBlock(bukkitBlock.getTypeId(), bukkitBlock.getData());
|
||||||
|
|
||||||
|
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
|
||||||
|
if (te != null)
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
readTileEntityIntoTag(te, tag);
|
||||||
|
block.setNbtData((CompoundTag)toNative(tag));
|
||||||
|
}
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setBlock(Location location, BaseBlock block, boolean notifyAndLight)
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull(location);
|
||||||
|
Preconditions.checkNotNull(block);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = (CraftWorld)location.getWorld();
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
|
||||||
|
boolean changed = location.getBlock().setTypeIdAndData(block.getId(), (byte)block.getData(), notifyAndLight);
|
||||||
|
|
||||||
|
CompoundTag nativeTag = block.getNbtData();
|
||||||
|
if (nativeTag != null)
|
||||||
|
{
|
||||||
|
TileEntity tileEntity = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
|
||||||
|
if (tileEntity != null)
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = (NBTTagCompound)fromNative(nativeTag);
|
||||||
|
tag.set("x", new NBTTagInt(x));
|
||||||
|
tag.set("y", new NBTTagInt(y));
|
||||||
|
tag.set("z", new NBTTagInt(z));
|
||||||
|
readTagIntoTileEntity(tag, tileEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseEntity getEntity(org.bukkit.entity.Entity entity)
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull(entity);
|
||||||
|
|
||||||
|
CraftEntity craftEntity = (CraftEntity)entity;
|
||||||
|
Entity mcEntity = craftEntity.getHandle();
|
||||||
|
|
||||||
|
String id = getEntityId(mcEntity);
|
||||||
|
if (id != null) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
readEntityIntoTag(mcEntity, tag);
|
||||||
|
CompoundTag weTag = (CompoundTag) toNative(tag);
|
||||||
|
return new BaseEntity(id, weTag);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state)
|
||||||
|
{
|
||||||
|
Preconditions.checkNotNull(location);
|
||||||
|
Preconditions.checkNotNull(state);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = (CraftWorld)location.getWorld();
|
||||||
|
WorldServer worldServer = craftWorld.getHandle();
|
||||||
|
|
||||||
|
Entity createdEntity = createEntityFromId(state.getTypeId(), craftWorld.getHandle());
|
||||||
|
if (createdEntity != null)
|
||||||
|
{
|
||||||
|
CompoundTag nativeTag = state.getNbtData();
|
||||||
|
if (nativeTag != null)
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = (NBTTagCompound)fromNative(nativeTag);
|
||||||
|
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||||
|
tag.remove(name);
|
||||||
|
}
|
||||||
|
readTagIntoEntity(tag, createdEntity);
|
||||||
|
}
|
||||||
|
createdEntity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||||
|
|
||||||
|
worldServer.addEntity(createdEntity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||||
|
return createdEntity.getBukkitEntity();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tag toNative(NBTBase foreign) {
|
||||||
|
if (foreign == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (foreign instanceof NBTTagCompound) {
|
||||||
|
Map<String, Tag> values = new HashMap<String, Tag>();
|
||||||
|
Set<String> foreignKeys = ((NBTTagCompound) foreign).c(); // map.keySet
|
||||||
|
|
||||||
|
for (String str : foreignKeys) {
|
||||||
|
NBTBase base = ((NBTTagCompound) foreign).get(str);
|
||||||
|
values.put(str, toNative(base));
|
||||||
|
}
|
||||||
|
return new CompoundTag(values);
|
||||||
|
} else if (foreign instanceof NBTTagByte) {
|
||||||
|
return new ByteTag(((NBTTagByte) foreign).g()); // getByte
|
||||||
|
} else if (foreign instanceof NBTTagByteArray) {
|
||||||
|
return new ByteArrayTag(((NBTTagByteArray) foreign).c()); // data
|
||||||
|
} else if (foreign instanceof NBTTagDouble) {
|
||||||
|
return new DoubleTag(((NBTTagDouble) foreign).asDouble()); // getDouble
|
||||||
|
} else if (foreign instanceof NBTTagFloat) {
|
||||||
|
return new FloatTag(((NBTTagFloat) foreign).i()); // getFloat
|
||||||
|
} else if (foreign instanceof NBTTagInt) {
|
||||||
|
return new IntTag(((NBTTagInt) foreign).e()); // getInt
|
||||||
|
} else if (foreign instanceof NBTTagIntArray) {
|
||||||
|
return new IntArrayTag(((NBTTagIntArray) foreign).d()); // data
|
||||||
|
} else if (foreign instanceof NBTTagList) {
|
||||||
|
try {
|
||||||
|
return toNativeList((NBTTagList) foreign);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.log(Level.WARNING, "Failed to convert NBTTagList", e);
|
||||||
|
return new ListTag(ByteTag.class, new ArrayList<ByteTag>());
|
||||||
|
}
|
||||||
|
} else if (foreign instanceof NBTTagLong) {
|
||||||
|
return new LongTag(((NBTTagLong) foreign).d()); // getLong
|
||||||
|
} else if (foreign instanceof NBTTagShort) {
|
||||||
|
return new ShortTag(((NBTTagShort) foreign).f()); // getShort
|
||||||
|
} else if (foreign instanceof NBTTagString) {
|
||||||
|
return new StringTag(((NBTTagString) foreign).c_()); // data
|
||||||
|
} else if (foreign instanceof NBTTagEnd) {
|
||||||
|
return new EndTag();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListTag toNativeList(NBTTagList foreign) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||||
|
List<Tag> values = new ArrayList<Tag>();
|
||||||
|
int type = foreign.g();
|
||||||
|
|
||||||
|
List foreignList;
|
||||||
|
foreignList = (List) nbtListTagListField.get(foreign);
|
||||||
|
for (int i = 0; i < foreign.size(); i++) {
|
||||||
|
NBTBase element = (NBTBase) foreignList.get(i);
|
||||||
|
values.add(toNative(element)); // List elements shouldn't have names
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
|
||||||
|
return new ListTag(cls, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBTBase fromNative(Tag foreign) {
|
||||||
|
if (foreign == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (foreign instanceof CompoundTag) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
for (Map.Entry<String, Tag> entry : ((CompoundTag) foreign)
|
||||||
|
.getValue().entrySet()) {
|
||||||
|
tag.set(entry.getKey(), fromNative(entry.getValue()));
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
} else if (foreign instanceof ByteTag) {
|
||||||
|
return new NBTTagByte(((ByteTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof ByteArrayTag) {
|
||||||
|
return new NBTTagByteArray(((ByteArrayTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof DoubleTag) {
|
||||||
|
return new NBTTagDouble(((DoubleTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof FloatTag) {
|
||||||
|
return new NBTTagFloat(((FloatTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof IntTag) {
|
||||||
|
return new NBTTagInt(((IntTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof IntArrayTag) {
|
||||||
|
return new NBTTagIntArray(((IntArrayTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof ListTag) {
|
||||||
|
NBTTagList tag = new NBTTagList();
|
||||||
|
ListTag foreignList = (ListTag) foreign;
|
||||||
|
for (Tag t : foreignList.getValue()) {
|
||||||
|
tag.add(fromNative(t));
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
} else if (foreign instanceof LongTag) {
|
||||||
|
return new NBTTagLong(((LongTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof ShortTag) {
|
||||||
|
return new NBTTagShort(((ShortTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof StringTag) {
|
||||||
|
return new NBTTagString(((StringTag) foreign).getValue());
|
||||||
|
} else if (foreign instanceof EndTag) {
|
||||||
|
try {
|
||||||
|
return (NBTBase) nbtCreateTagMethod.invoke(null, (byte) 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.boydti.fawe.bukkit.v1_12;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import net.minecraft.server.v1_12_R1.GenLayer;
|
||||||
|
import net.minecraft.server.v1_12_R1.IntCache;
|
||||||
|
|
||||||
|
public class MutableGenLayer extends GenLayer {
|
||||||
|
|
||||||
|
private int biome;
|
||||||
|
|
||||||
|
public MutableGenLayer(long seed) {
|
||||||
|
super(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableGenLayer set(int biome) {
|
||||||
|
this.biome = biome;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] a(int areaX, int areaY, int areaWidth, int areaHeight) {
|
||||||
|
int[] biomes = IntCache.a(areaWidth * areaHeight);
|
||||||
|
Arrays.fill(biomes, biome);
|
||||||
|
return biomes;
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ import com.boydti.fawe.object.FawePlayer;
|
|||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||||
import com.boydti.fawe.object.number.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
@ -35,7 +35,7 @@ import com.sk89q.worldedit.command.BrushCommands;
|
|||||||
import com.sk89q.worldedit.command.ChunkCommands;
|
import com.sk89q.worldedit.command.ChunkCommands;
|
||||||
import com.sk89q.worldedit.command.ClipboardCommands;
|
import com.sk89q.worldedit.command.ClipboardCommands;
|
||||||
import com.sk89q.worldedit.command.FlattenedClipboardTransform;
|
import com.sk89q.worldedit.command.FlattenedClipboardTransform;
|
||||||
import com.sk89q.worldedit.command.GeneralCommands;
|
import com.sk89q.worldedit.command.OptionsCommands;
|
||||||
import com.sk89q.worldedit.command.GenerationCommands;
|
import com.sk89q.worldedit.command.GenerationCommands;
|
||||||
import com.sk89q.worldedit.command.HistoryCommands;
|
import com.sk89q.worldedit.command.HistoryCommands;
|
||||||
import com.sk89q.worldedit.command.NavigationCommands;
|
import com.sk89q.worldedit.command.NavigationCommands;
|
||||||
@ -46,7 +46,7 @@ import com.sk89q.worldedit.command.SnapshotCommands;
|
|||||||
import com.sk89q.worldedit.command.SnapshotUtilCommands;
|
import com.sk89q.worldedit.command.SnapshotUtilCommands;
|
||||||
import com.sk89q.worldedit.command.SuperPickaxeCommands;
|
import com.sk89q.worldedit.command.SuperPickaxeCommands;
|
||||||
import com.sk89q.worldedit.command.ToolCommands;
|
import com.sk89q.worldedit.command.ToolCommands;
|
||||||
import com.sk89q.worldedit.command.ToolUtilCommands;
|
import com.sk89q.worldedit.command.BrushOptionsCommands;
|
||||||
import com.sk89q.worldedit.command.UtilityCommands;
|
import com.sk89q.worldedit.command.UtilityCommands;
|
||||||
import com.sk89q.worldedit.command.WorldEditCommands;
|
import com.sk89q.worldedit.command.WorldEditCommands;
|
||||||
import com.sk89q.worldedit.command.composition.SelectionCommand;
|
import com.sk89q.worldedit.command.composition.SelectionCommand;
|
||||||
@ -77,6 +77,8 @@ import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
|||||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||||
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
|
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
|
||||||
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
|
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.FuzzyBlockMask;
|
import com.sk89q.worldedit.function.mask.FuzzyBlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
@ -87,6 +89,7 @@ import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
|||||||
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
@ -115,6 +118,7 @@ import com.sk89q.worldedit.session.PasteBuilder;
|
|||||||
import com.sk89q.worldedit.session.SessionManager;
|
import com.sk89q.worldedit.session.SessionManager;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
import com.sk89q.worldedit.session.request.Request;
|
||||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||||
|
import com.sk89q.worldedit.util.command.fluent.DispatcherNode;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
|
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
|
||||||
@ -133,6 +137,7 @@ import java.lang.management.MemoryUsage;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -423,8 +428,6 @@ public class Fawe {
|
|||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
// Setting up commands.yml
|
// Setting up commands.yml
|
||||||
Commands.load(new File(INSTANCE.IMP.getDirectory(), "commands.yml"));
|
|
||||||
Commands.inject(); // Translations
|
|
||||||
EditSession.inject(); // Custom block placer + optimizations
|
EditSession.inject(); // Custom block placer + optimizations
|
||||||
EditSessionEvent.inject(); // Add EditSession to event (API)
|
EditSessionEvent.inject(); // Add EditSession to event (API)
|
||||||
LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk / brush visualization
|
LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk / brush visualization
|
||||||
@ -433,6 +436,8 @@ public class Fawe {
|
|||||||
AbstractPlayerActor.inject(); // Don't use exception for getBlockInHand control flow
|
AbstractPlayerActor.inject(); // Don't use exception for getBlockInHand control flow
|
||||||
Request.inject(); // Custom pattern extent
|
Request.inject(); // Custom pattern extent
|
||||||
// Commands
|
// Commands
|
||||||
|
Commands.load(new File(INSTANCE.IMP.getDirectory(), "commands.yml"));
|
||||||
|
Commands.inject(); // Translations
|
||||||
BiomeCommands.inject(); // Translations + Optimizations
|
BiomeCommands.inject(); // Translations + Optimizations
|
||||||
ChunkCommands.inject(); // Translations + Optimizations
|
ChunkCommands.inject(); // Translations + Optimizations
|
||||||
GenerationCommands.inject(); // Translations + Optimizations
|
GenerationCommands.inject(); // Translations + Optimizations
|
||||||
@ -453,8 +458,9 @@ public class Fawe {
|
|||||||
ParametricBuilder.inject(); // Translations
|
ParametricBuilder.inject(); // Translations
|
||||||
ParametricCallable.inject(); // Translations
|
ParametricCallable.inject(); // Translations
|
||||||
ParameterData.inject(); // Translations
|
ParameterData.inject(); // Translations
|
||||||
ToolUtilCommands.inject(); // Fixes + Translations
|
BrushOptionsCommands.inject(); // Fixes + Translations
|
||||||
GeneralCommands.inject(); // Translations + gmask args
|
OptionsCommands.inject(); // Translations + gmask args
|
||||||
|
DispatcherNode.inject(); // Method command delegate
|
||||||
// Formatting
|
// Formatting
|
||||||
MessageBox.inject();
|
MessageBox.inject();
|
||||||
Fragment.inject();
|
Fragment.inject();
|
||||||
@ -521,6 +527,7 @@ public class Fawe {
|
|||||||
HashTagPatternParser.inject(); // Add new patterns
|
HashTagPatternParser.inject(); // Add new patterns
|
||||||
DefaultBlockParser.inject(); // Fix block lookups
|
DefaultBlockParser.inject(); // Fix block lookups
|
||||||
BlockPattern.inject(); // Optimization
|
BlockPattern.inject(); // Optimization
|
||||||
|
AbstractPattern.inject();
|
||||||
// Mask
|
// Mask
|
||||||
Mask.inject(); // Extend deprecated mask
|
Mask.inject(); // Extend deprecated mask
|
||||||
BlockMask.inject(); // Optimizations
|
BlockMask.inject(); // Optimizations
|
||||||
@ -530,6 +537,8 @@ public class Fawe {
|
|||||||
DefaultMaskParser.inject(); // Add new masks
|
DefaultMaskParser.inject(); // Add new masks
|
||||||
Masks.inject(); // Optimizations
|
Masks.inject(); // Optimizations
|
||||||
MaskUnion.inject(); // Optimizations
|
MaskUnion.inject(); // Optimizations
|
||||||
|
AbstractMask.inject(); // Serializing
|
||||||
|
AbstractExtentMask.inject(); // Serializing
|
||||||
// Operations
|
// Operations
|
||||||
Operations.inject(); // Optimizations
|
Operations.inject(); // Optimizations
|
||||||
ExtentBlockCopy.inject(); // Optimizations
|
ExtentBlockCopy.inject(); // Optimizations
|
||||||
@ -688,19 +697,26 @@ public class Fawe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ConcurrentHashMap<String, FawePlayer> players = new ConcurrentHashMap<>(8, 0.9f, 1);
|
private ConcurrentHashMap<String, FawePlayer> players = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||||
|
private ConcurrentHashMap<UUID, FawePlayer> playersUUID = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||||
|
|
||||||
public <T> void register(FawePlayer<T> player) {
|
public <T> void register(FawePlayer<T> player) {
|
||||||
players.put(player.getName(), player);
|
players.put(player.getName(), player);
|
||||||
|
playersUUID.put(player.getUUID(), player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void unregister(String name) {
|
public <T> void unregister(String name) {
|
||||||
players.remove(name);
|
FawePlayer player = players.remove(name);
|
||||||
|
if (player != null) playersUUID.remove(player.getUUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public FawePlayer getCachedPlayer(String name) {
|
public FawePlayer getCachedPlayer(String name) {
|
||||||
return players.get(name);
|
return players.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FawePlayer getCachedPlayer(UUID uuid) {
|
||||||
|
return playersUUID.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<FawePlayer> getCachedPlayers() {
|
public Collection<FawePlayer> getCachedPlayers() {
|
||||||
return players.values();
|
return players.values();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@Command(aliases = "/anvil", desc = "Manipulate billions of blocks: [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Anvil-API)")
|
@Command(aliases = {"anvil", "/anvil"}, desc = "Manipulate billions of blocks: [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Anvil-API)")
|
||||||
public class AnvilCommands {
|
public class AnvilCommands {
|
||||||
|
|
||||||
private final WorldEdit worldEdit;
|
private final WorldEdit worldEdit;
|
||||||
|
@ -109,35 +109,18 @@ public enum BBC {
|
|||||||
BRUSH_RESET("Reset your brush.", "WorldEdit.Brush"),
|
BRUSH_RESET("Reset your brush.", "WorldEdit.Brush"),
|
||||||
BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"),
|
BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"),
|
||||||
BRUSH_SCROLL_ACTION_SET("Set scroll action to %s0", "WorldEdit.Brush"),
|
BRUSH_SCROLL_ACTION_SET("Set scroll action to %s0", "WorldEdit.Brush"),
|
||||||
|
BRUSH_SCROLL_ACTION_UNSET("Removed scrol action", "WorldEdit.Brush"),
|
||||||
BRUSH_VISUAL_MODE_SET("Set visual mode to %s0", "WorldEdit.Brush"),
|
BRUSH_VISUAL_MODE_SET("Set visual mode to %s0", "WorldEdit.Brush"),
|
||||||
BRUSH_TARGET_MODE_SET("Set target mode to %s0", "WorldEdit.Brush"),
|
BRUSH_TARGET_MODE_SET("Set target mode to %s0", "WorldEdit.Brush"),
|
||||||
BRUSH_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"),
|
BRUSH_EQUIPPED("Equipped brush %s0", "WorldEdit.Brush"),
|
||||||
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
|
|
||||||
BRUSH_CYLINDER("Cylinder brush shape equipped (%s0 by %s1).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_EXTINGUISHER("Extinguisher equipped (%s0).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_GRAVITY("Gravity brush equipped (%s0)", "WorldEdit.Brush"),
|
|
||||||
BRUSH_HEIGHT("Height brush equipped (%s0)", "WorldEdit.Brush"),
|
|
||||||
BRUSH_TRY_OTHER("&cThere are other more suitable brushes e.g.\n&8 - &7//br height [radius=5] [#clipboard|file=null] [rotation=0] [yscale=1.00]", "WorldEdit.Brush"),
|
BRUSH_TRY_OTHER("&cThere are other more suitable brushes e.g.\n&8 - &7//br height [radius=5] [#clipboard|file=null] [rotation=0] [yscale=1.00]", "WorldEdit.Brush"),
|
||||||
BRUSH_COPY("Copy brush equipped (%s0). Left click the base of an object to copy, right click to paste. Increase the brush radius if necessary.", "WorldEdit.Brush"),
|
BRUSH_COPY("Left click the base of an object to copy, right click to paste. Increase the brush radius if necessary.", "WorldEdit.Brush"),
|
||||||
BRUSH_COMMAND("Command brush equipped (%s0)", "WorldEdit.Brush"),
|
|
||||||
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
|
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
|
||||||
BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2. Note: Use the blend brush if you want to smooth overhangs or caves.).", "WorldEdit.Brush"),
|
BRUSH_SMOOTH("Note: Use the blend brush if you want to smooth overhangs or caves.", "WorldEdit.Brush"),
|
||||||
BRUSH_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"),
|
BRUSH_SPLINE("Click to add a point, click the same spot to finish", "WorldEdit.Brush"),
|
||||||
BRUSH_SCATTER("Scatter brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_SHATTER("Shatter brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_POPULATE("Populate brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_LAYER("Layer brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_STENCIL("Stencil brush equipped (%s0).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_SURFACE("Surface brush equipped (%s0).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_LINE("Line brush shape equipped (%s0).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_SPLINE("Spline brush shape equipped (%s0). Right click an end to add a shape", "WorldEdit.Brush"),
|
|
||||||
BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"),
|
BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"),
|
||||||
BRUSH_BLEND_BALL("Blend ball brush equipped (%s0).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_ERODE("Erode brush equipped (%s0). Right click to erode, left click to pull.", "WorldEdit.Brush"),
|
|
||||||
BRUSH_CIRCLE("Circle brush equipped (%s0). Right click to create a circle.", "WorldEdit.Brush"),
|
|
||||||
BRUSH_RECURSIVE("Recursive brush equipped (%s0).", "WorldEdit.Brush"),
|
|
||||||
BRUSH_SIZE("Brush size set", "WorldEdit.Brush"),
|
BRUSH_SIZE("Brush size set", "WorldEdit.Brush"),
|
||||||
BRUSH_RANGE("Brush size set", "WorldEdit.Brush"),
|
BRUSH_RANGE("Brush size set", "WorldEdit.Brush"),
|
||||||
BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"),
|
BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"),
|
||||||
@ -190,12 +173,13 @@ public enum BBC {
|
|||||||
|
|
||||||
|
|
||||||
SCHEMATIC_DELETE("%s0 has been deleted.", "Worldedit.Schematic"),
|
SCHEMATIC_DELETE("%s0 has been deleted.", "Worldedit.Schematic"),
|
||||||
SCHEMATIC_FORMAT("Available clipboard formats (Name: Lookup names)", "Worldedit.Schematic"),
|
SCHEMATIC_FORMAT("Available formats (Name: Lookup names)", "Worldedit.Schematic"),
|
||||||
SCHEMATIC_LOADED("%s0 loaded. Paste it with //paste", "Worldedit.Schematic"),
|
SCHEMATIC_LOADED("%s0 loaded. Paste it with //paste", "Worldedit.Schematic"),
|
||||||
SCHEMATIC_SAVED("%s0 saved.", "Worldedit.Schematic"),
|
SCHEMATIC_SAVED("%s0 saved.", "Worldedit.Schematic"),
|
||||||
SCHEMATIC_PAGE("Page must be %s", "WorldEdit.Schematic"),
|
SCHEMATIC_PAGE("Page must be %s", "WorldEdit.Schematic"),
|
||||||
SCHEMATIC_NONE("No schematics found.", "WorldEdit.Schematic"),
|
SCHEMATIC_NONE("No files found.", "WorldEdit.Schematic"),
|
||||||
SCHEMATIC_LIST("Available schematics (Filename: Format) [%s0/%s1]:", "Worldedit.Schematic"),
|
SCHEMATIC_LIST("Available files (Filename: Format) [%s0/%s1]:", "Worldedit.Schematic"),
|
||||||
|
SCHEMATIC_LIST_ELEM("&8 - &a%s0 &8- &7%s1", "Worldedit.Schematic"),
|
||||||
|
|
||||||
CLIPBOARD_CLEARED("Clipboard cleared", "WorldEdit.Clipboard"),
|
CLIPBOARD_CLEARED("Clipboard cleared", "WorldEdit.Clipboard"),
|
||||||
CLIPBOARD_INVALID_FORMAT("Unknown clipboard format: %s0", "WorldEdit.Clipboard"),
|
CLIPBOARD_INVALID_FORMAT("Unknown clipboard format: %s0", "WorldEdit.Clipboard"),
|
||||||
@ -232,6 +216,8 @@ public enum BBC {
|
|||||||
COMMAND_SYNTAX("&cUsage: &7%s0", "Error"),
|
COMMAND_SYNTAX("&cUsage: &7%s0", "Error"),
|
||||||
NO_PERM("&cYou are lacking the permission node: %s0", "Error"),
|
NO_PERM("&cYou are lacking the permission node: %s0", "Error"),
|
||||||
SETTING_DISABLE("&cLacking setting: %s0","Error"),
|
SETTING_DISABLE("&cLacking setting: %s0","Error"),
|
||||||
|
BRUSH_NOT_FOUND("&cAvailable brushes: %s0", "Error"),
|
||||||
|
BRUSH_INCOMPATIBLE("&cBrush not compatible with this version", "Error"),
|
||||||
SCHEMATIC_NOT_FOUND("&cSchematic not found: &7%s0", "Error"),
|
SCHEMATIC_NOT_FOUND("&cSchematic not found: &7%s0", "Error"),
|
||||||
NO_REGION("&cYou have no current allowed region", "Error"),
|
NO_REGION("&cYou have no current allowed region", "Error"),
|
||||||
NO_MASK("&cYou have no current mask set", "Error"),
|
NO_MASK("&cYou have no current mask set", "Error"),
|
||||||
@ -316,16 +302,6 @@ public enum BBC {
|
|||||||
TIP_ROTATE("Tip: Orientate with &c//rotate", "Tips"),
|
TIP_ROTATE("Tip: Orientate with &c//rotate", "Tips"),
|
||||||
TIP_COPY_PATTERN("Tip: To use as a pattern try &c#copy", "Tips"),
|
TIP_COPY_PATTERN("Tip: To use as a pattern try &c#copy", "Tips"),
|
||||||
|
|
||||||
// brush
|
|
||||||
TIP_BRUSH_SPLINE("&7Tip The spline &c//brush &7connects multiple shapes together", "Tips"),
|
|
||||||
TIP_BRUSH_HEIGHT("&7Tip: The height &c//brush &7smoothly raises or lowers terrain", "Tips"),
|
|
||||||
TIP_BRUSH_COPY("&7Tip: The copypaste &c//brush &7allows you to easily copy and paste objects", "Tips"),
|
|
||||||
TIP_BRUSH_MASK("&7Tip: Set a brush destination mask with &c/mask", "Tips"),
|
|
||||||
TIP_BRUSH_MASK_SOURCE("&7Tip: Set a brush source mask with &c/smask", "Tips"),
|
|
||||||
TIP_BRUSH_TRANSFORM("&7Tip: Set a brush transform with &c/transform", "Tips"),
|
|
||||||
TIP_BRUSH_RELATIVE("&7Tip: Use a relative clipboard pattern with //br sphere #~[#copy]", "Tips"),
|
|
||||||
TIP_BRUSH_COMMAND("&7Tip: Try the command brush &c//br cmd <radius> <cmd1;cmd2>", "Tips"),
|
|
||||||
|
|
||||||
// regen
|
// regen
|
||||||
TIP_REGEN_0("Tip: Use a biome with /regen [biome]", "Tips"),
|
TIP_REGEN_0("Tip: Use a biome with /regen [biome]", "Tips"),
|
||||||
TIP_REGEN_1("Tip: Use a seed with /regen [biome] [seed]", "Tips"),
|
TIP_REGEN_1("Tip: Use a seed with /regen [biome] [seed]", "Tips"),
|
||||||
|
@ -323,13 +323,13 @@ public class Settings extends Config {
|
|||||||
@Comment("Enable the limiter")
|
@Comment("Enable the limiter")
|
||||||
public boolean ENABLED = true;
|
public boolean ENABLED = true;
|
||||||
@Comment("The interval in ticks")
|
@Comment("The interval in ticks")
|
||||||
public int INTERVAL = 1;
|
public int INTERVAL = 20;
|
||||||
@Comment("Max falling blocks per interval (per chunk)")
|
@Comment("Max falling blocks per interval (per chunk)")
|
||||||
public int FALLING = 512;
|
public int FALLING = 64;
|
||||||
@Comment("Max physics per interval (per chunk)")
|
@Comment("Max physics per interval (per chunk)")
|
||||||
public int PHYSICS = 512;
|
public int PHYSICS = 8192;
|
||||||
@Comment("Max item spawns per interval (per chunk)")
|
@Comment("Max item spawns per interval (per chunk)")
|
||||||
public int ITEMS = 128;
|
public int ITEMS = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CLIPBOARD {
|
public static class CLIPBOARD {
|
||||||
|
@ -1,18 +1,238 @@
|
|||||||
package com.boydti.fawe.object.brush;
|
package com.boydti.fawe.object.brush;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.object.brush.scroll.ScrollAction;
|
import com.boydti.fawe.object.brush.scroll.ScrollAction;
|
||||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
import com.sk89q.worldedit.LocalSession;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||||
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.util.command.CommandCallable;
|
||||||
|
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||||
|
import com.sk89q.worldedit.util.command.ProcessedCallable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class BrushSettings {
|
public class BrushSettings {
|
||||||
public Brush brush = null;
|
public enum SettingType {
|
||||||
public Mask mask = null;
|
BRUSH,
|
||||||
public Mask sourceMask = null;
|
SIZE,
|
||||||
public ResettableExtent transform = null;
|
MASK,
|
||||||
public Pattern material;
|
SOURCE_MASK,
|
||||||
public double size = 1;
|
TRANSFORM,
|
||||||
public String permission;
|
FILL,
|
||||||
public ScrollAction scrollAction;
|
PERMISSIONS,
|
||||||
|
SCROLL_ACTION,
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<SettingType, Object> constructor = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private Brush brush = null;
|
||||||
|
private Mask mask = null;
|
||||||
|
private Mask sourceMask = null;
|
||||||
|
private ResettableExtent transform = null;
|
||||||
|
private Pattern material;
|
||||||
|
private double size = 1;
|
||||||
|
private Set<String> permissions;
|
||||||
|
private ScrollAction scrollAction;
|
||||||
|
|
||||||
|
public BrushSettings() {
|
||||||
|
this.permissions = new HashSet<>();
|
||||||
|
this.constructor.put(SettingType.PERMISSIONS, permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BrushSettings get(BrushTool tool, Player player, LocalSession session, Map<String, Object> settings) throws CommandException, InputParseException {
|
||||||
|
Dispatcher dispatcher = CommandManager.getInstance().getDispatcher();
|
||||||
|
Dispatcher brushDispatcher = (Dispatcher) (dispatcher.get("brush").getCallable());
|
||||||
|
if (brushDispatcher == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String constructor = (String) settings.get(SettingType.BRUSH.name());
|
||||||
|
if (constructor == null) {
|
||||||
|
return new BrushSettings();
|
||||||
|
}
|
||||||
|
String[] split = constructor.split(" ");
|
||||||
|
|
||||||
|
CommandCallable sphereCommand = ((ProcessedCallable) brushDispatcher.get(split[0]).getCallable()).getParent();
|
||||||
|
CommandLocals locals = new CommandLocals();
|
||||||
|
locals.put(Actor.class, player);
|
||||||
|
String args = constructor.substring(constructor.indexOf(' ') + 1);
|
||||||
|
String[] parentArgs = new String[]{"brush", split[0]};
|
||||||
|
BrushSettings bs = (BrushSettings) sphereCommand.call(args, locals, parentArgs);
|
||||||
|
if (settings.containsKey(SettingType.PERMISSIONS.name())) {
|
||||||
|
bs.permissions.addAll((Collection<? extends String>) settings.get(SettingType.PERMISSIONS.name()));
|
||||||
|
}
|
||||||
|
if (settings.containsKey(SettingType.SIZE.name())) {
|
||||||
|
bs.size = (double) settings.get(SettingType.SIZE.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserContext parserContext = new ParserContext();
|
||||||
|
parserContext.setActor(player);
|
||||||
|
parserContext.setWorld(player.getWorld());
|
||||||
|
parserContext.setSession(session);
|
||||||
|
|
||||||
|
if (settings.containsKey(SettingType.MASK.name())) {
|
||||||
|
String maskArgs = (String) settings.get(SettingType.MASK.name());
|
||||||
|
Mask mask = WorldEdit.getInstance().getMaskFactory().parseFromInput(maskArgs, parserContext);
|
||||||
|
bs.setMask(mask);
|
||||||
|
bs.constructor.put(SettingType.MASK, maskArgs);
|
||||||
|
}
|
||||||
|
if (settings.containsKey(SettingType.SOURCE_MASK.name())) {
|
||||||
|
String maskArgs = (String) settings.get(SettingType.SOURCE_MASK.name());
|
||||||
|
Mask mask = WorldEdit.getInstance().getMaskFactory().parseFromInput(maskArgs, parserContext);
|
||||||
|
bs.setSourceMask(mask);
|
||||||
|
bs.constructor.put(SettingType.SOURCE_MASK, maskArgs);
|
||||||
|
}
|
||||||
|
if (settings.containsKey(SettingType.TRANSFORM.name())) {
|
||||||
|
String transformArgs = (String) settings.get(SettingType.TRANSFORM.name());
|
||||||
|
ResettableExtent extent = Fawe.get().getTransformParser().parseFromInput(transformArgs, parserContext);
|
||||||
|
bs.setTransform(extent);
|
||||||
|
bs.constructor.put(SettingType.TRANSFORM, transformArgs);
|
||||||
|
}
|
||||||
|
if (settings.containsKey(SettingType.FILL.name())) {
|
||||||
|
String fillArgs = (String) settings.get(SettingType.FILL.name());
|
||||||
|
Pattern pattern = WorldEdit.getInstance().getPatternFactory().parseFromInput(fillArgs, parserContext);
|
||||||
|
bs.setFill(pattern);
|
||||||
|
bs.constructor.put(SettingType.FILL, fillArgs);
|
||||||
|
}
|
||||||
|
if (settings.containsKey(SettingType.SCROLL_ACTION.name())) {
|
||||||
|
String actionArgs = (String) settings.get(SettingType.SCROLL_ACTION.name());
|
||||||
|
ScrollAction action = ScrollAction.fromArguments(tool, player, session, actionArgs, false);
|
||||||
|
if (action != null) {
|
||||||
|
bs.setScrollAction(action);
|
||||||
|
bs.constructor.put(SettingType.SCROLL_ACTION, actionArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setBrush(Brush brush) {
|
||||||
|
this.brush = brush;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings clear() {
|
||||||
|
brush = null;
|
||||||
|
mask = null;
|
||||||
|
sourceMask = null;
|
||||||
|
transform = null;
|
||||||
|
material = null;
|
||||||
|
scrollAction = null;
|
||||||
|
size = 1;
|
||||||
|
permissions.clear();
|
||||||
|
constructor.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings addSetting(SettingType type, String args) {
|
||||||
|
constructor.put(type, args);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<SettingType, Object> getSettings() {
|
||||||
|
return Collections.unmodifiableMap(constructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setMask(Mask mask) {
|
||||||
|
if (mask == null) constructor.remove(SettingType.MASK);
|
||||||
|
this.mask = mask;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setSourceMask(Mask mask) {
|
||||||
|
if (mask == null) constructor.remove(SettingType.SOURCE_MASK);
|
||||||
|
this.sourceMask = mask;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setTransform(ResettableExtent transform) {
|
||||||
|
if (transform == null) constructor.remove(SettingType.TRANSFORM);
|
||||||
|
this.transform = transform;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setFill(Pattern pattern) {
|
||||||
|
if (pattern == null) constructor.remove(SettingType.FILL);
|
||||||
|
this.material = pattern;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setSize(double size) {
|
||||||
|
this.size = size;
|
||||||
|
if (size == -1) {
|
||||||
|
constructor.remove(SettingType.SIZE);
|
||||||
|
} else {
|
||||||
|
constructor.put(SettingType.SIZE, size);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings setScrollAction(ScrollAction scrollAction) {
|
||||||
|
if (scrollAction == null) constructor.remove(SettingType.SCROLL_ACTION);
|
||||||
|
this.scrollAction = scrollAction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings addPermission(String permission) {
|
||||||
|
this.permissions.add(permission);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BrushSettings addPermissions(String... perms) {
|
||||||
|
for (String perm : perms) permissions.add(perm);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush getBrush() {
|
||||||
|
return brush;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mask getMask() {
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mask getSourceMask() {
|
||||||
|
return sourceMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResettableExtent getTransform() {
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pattern getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getPermissions() {
|
||||||
|
return Collections.unmodifiableSet(permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScrollAction getScrollAction() {
|
||||||
|
return scrollAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canUse(Actor actor) {
|
||||||
|
for (String perm : getPermissions()) {
|
||||||
|
if (actor.hasPermission(perm)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,81 @@
|
|||||||
package com.boydti.fawe.object.brush.scroll;
|
package com.boydti.fawe.object.brush.scroll;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.sk89q.worldedit.LocalConfiguration;
|
||||||
|
import com.sk89q.worldedit.LocalSession;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public abstract class ScrollAction implements ScrollTool {
|
public abstract class ScrollAction implements ScrollTool {
|
||||||
private BrushTool tool;
|
private BrushTool tool;
|
||||||
|
|
||||||
|
public static ScrollAction fromArguments(BrushTool tool, Player player, LocalSession session, String arguments, boolean message) throws InputParseException {
|
||||||
|
ParserContext parserContext = new ParserContext();
|
||||||
|
parserContext.setActor(player);
|
||||||
|
parserContext.setWorld(player.getWorld());
|
||||||
|
parserContext.setSession(session);
|
||||||
|
final LocalConfiguration config = WorldEdit.getInstance().getConfiguration();
|
||||||
|
String[] split = arguments.split(" ");
|
||||||
|
switch (split[0].toLowerCase()) {
|
||||||
|
case "none":
|
||||||
|
return null;
|
||||||
|
case "clipboard":
|
||||||
|
if (split.length != 2) {
|
||||||
|
if (message) BBC.COMMAND_SYNTAX.send(player, "clipboard [file]");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String filename = split[1];
|
||||||
|
try {
|
||||||
|
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, message);
|
||||||
|
if (clipboards == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (new ScrollClipboard(tool, session, clipboards));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
case "mask":
|
||||||
|
if (split.length < 2) {
|
||||||
|
if (message) BBC.COMMAND_SYNTAX.send(player, "mask [mask 1] [mask 2] [mask 3]...");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Mask[] masks = new Mask[split.length - 1];
|
||||||
|
for (int i = 1; i < split.length; i++) {
|
||||||
|
String arg = split[i];
|
||||||
|
masks[i - 1] = WorldEdit.getInstance().getMaskFactory().parseFromInput(arg, parserContext);
|
||||||
|
}
|
||||||
|
return (new ScrollMask(tool, masks));
|
||||||
|
case "pattern":
|
||||||
|
if (split.length < 2) {
|
||||||
|
if (message) BBC.COMMAND_SYNTAX.send(player, "pattern [pattern 1] [pattern 2] [pattern 3]...");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Pattern[] patterns = new Pattern[split.length - 1];
|
||||||
|
for (int i = 1; i < split.length; i++) {
|
||||||
|
String arg = split[i];
|
||||||
|
patterns[i - 1] = WorldEdit.getInstance().getPatternFactory().parseFromInput(arg, parserContext);
|
||||||
|
}
|
||||||
|
return (new ScrollPattern(tool, patterns));
|
||||||
|
case "range":
|
||||||
|
return (new ScrollRange(tool));
|
||||||
|
case "size":
|
||||||
|
return (new ScrollSize(tool));
|
||||||
|
case "target":
|
||||||
|
return (new ScrollTarget(tool));
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ScrollAction(BrushTool tool) {
|
public ScrollAction(BrushTool tool) {
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
|||||||
|
|
||||||
public class BlockTranslateExtent extends AbstractDelegateExtent {
|
public class BlockTranslateExtent extends AbstractDelegateExtent {
|
||||||
private final int dx,dy,dz;
|
private final int dx,dy,dz;
|
||||||
private final Extent extent;
|
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
private MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
public BlockTranslateExtent(Extent extent, int dx, int dy, int dz) {
|
public BlockTranslateExtent(Extent extent, int dx, int dy, int dz) {
|
||||||
@ -19,7 +18,6 @@ public class BlockTranslateExtent extends AbstractDelegateExtent {
|
|||||||
this.dx = dx;
|
this.dx = dx;
|
||||||
this.dy = dy;
|
this.dy = dy;
|
||||||
this.dz = dz;
|
this.dz = dz;
|
||||||
this.extent = extent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,7 +25,7 @@ public class BlockTranslateExtent extends AbstractDelegateExtent {
|
|||||||
mutable.mutX((location.getX() + dx));
|
mutable.mutX((location.getX() + dx));
|
||||||
mutable.mutY((location.getY() + dy));
|
mutable.mutY((location.getY() + dy));
|
||||||
mutable.mutZ((location.getZ() + dz));
|
mutable.mutZ((location.getZ() + dz));
|
||||||
return extent.setBlock(mutable, block);
|
return getExtent().setBlock(mutable, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -35,7 +33,7 @@ public class BlockTranslateExtent extends AbstractDelegateExtent {
|
|||||||
mutable.mutX(x + dx);
|
mutable.mutX(x + dx);
|
||||||
mutable.mutY(y + dy);
|
mutable.mutY(y + dy);
|
||||||
mutable.mutZ(z + dz);
|
mutable.mutZ(z + dz);
|
||||||
return extent.setBlock(mutable, block);
|
return getExtent().setBlock(mutable, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,17 +2,13 @@ package com.boydti.fawe.object.extent;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class Linear3DTransform extends SelectTransform {
|
public class Linear3DTransform extends SelectTransform {
|
||||||
|
|
||||||
private final Collection<ResettableExtent> extents;
|
|
||||||
private final ResettableExtent[] extentsArray;
|
private final ResettableExtent[] extentsArray;
|
||||||
|
|
||||||
public Linear3DTransform(ResettableExtent[] extents) {
|
public Linear3DTransform(ResettableExtent[] extents) {
|
||||||
this.extentsArray = extents;
|
this.extentsArray = extents;
|
||||||
this.extents = Arrays.asList(extents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,18 +2,14 @@ package com.boydti.fawe.object.extent;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class LinearTransform extends SelectTransform {
|
public class LinearTransform extends SelectTransform {
|
||||||
|
|
||||||
private final Collection<ResettableExtent> extents;
|
|
||||||
private final ResettableExtent[] extentsArray;
|
private final ResettableExtent[] extentsArray;
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
public LinearTransform(ResettableExtent[] extents) {
|
public LinearTransform(ResettableExtent[] extents) {
|
||||||
this.extentsArray = extents;
|
this.extentsArray = extents;
|
||||||
this.extents = Arrays.asList(extents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -13,20 +13,20 @@ import java.util.Collection;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class MultiTransform extends RandomTransform {
|
public class MultiTransform extends RandomTransform {
|
||||||
private AbstractDelegateExtent[] extents;
|
private ResettableExtent[] extents;
|
||||||
|
|
||||||
public MultiTransform(Collection<ResettableExtent> extents) {
|
public MultiTransform(Collection<ResettableExtent> extents) {
|
||||||
for (ResettableExtent extent : extents) add(extent, 1);
|
for (ResettableExtent extent : extents) add(extent, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiTransform() {
|
public MultiTransform() {
|
||||||
this.extents = new AbstractDelegateExtent[0];
|
this.extents = new ResettableExtent[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(ResettableExtent extent, double chance) {
|
public void add(ResettableExtent extent, double chance) {
|
||||||
super.add(extent, chance);
|
super.add(extent, chance);
|
||||||
this.extents = getExtents().toArray(new AbstractDelegateExtent[getExtents().size()]);
|
this.extents = getExtents().toArray(new ResettableExtent[getExtents().size()]);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||||
|
@ -10,7 +10,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
|||||||
|
|
||||||
public class OffsetExtent extends ResettableExtent {
|
public class OffsetExtent extends ResettableExtent {
|
||||||
private final int dx, dy, dz;
|
private final int dx, dy, dz;
|
||||||
private MutableBlockVector2D mutable = new MutableBlockVector2D();
|
private transient MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||||
|
|
||||||
public OffsetExtent(Extent parent, int dx, int dy, int dz) {
|
public OffsetExtent(Extent parent, int dx, int dy, int dz) {
|
||||||
super(parent);
|
super(parent);
|
||||||
@ -33,4 +33,10 @@ public class OffsetExtent extends ResettableExtent {
|
|||||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||||
return getExtent().setBlock(x + dx, y + dy, z + dz, block);
|
return getExtent().setBlock(x + dx, y + dy, z + dz, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResettableExtent setExtent(Extent extent) {
|
||||||
|
mutable = new MutableBlockVector2D();
|
||||||
|
return super.setExtent(extent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
|||||||
|
|
||||||
public class PositionTransformExtent extends ResettableExtent {
|
public class PositionTransformExtent extends ResettableExtent {
|
||||||
|
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
private transient Vector min;
|
||||||
private Transform transform;
|
private Transform transform;
|
||||||
private Vector min;
|
|
||||||
|
|
||||||
public PositionTransformExtent(Extent parent, Transform transform) {
|
public PositionTransformExtent(Extent parent, Transform transform) {
|
||||||
super(parent);
|
super(parent);
|
||||||
@ -22,6 +22,7 @@ public class PositionTransformExtent extends ResettableExtent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResettableExtent setExtent(Extent extent) {
|
public ResettableExtent setExtent(Extent extent) {
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
min = null;
|
min = null;
|
||||||
return super.setExtent(extent);
|
return super.setExtent(extent);
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,10 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
|||||||
import java.util.SplittableRandom;
|
import java.util.SplittableRandom;
|
||||||
|
|
||||||
public class RandomOffsetTransform extends ResettableExtent {
|
public class RandomOffsetTransform extends ResettableExtent {
|
||||||
|
private transient SplittableRandom random;
|
||||||
|
private transient MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||||
|
|
||||||
private final int dx, dy, dz;
|
private final int dx, dy, dz;
|
||||||
private final SplittableRandom random;
|
|
||||||
private MutableBlockVector2D mutable = new MutableBlockVector2D();
|
|
||||||
|
|
||||||
public RandomOffsetTransform(Extent parent, int dx, int dy, int dz) {
|
public RandomOffsetTransform(Extent parent, int dx, int dy, int dz) {
|
||||||
super(parent);
|
super(parent);
|
||||||
@ -47,6 +48,8 @@ public class RandomOffsetTransform extends ResettableExtent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResettableExtent setExtent(Extent extent) {
|
public ResettableExtent setExtent(Extent extent) {
|
||||||
|
random = new SplittableRandom();
|
||||||
|
mutable = new MutableBlockVector2D();
|
||||||
return super.setExtent(extent);
|
return super.setExtent(extent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public class RandomTransform extends SelectTransform {
|
public class RandomTransform extends SelectTransform {
|
||||||
|
|
||||||
private final SimpleRandom random;
|
private SimpleRandom random;
|
||||||
private Map<ResettableExtent, Double> weights = new HashMap<>();
|
private Map<ResettableExtent, Double> weights = new HashMap<>();
|
||||||
private RandomCollection<ResettableExtent> collection;
|
|
||||||
private LinkedHashSet<ResettableExtent> extents = new LinkedHashSet<>();
|
private transient RandomCollection<ResettableExtent> collection;
|
||||||
|
private transient LinkedHashSet<ResettableExtent> extents = new LinkedHashSet<>();
|
||||||
|
|
||||||
public RandomTransform() {
|
public RandomTransform() {
|
||||||
this(new TrueRandom());
|
this(new TrueRandom());
|
||||||
@ -44,6 +45,10 @@ public class RandomTransform extends SelectTransform {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResettableExtent setExtent(Extent extent) {
|
public ResettableExtent setExtent(Extent extent) {
|
||||||
|
if (collection == null) {
|
||||||
|
collection = RandomCollection.of(weights, random);
|
||||||
|
extents = new LinkedHashSet<>(weights.keySet());
|
||||||
|
}
|
||||||
for (AbstractDelegateExtent current : extents) {
|
for (AbstractDelegateExtent current : extents) {
|
||||||
if (current instanceof ResettableExtent) {
|
if (current instanceof ResettableExtent) {
|
||||||
((ResettableExtent) current).setExtent(extent);
|
((ResettableExtent) current).setExtent(extent);
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
package com.boydti.fawe.object.extent;
|
package com.boydti.fawe.object.extent;
|
||||||
|
|
||||||
import com.boydti.fawe.util.ExtentTraverser;
|
import com.boydti.fawe.util.ExtentTraverser;
|
||||||
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class ResettableExtent extends AbstractDelegateExtent {
|
public class ResettableExtent extends AbstractDelegateExtent implements Serializable {
|
||||||
public ResettableExtent(Extent parent) {
|
public ResettableExtent(Extent parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
}
|
}
|
||||||
@ -23,4 +27,26 @@ public class ResettableExtent extends AbstractDelegateExtent {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
stream.defaultWriteObject();
|
||||||
|
Extent extent = getExtent();
|
||||||
|
boolean next = extent instanceof ResettableExtent;
|
||||||
|
stream.writeBoolean(next);
|
||||||
|
if (next) {
|
||||||
|
stream.writeObject(extent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
if (stream.readBoolean()) {
|
||||||
|
try {
|
||||||
|
Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||||
|
ReflectionUtils.setFailsafeFieldValue(field, this, stream.readObject());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,11 +13,12 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class ScaleTransform extends ResettableExtent {
|
public class ScaleTransform extends ResettableExtent {
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
private final double dx,dy,dz;
|
private transient int maxy;
|
||||||
private int maxy;
|
private transient Vector min;
|
||||||
|
|
||||||
|
private final double dx,dy,dz;
|
||||||
|
|
||||||
private Vector min;
|
|
||||||
|
|
||||||
public ScaleTransform(Extent parent, double dx, double dy, double dz) {
|
public ScaleTransform(Extent parent, double dx, double dy, double dz) {
|
||||||
super(parent);
|
super(parent);
|
||||||
@ -31,6 +32,7 @@ public class ScaleTransform extends ResettableExtent {
|
|||||||
public ResettableExtent setExtent(Extent extent) {
|
public ResettableExtent setExtent(Extent extent) {
|
||||||
min = null;
|
min = null;
|
||||||
maxy = extent.getMaximumPoint().getBlockY();
|
maxy = extent.getMaximumPoint().getBlockY();
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
return super.setExtent(extent);
|
return super.setExtent(extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +113,6 @@ public class ScaleTransform extends ResettableExtent {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Entity createEntity(Location location, BaseEntity entity) {
|
public Entity createEntity(Location location, BaseEntity entity) {
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
//
|
|
||||||
// Source code recreated from a .class file by IntelliJ IDEA
|
|
||||||
// (powered by Fernflower decompiler)
|
|
||||||
//
|
|
||||||
|
|
||||||
package com.boydti.fawe.object.function.block;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.sk89q.worldedit.Vector;
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import com.sk89q.worldedit.function.RegionFunction;
|
|
||||||
import com.sk89q.worldedit.patterns.Pattern;
|
|
||||||
|
|
||||||
public class LegacyBlockReplace implements RegionFunction {
|
|
||||||
private final Extent extent;
|
|
||||||
private Pattern pattern;
|
|
||||||
|
|
||||||
public LegacyBlockReplace(Extent extent, Pattern pattern) {
|
|
||||||
Preconditions.checkNotNull(extent);
|
|
||||||
Preconditions.checkNotNull(pattern);
|
|
||||||
this.extent = extent;
|
|
||||||
this.pattern = pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean apply(Vector position) throws WorldEditException {
|
|
||||||
return this.extent.setBlock(position, this.pattern.next(position));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,12 @@
|
|||||||
package com.boydti.fawe.object.function.mask;
|
package com.boydti.fawe.object.function.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class AbstractDelegateMask implements Mask {
|
public class AbstractDelegateMask extends AbstractMask {
|
||||||
|
|
||||||
private final Mask mask;
|
private final Mask mask;
|
||||||
|
|
||||||
|
@ -2,15 +2,16 @@ package com.boydti.fawe.object.mask;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just an optimized version of the Adjacent Mask for single adjacency
|
* Just an optimized version of the Adjacent Mask for single adjacency
|
||||||
*/
|
*/
|
||||||
public class AdjacentAnyMask implements Mask {
|
public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
|
||||||
|
|
||||||
private final Mask mask;
|
private final Mask mask;
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
public AdjacentAnyMask(Mask mask) {
|
public AdjacentAnyMask(Mask mask) {
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
@ -20,6 +21,11 @@ public class AdjacentAnyMask implements Mask {
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector v) {
|
public boolean test(Vector v) {
|
||||||
int x = v.getBlockX();
|
int x = v.getBlockX();
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
public class AdjacentMask implements Mask {
|
public class AdjacentMask extends AbstractMask {
|
||||||
private final int min, max;
|
private final int min, max;
|
||||||
private final Mask mask;
|
private final Mask mask;
|
||||||
|
|
||||||
|
@ -8,48 +8,52 @@ import com.sk89q.worldedit.function.mask.Mask2D;
|
|||||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class AngleMask extends SolidBlockMask {
|
public class AngleMask extends SolidBlockMask implements ResettableMask {
|
||||||
public static double ADJACENT_MOD = 0.5;
|
public static double ADJACENT_MOD = 0.5;
|
||||||
public static double DIAGONAL_MOD = 1 / Math.sqrt(8);
|
public static double DIAGONAL_MOD = 1 / Math.sqrt(8);
|
||||||
|
|
||||||
private final double max;
|
private final double max;
|
||||||
private final double min;
|
private final double min;
|
||||||
private final Extent extent;
|
|
||||||
private final boolean overlay;
|
private final boolean overlay;
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
|
||||||
private int maxY;
|
private int maxY;
|
||||||
|
|
||||||
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
public AngleMask(Extent extent, double min, double max, boolean overlay) {
|
public AngleMask(Extent extent, double min, double max, boolean overlay) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.extent = extent;
|
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
this.maxY = extent.getMaximumPoint().getBlockY();
|
this.maxY = extent.getMaximumPoint().getBlockY();
|
||||||
this.overlay = overlay;
|
this.overlay = overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
int x = vector.getBlockX();
|
int x = vector.getBlockX();
|
||||||
int y = vector.getBlockY();
|
int y = vector.getBlockY();
|
||||||
int z = vector.getBlockZ();
|
int z = vector.getBlockZ();
|
||||||
BaseBlock block = extent.getLazyBlock(x, y, z);
|
BaseBlock block = getExtent().getLazyBlock(x, y, z);
|
||||||
if (!test(block.getId(), block.getData())) {
|
if (!test(block.getId(), block.getData())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
block = extent.getLazyBlock(x, y + 1, z);
|
block = getExtent().getLazyBlock(x, y + 1, z);
|
||||||
if (overlay && test(block.getId(), block.getData())) {
|
if (overlay && test(block.getId(), block.getData())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
double slope;
|
double slope;
|
||||||
boolean aboveMin;
|
boolean aboveMin;
|
||||||
slope = Math.abs(extent.getNearestSurfaceTerrainBlock(x + 1, z, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x - 1, z, y, 0, maxY)) * ADJACENT_MOD;
|
slope = Math.abs(getExtent().getNearestSurfaceTerrainBlock(x + 1, z, y, 0, maxY) - getExtent().getNearestSurfaceTerrainBlock(x - 1, z, y, 0, maxY)) * ADJACENT_MOD;
|
||||||
if (slope >= min && max >= Math.max(maxY - y, y)) {
|
if (slope >= min && max >= Math.max(maxY - y, y)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
slope = Math.max(slope, Math.abs(extent.getNearestSurfaceTerrainBlock(x, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x, z - 1, y, 0, maxY)) * ADJACENT_MOD);
|
slope = Math.max(slope, Math.abs(getExtent().getNearestSurfaceTerrainBlock(x, z + 1, y, 0, maxY) - getExtent().getNearestSurfaceTerrainBlock(x, z - 1, y, 0, maxY)) * ADJACENT_MOD);
|
||||||
slope = Math.max(slope, Math.abs(extent.getNearestSurfaceTerrainBlock(x + 1, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x - 1, z - 1, y, 0, maxY)) * DIAGONAL_MOD);
|
slope = Math.max(slope, Math.abs(getExtent().getNearestSurfaceTerrainBlock(x + 1, z + 1, y, 0, maxY) - getExtent().getNearestSurfaceTerrainBlock(x - 1, z - 1, y, 0, maxY)) * DIAGONAL_MOD);
|
||||||
slope = Math.max(slope, Math.abs(extent.getNearestSurfaceTerrainBlock(x - 1, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x + 1, z - 1, y, 0, maxY)) * DIAGONAL_MOD);
|
slope = Math.max(slope, Math.abs(getExtent().getNearestSurfaceTerrainBlock(x - 1, z + 1, y, 0, maxY) - getExtent().getNearestSurfaceTerrainBlock(x + 1, z - 1, y, 0, maxY)) * DIAGONAL_MOD);
|
||||||
return (slope >= min && slope <= max);
|
return (slope >= min && slope <= max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,15 +7,20 @@ import com.sk89q.worldedit.extent.Extent;
|
|||||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
|
||||||
public class BiomeMask extends AbstractExtentMask {
|
public class BiomeMask extends AbstractExtentMask implements ResettableMask {
|
||||||
private final BaseBiome biome;
|
private final BaseBiome biome;
|
||||||
private MutableBlockVector2D mutable = new MutableBlockVector2D();
|
private transient MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||||
|
|
||||||
public BiomeMask(Extent extent, BaseBiome biome) {
|
public BiomeMask(Extent extent, BaseBiome biome) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
mutable = new MutableBlockVector2D();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
Vector2D pos = mutable.setComponents(vector.getBlockX(), vector.getBlockZ());
|
Vector2D pos = mutable.setComponents(vector.getBlockX(), vector.getBlockZ());
|
||||||
|
@ -3,23 +3,23 @@ package com.boydti.fawe.object.mask;
|
|||||||
import com.boydti.fawe.object.extent.LightingExtent;
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BlockLightMask implements Mask {
|
public class BlockLightMask extends AbstractExtentMask {
|
||||||
|
|
||||||
private final Extent extent;
|
|
||||||
private final int min,max;
|
private final int min,max;
|
||||||
|
|
||||||
public BlockLightMask(Extent extent, int min, int max) {
|
public BlockLightMask(Extent extent, int min, int max) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
Extent extent = getExtent();
|
||||||
if (extent instanceof LightingExtent) {
|
if (extent instanceof LightingExtent) {
|
||||||
int light = ((LightingExtent) extent).getBlockLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
int light = ((LightingExtent) extent).getBlockLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
||||||
return light >= min && light <= max;
|
return light >= min && light <= max;
|
||||||
|
@ -3,23 +3,23 @@ package com.boydti.fawe.object.mask;
|
|||||||
import com.boydti.fawe.object.extent.LightingExtent;
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BrightnessMask implements Mask {
|
public class BrightnessMask extends AbstractExtentMask {
|
||||||
|
|
||||||
private final Extent extent;
|
|
||||||
private final int min,max;
|
private final int min,max;
|
||||||
|
|
||||||
public BrightnessMask(Extent extent, int min, int max) {
|
public BrightnessMask(Extent extent, int min, int max) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
Extent extent = getExtent();
|
||||||
if (extent instanceof LightingExtent) {
|
if (extent instanceof LightingExtent) {
|
||||||
int light = ((LightingExtent) extent).getBrightness(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
int light = ((LightingExtent) extent).getBrightness(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
||||||
return light >= min && light <= max;
|
return light >= min && light <= max;
|
||||||
|
@ -2,22 +2,21 @@ package com.boydti.fawe.object.mask;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class DataMask implements Mask, ResettableMask {
|
public class DataMask extends AbstractExtentMask implements ResettableMask {
|
||||||
|
|
||||||
private final Extent extent;
|
|
||||||
|
|
||||||
public DataMask(Extent extent) {
|
public DataMask(Extent extent) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int data = -1;
|
private transient int data = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
Extent extent = getExtent();
|
||||||
if (data != -1) {
|
if (data != -1) {
|
||||||
return extent.getLazyBlock(vector).getData() == data;
|
return extent.getLazyBlock(vector).getData() == data;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,22 +3,20 @@ package com.boydti.fawe.object.mask;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class IdDataMask implements Mask, ResettableMask {
|
public class IdDataMask extends AbstractExtentMask implements ResettableMask {
|
||||||
|
private transient int combined = -1;
|
||||||
private final Extent extent;
|
|
||||||
|
|
||||||
public IdDataMask(Extent extent) {
|
public IdDataMask(Extent extent) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int combined = -1;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
Extent extent = getExtent();
|
||||||
if (combined != -1) {
|
if (combined != -1) {
|
||||||
return FaweCache.getCombined(extent.getLazyBlock(vector)) == combined;
|
return FaweCache.getCombined(extent.getLazyBlock(vector)) == combined;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,22 +2,21 @@ package com.boydti.fawe.object.mask;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class IdMask implements Mask, ResettableMask {
|
public class IdMask extends AbstractExtentMask implements ResettableMask {
|
||||||
|
|
||||||
private Extent extent;
|
private transient int id = -1;
|
||||||
|
|
||||||
public IdMask(Extent extent) {
|
public IdMask(Extent extent) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = -1;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
Extent extent = getExtent();
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
return extent.getLazyBlock(vector).getId() == id;
|
return extent.getLazyBlock(vector).getId() == id;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,25 +3,24 @@ package com.boydti.fawe.object.mask;
|
|||||||
import com.boydti.fawe.object.extent.LightingExtent;
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class LightMask implements Mask {
|
public class LightMask extends AbstractExtentMask {
|
||||||
|
|
||||||
private final Extent extent;
|
|
||||||
private final int min,max;
|
private final int min,max;
|
||||||
|
|
||||||
public LightMask(Extent extent, int min, int max) {
|
public LightMask(Extent extent, int min, int max) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
if (extent instanceof LightingExtent) {
|
if (getExtent() instanceof LightingExtent) {
|
||||||
int light = ((LightingExtent) extent).getLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
int light = ((LightingExtent) getExtent()).getLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
||||||
return light >= min && light <= max;
|
return light >= min && light <= max;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3,25 +3,24 @@ package com.boydti.fawe.object.mask;
|
|||||||
import com.boydti.fawe.object.extent.LightingExtent;
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class OpacityMask implements Mask {
|
public class OpacityMask extends AbstractExtentMask {
|
||||||
|
|
||||||
private final Extent extent;
|
|
||||||
private final int min,max;
|
private final int min,max;
|
||||||
|
|
||||||
public OpacityMask(Extent extent, int min, int max) {
|
public OpacityMask(Extent extent, int min, int max) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
if (extent instanceof LightingExtent) {
|
if (getExtent() instanceof LightingExtent) {
|
||||||
int light = ((LightingExtent) extent).getOpacity(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
int light = ((LightingExtent) getExtent()).getOpacity(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
||||||
return light >= min && light <= max;
|
return light >= min && light <= max;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricts the
|
* Restricts the
|
||||||
*/
|
*/
|
||||||
public class PlaneMask implements Mask, ResettableMask {
|
public class PlaneMask extends AbstractMask implements ResettableMask {
|
||||||
|
|
||||||
private int mode = -1;
|
private transient int mode = -1;
|
||||||
|
private transient int originX = Integer.MAX_VALUE, originY = Integer.MAX_VALUE,originZ = Integer.MAX_VALUE;
|
||||||
private int originX = Integer.MAX_VALUE,originY = Integer.MAX_VALUE,originZ = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
@ -2,12 +2,13 @@ package com.boydti.fawe.object.mask;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class RadiusMask implements Mask, ResettableMask{
|
public class RadiusMask extends AbstractMask implements ResettableMask{
|
||||||
|
|
||||||
|
private transient Vector pos;
|
||||||
private final int minSqr, maxSqr;
|
private final int minSqr, maxSqr;
|
||||||
|
|
||||||
public RadiusMask(int min, int max) {
|
public RadiusMask(int min, int max) {
|
||||||
@ -20,8 +21,6 @@ public class RadiusMask implements Mask, ResettableMask{
|
|||||||
pos = null;
|
pos = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector pos;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector to) {
|
public boolean test(Vector to) {
|
||||||
if (pos == null) {
|
if (pos == null) {
|
||||||
|
@ -4,8 +4,8 @@ import com.sk89q.worldedit.Vector;
|
|||||||
import com.sk89q.worldedit.function.mask.AbstractMask;
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import java.util.SplittableRandom;
|
import java.util.SplittableRandom;
|
||||||
|
|
||||||
public class RandomMask extends AbstractMask {
|
public class RandomMask extends AbstractMask implements ResettableMask {
|
||||||
private final SplittableRandom random;
|
private transient SplittableRandom random;
|
||||||
private final double threshold;
|
private final double threshold;
|
||||||
|
|
||||||
public RandomMask(double threshold) {
|
public RandomMask(double threshold) {
|
||||||
@ -17,4 +17,9 @@ public class RandomMask extends AbstractMask {
|
|||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
return random.nextInt() <= threshold;
|
return random.nextInt() <= threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
random = new SplittableRandom();
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,25 +3,24 @@ package com.boydti.fawe.object.mask;
|
|||||||
import com.boydti.fawe.object.extent.LightingExtent;
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
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.AbstractExtentMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class SkyLightMask implements Mask {
|
public class SkyLightMask extends AbstractExtentMask {
|
||||||
|
|
||||||
private final Extent extent;
|
|
||||||
private final int min,max;
|
private final int min,max;
|
||||||
|
|
||||||
public SkyLightMask(Extent extent, int min, int max) {
|
public SkyLightMask(Extent extent, int min, int max) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
if (extent instanceof LightingExtent) {
|
if (getExtent() instanceof LightingExtent) {
|
||||||
int light = ((LightingExtent) extent).getSkyLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
int light = ((LightingExtent) getExtent()).getSkyLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
|
||||||
return light >= min && light <= max;
|
return light >= min && light <= max;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -12,8 +12,8 @@ import javax.annotation.Nullable;
|
|||||||
*/
|
*/
|
||||||
public class SolidPlaneMask extends SolidBlockMask implements ResettableMask {
|
public class SolidPlaneMask extends SolidBlockMask implements ResettableMask {
|
||||||
|
|
||||||
private int mode = -1;
|
private transient int mode = -1;
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
private int originX = Integer.MAX_VALUE,originY = Integer.MAX_VALUE,originZ = Integer.MAX_VALUE;
|
private int originX = Integer.MAX_VALUE,originY = Integer.MAX_VALUE,originZ = Integer.MAX_VALUE;
|
||||||
|
|
||||||
@ -84,6 +84,7 @@ public class SolidPlaneMask extends SolidBlockMask implements ResettableMask {
|
|||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
mode = -1;
|
mode = -1;
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -7,7 +7,7 @@ import com.sk89q.worldedit.extent.Extent;
|
|||||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||||
|
|
||||||
public class SurfaceMask extends AdjacentAnyMask {
|
public class SurfaceMask extends AdjacentAnyMask {
|
||||||
private final Extent extent;
|
private final transient Extent extent;
|
||||||
|
|
||||||
public SurfaceMask(Extent extent) {
|
public SurfaceMask(Extent extent) {
|
||||||
super(new BlockMask(extent, new BaseBlock(0)));
|
super(new BlockMask(extent, new BaseBlock(0)));
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
public class WallMask implements Mask {
|
public class WallMask extends AbstractMask {
|
||||||
private final int min, max;
|
private final int min, max;
|
||||||
private final Mask mask;
|
private final Mask mask;
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricts the
|
* Restricts the
|
||||||
*/
|
*/
|
||||||
public class XAxisMask implements Mask, ResettableMask {
|
public class XAxisMask extends AbstractMask implements ResettableMask {
|
||||||
|
|
||||||
private int layer = -1;
|
private transient int layer = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricts the
|
* Restricts the
|
||||||
*/
|
*/
|
||||||
public class YAxisMask implements Mask, ResettableMask {
|
public class YAxisMask extends AbstractMask implements ResettableMask {
|
||||||
|
|
||||||
private int layer = -1;
|
private transient int layer = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricts the
|
* Restricts the
|
||||||
*/
|
*/
|
||||||
public class ZAxisMask implements Mask, ResettableMask {
|
public class ZAxisMask extends AbstractMask implements ResettableMask {
|
||||||
|
|
||||||
private int layer = -1;
|
private transient int layer = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
public boolean test(Vector vector) {
|
||||||
|
@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
|
||||||
* Expert Group and released to the public domain, as explained at
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Source:
|
|
||||||
* http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.17
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.boydti.fawe.object.number;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public final class LongAdder extends Striped64 implements Serializable {
|
|
||||||
private static final long serialVersionUID = 7249069246863182397L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Version of plus for use in retryUpdate
|
|
||||||
*/
|
|
||||||
final long fn(long v, long x) { return v + x; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new adder with initial sum of zero.
|
|
||||||
*/
|
|
||||||
public LongAdder() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the given value.
|
|
||||||
*
|
|
||||||
* @param x the value to add
|
|
||||||
*/
|
|
||||||
public void add(long x) {
|
|
||||||
Cell[] as; long b, v; int[] hc; Cell a; int n;
|
|
||||||
if ((as = cells) != null || !casBase(b = base, b + x)) {
|
|
||||||
boolean uncontended = true;
|
|
||||||
if ((hc = threadHashCode.get()) == null ||
|
|
||||||
as == null || (n = as.length) < 1 ||
|
|
||||||
(a = as[(n - 1) & hc[0]]) == null ||
|
|
||||||
!(uncontended = a.cas(v = a.value, v + x)))
|
|
||||||
retryUpdate(x, hc, uncontended);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Equivalent to {@code add(1)}.
|
|
||||||
*/
|
|
||||||
public void increment() {
|
|
||||||
add(1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Equivalent to {@code add(-1)}.
|
|
||||||
*/
|
|
||||||
public void decrement() {
|
|
||||||
add(-1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current sum. The returned value is <em>NOT</em> an
|
|
||||||
* atomic snapshot; invocation in the absence of concurrent
|
|
||||||
* updates returns an accurate result, but concurrent updates that
|
|
||||||
* occur while the sum is being calculated might not be
|
|
||||||
* incorporated.
|
|
||||||
*
|
|
||||||
* @return the sum
|
|
||||||
*/
|
|
||||||
public long sum() {
|
|
||||||
long sum = base;
|
|
||||||
Cell[] as = cells;
|
|
||||||
if (as != null) {
|
|
||||||
int n = as.length;
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
Cell a = as[i];
|
|
||||||
if (a != null)
|
|
||||||
sum += a.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets variables maintaining the sum to zero. This method may
|
|
||||||
* be a useful alternative to creating a new adder, but is only
|
|
||||||
* effective if there are no concurrent updates. Because this
|
|
||||||
* method is intrinsically racy, it should only be used when it is
|
|
||||||
* known that no threads are concurrently updating.
|
|
||||||
*/
|
|
||||||
public void reset() {
|
|
||||||
internalReset(0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Equivalent in effect to {@link #sum} followed by {@link
|
|
||||||
* #reset}. This method may apply for example during quiescent
|
|
||||||
* points between multithreaded computations. If there are
|
|
||||||
* updates concurrent with this method, the returned value is
|
|
||||||
* <em>not</em> guaranteed to be the final value occurring before
|
|
||||||
* the reset.
|
|
||||||
*
|
|
||||||
* @return the sum
|
|
||||||
*/
|
|
||||||
public long sumThenReset() {
|
|
||||||
long sum = base;
|
|
||||||
Cell[] as = cells;
|
|
||||||
base = 0L;
|
|
||||||
if (as != null) {
|
|
||||||
int n = as.length;
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
Cell a = as[i];
|
|
||||||
if (a != null) {
|
|
||||||
sum += a.value;
|
|
||||||
a.value = 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the String representation of the {@link #sum}.
|
|
||||||
* @return the String representation of the {@link #sum}
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return Long.toString(sum());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Equivalent to {@link #sum}.
|
|
||||||
*
|
|
||||||
* @return the sum
|
|
||||||
*/
|
|
||||||
public long longValue() {
|
|
||||||
return sum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link #sum} as an {@code int} after a narrowing
|
|
||||||
* primitive conversion.
|
|
||||||
*/
|
|
||||||
public int intValue() {
|
|
||||||
return (int)sum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link #sum} as a {@code float}
|
|
||||||
* after a widening primitive conversion.
|
|
||||||
*/
|
|
||||||
public float floatValue() {
|
|
||||||
return (float)sum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link #sum} as a {@code double} after a widening
|
|
||||||
* primitive conversion.
|
|
||||||
*/
|
|
||||||
public double doubleValue() {
|
|
||||||
return (double)sum();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
|
||||||
s.defaultWriteObject();
|
|
||||||
s.writeLong(sum());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readObject(ObjectInputStream s)
|
|
||||||
throws IOException, ClassNotFoundException {
|
|
||||||
s.defaultReadObject();
|
|
||||||
busy = 0;
|
|
||||||
cells = null;
|
|
||||||
base = s.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,341 +0,0 @@
|
|||||||
package com.boydti.fawe.object.number;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
|
||||||
* Expert Group and released to the public domain, as explained at
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Source:
|
|
||||||
* http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.9
|
|
||||||
*/
|
|
||||||
|
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A package-local class holding common representation and mechanics
|
|
||||||
* for classes supporting dynamic striping on 64bit values. The class
|
|
||||||
* extends Number so that concrete subclasses must publicly do so.
|
|
||||||
*/
|
|
||||||
abstract class Striped64 extends Number {
|
|
||||||
/*
|
|
||||||
* This class maintains a lazily-initialized table of atomically
|
|
||||||
* updated variables, plus an extra "base" field. The table size
|
|
||||||
* is a power of two. Indexing uses masked per-thread hash codes.
|
|
||||||
* Nearly all declarations in this class are package-private,
|
|
||||||
* accessed directly by subclasses.
|
|
||||||
*
|
|
||||||
* Table entries are of class Cell; a variant of AtomicLong padded
|
|
||||||
* to reduce cache contention on most processors. Padding is
|
|
||||||
* overkill for most Atomics because they are usually irregularly
|
|
||||||
* scattered in memory and thus don't interfere much with each
|
|
||||||
* other. But Atomic objects residing in arrays will tend to be
|
|
||||||
* placed adjacent to each other, and so will most often share
|
|
||||||
* cache lines (with a huge negative performance impact) without
|
|
||||||
* this precaution.
|
|
||||||
*
|
|
||||||
* In part because Cells are relatively large, we avoid creating
|
|
||||||
* them until they are needed. When there is no contention, all
|
|
||||||
* updates are made to the base field. Upon first contention (a
|
|
||||||
* failed CAS on base update), the table is initialized to size 2.
|
|
||||||
* The table size is doubled upon further contention until
|
|
||||||
* reaching the nearest power of two greater than or equal to the
|
|
||||||
* number of CPUS. Table slots remain empty (null) until they are
|
|
||||||
* needed.
|
|
||||||
*
|
|
||||||
* A single spinlock ("busy") is used for initializing and
|
|
||||||
* resizing the table, as well as populating slots with new Cells.
|
|
||||||
* There is no need for a blocking lock; when the lock is not
|
|
||||||
* available, threads try other slots (or the base). During these
|
|
||||||
* retries, there is increased contention and reduced locality,
|
|
||||||
* which is still better than alternatives.
|
|
||||||
*
|
|
||||||
* Per-thread hash codes are initialized to random values.
|
|
||||||
* Contention and/or table collisions are indicated by failed
|
|
||||||
* CASes when performing an update operation (see method
|
|
||||||
* retryUpdate). Upon a collision, if the table size is less than
|
|
||||||
* the capacity, it is doubled in size unless some other thread
|
|
||||||
* holds the lock. If a hashed slot is empty, and lock is
|
|
||||||
* available, a new Cell is created. Otherwise, if the slot
|
|
||||||
* exists, a CAS is tried. Retries proceed by "double hashing",
|
|
||||||
* using a secondary hash (Marsaglia XorShift) to try to find a
|
|
||||||
* free slot.
|
|
||||||
*
|
|
||||||
* The table size is capped because, when there are more threads
|
|
||||||
* than CPUs, supposing that each thread were bound to a CPU,
|
|
||||||
* there would exist a perfect hash function mapping threads to
|
|
||||||
* slots that eliminates collisions. When we reach capacity, we
|
|
||||||
* search for this mapping by randomly varying the hash codes of
|
|
||||||
* colliding threads. Because search is random, and collisions
|
|
||||||
* only become known via CAS failures, convergence can be slow,
|
|
||||||
* and because threads are typically not bound to CPUS forever,
|
|
||||||
* may not occur at all. However, despite these limitations,
|
|
||||||
* observed contention rates are typically low in these cases.
|
|
||||||
*
|
|
||||||
* It is possible for a Cell to become unused when threads that
|
|
||||||
* once hashed to it terminate, as well as in the case where
|
|
||||||
* doubling the table causes no thread to hash to it under
|
|
||||||
* expanded mask. We do not try to detect or remove such cells,
|
|
||||||
* under the assumption that for long-running instances, observed
|
|
||||||
* contention levels will recur, so the cells will eventually be
|
|
||||||
* needed again; and for short-lived ones, it does not matter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Padded variant of AtomicLong supporting only raw accesses plus CAS.
|
|
||||||
* The value field is placed between pads, hoping that the JVM doesn't
|
|
||||||
* reorder them.
|
|
||||||
*
|
|
||||||
* JVM intrinsics note: It would be possible to use a release-only
|
|
||||||
* form of CAS here, if it were provided.
|
|
||||||
*/
|
|
||||||
static final class Cell {
|
|
||||||
volatile long p0, p1, p2, p3, p4, p5, p6;
|
|
||||||
volatile long value;
|
|
||||||
volatile long q0, q1, q2, q3, q4, q5, q6;
|
|
||||||
Cell(long x) { value = x; }
|
|
||||||
|
|
||||||
final boolean cas(long cmp, long val) {
|
|
||||||
return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unsafe mechanics
|
|
||||||
private static final sun.misc.Unsafe UNSAFE;
|
|
||||||
private static final long valueOffset;
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
UNSAFE = getUnsafe();
|
|
||||||
Class<?> ak = Cell.class;
|
|
||||||
valueOffset = UNSAFE.objectFieldOffset
|
|
||||||
(ak.getDeclaredField("value"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ThreadLocal holding a single-slot int array holding hash code.
|
|
||||||
* Unlike the JDK8 version of this class, we use a suboptimal
|
|
||||||
* int[] representation to avoid introducing a new type that can
|
|
||||||
* impede class-unloading when ThreadLocals are not removed.
|
|
||||||
*/
|
|
||||||
static final ThreadLocal<int[]> threadHashCode = new ThreadLocal<int[]>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generator of new random hash codes
|
|
||||||
*/
|
|
||||||
static final PseudoRandom prng = new PseudoRandom(System.nanoTime());
|
|
||||||
|
|
||||||
static final Random rng = new Random();
|
|
||||||
|
|
||||||
/** Number of CPUS, to place bound on table size */
|
|
||||||
static final int NCPU = Runtime.getRuntime().availableProcessors();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Table of cells. When non-null, size is a power of 2.
|
|
||||||
*/
|
|
||||||
transient volatile Cell[] cells;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base value, used mainly when there is no contention, but also as
|
|
||||||
* a fallback during table initialization races. Updated via CAS.
|
|
||||||
*/
|
|
||||||
transient volatile long base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spinlock (locked via CAS) used when resizing and/or creating Cells.
|
|
||||||
*/
|
|
||||||
transient volatile int busy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package-private default constructor
|
|
||||||
*/
|
|
||||||
Striped64() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CASes the base field.
|
|
||||||
*/
|
|
||||||
final boolean casBase(long cmp, long val) {
|
|
||||||
return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CASes the busy field from 0 to 1 to acquire lock.
|
|
||||||
*/
|
|
||||||
final boolean casBusy() {
|
|
||||||
return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the function of current and new value. Subclasses
|
|
||||||
* should open-code this update function for most uses, but the
|
|
||||||
* virtualized form is needed within retryUpdate.
|
|
||||||
*
|
|
||||||
* @param currentValue the current value (of either base or a cell)
|
|
||||||
* @param newValue the argument from a user update call
|
|
||||||
* @return result of the update function
|
|
||||||
*/
|
|
||||||
abstract long fn(long currentValue, long newValue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles cases of updates involving initialization, resizing,
|
|
||||||
* creating new Cells, and/or contention. See above for
|
|
||||||
* explanation. This method suffers the usual non-modularity
|
|
||||||
* problems of optimistic retry code, relying on rechecked sets of
|
|
||||||
* reads.
|
|
||||||
*
|
|
||||||
* @param x the value
|
|
||||||
* @param hc the hash code holder
|
|
||||||
* @param wasUncontended false if CAS failed before call
|
|
||||||
*/
|
|
||||||
final void retryUpdate(long x, int[] hc, boolean wasUncontended) {
|
|
||||||
int h;
|
|
||||||
if (hc == null) {
|
|
||||||
threadHashCode.set(hc = new int[1]); // Initialize randomly
|
|
||||||
int r = prng.random(Integer.MAX_VALUE); // Avoid zero to allow xorShift rehash
|
|
||||||
h = hc[0] = (r == 0) ? 1 : r;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
h = hc[0];
|
|
||||||
boolean collide = false; // True if last slot nonempty
|
|
||||||
for (;;) {
|
|
||||||
Cell[] as; Cell a; int n; long v;
|
|
||||||
if ((as = cells) != null && (n = as.length) > 0) {
|
|
||||||
if ((a = as[(n - 1) & h]) == null) {
|
|
||||||
if (busy == 0) { // Try to attach new Cell
|
|
||||||
Cell r = new Cell(x); // Optimistically create
|
|
||||||
if (busy == 0 && casBusy()) {
|
|
||||||
boolean created = false;
|
|
||||||
try { // Recheck under lock
|
|
||||||
Cell[] rs; int m, j;
|
|
||||||
if ((rs = cells) != null &&
|
|
||||||
(m = rs.length) > 0 &&
|
|
||||||
rs[j = (m - 1) & h] == null) {
|
|
||||||
rs[j] = r;
|
|
||||||
created = true;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
busy = 0;
|
|
||||||
}
|
|
||||||
if (created)
|
|
||||||
break;
|
|
||||||
continue; // Slot is now non-empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
collide = false;
|
|
||||||
}
|
|
||||||
else if (!wasUncontended) // CAS already known to fail
|
|
||||||
wasUncontended = true; // Continue after rehash
|
|
||||||
else if (a.cas(v = a.value, fn(v, x)))
|
|
||||||
break;
|
|
||||||
else if (n >= NCPU || cells != as)
|
|
||||||
collide = false; // At max size or stale
|
|
||||||
else if (!collide)
|
|
||||||
collide = true;
|
|
||||||
else if (busy == 0 && casBusy()) {
|
|
||||||
try {
|
|
||||||
if (cells == as) { // Expand table unless stale
|
|
||||||
Cell[] rs = new Cell[n << 1];
|
|
||||||
for (int i = 0; i < n; ++i)
|
|
||||||
rs[i] = as[i];
|
|
||||||
cells = rs;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
busy = 0;
|
|
||||||
}
|
|
||||||
collide = false;
|
|
||||||
continue; // Retry with expanded table
|
|
||||||
}
|
|
||||||
h ^= h << 13; // Rehash
|
|
||||||
h ^= h >>> 17;
|
|
||||||
h ^= h << 5;
|
|
||||||
hc[0] = h; // Record index for next time
|
|
||||||
}
|
|
||||||
else if (busy == 0 && cells == as && casBusy()) {
|
|
||||||
boolean init = false;
|
|
||||||
try { // Initialize table
|
|
||||||
if (cells == as) {
|
|
||||||
Cell[] rs = new Cell[2];
|
|
||||||
rs[h & 1] = new Cell(x);
|
|
||||||
cells = rs;
|
|
||||||
init = true;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
busy = 0;
|
|
||||||
}
|
|
||||||
if (init)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (casBase(v = base, fn(v, x)))
|
|
||||||
break; // Fall back on using base
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets base and all cells to the given value.
|
|
||||||
*/
|
|
||||||
final void internalReset(long initialValue) {
|
|
||||||
Cell[] as = cells;
|
|
||||||
base = initialValue;
|
|
||||||
if (as != null) {
|
|
||||||
int n = as.length;
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
Cell a = as[i];
|
|
||||||
if (a != null)
|
|
||||||
a.value = initialValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unsafe mechanics
|
|
||||||
private static final sun.misc.Unsafe UNSAFE;
|
|
||||||
private static final long baseOffset;
|
|
||||||
private static final long busyOffset;
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
UNSAFE = getUnsafe();
|
|
||||||
Class<?> sk = Striped64.class;
|
|
||||||
baseOffset = UNSAFE.objectFieldOffset
|
|
||||||
(sk.getDeclaredField("base"));
|
|
||||||
busyOffset = UNSAFE.objectFieldOffset
|
|
||||||
(sk.getDeclaredField("busy"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
|
|
||||||
* Replace with a simple call to Unsafe.getUnsafe when integrating
|
|
||||||
* into a jdk.
|
|
||||||
*
|
|
||||||
* @return a sun.misc.Unsafe
|
|
||||||
*/
|
|
||||||
private static sun.misc.Unsafe getUnsafe() {
|
|
||||||
try {
|
|
||||||
return sun.misc.Unsafe.getUnsafe();
|
|
||||||
} catch (SecurityException tryReflectionInstead) {}
|
|
||||||
try {
|
|
||||||
return java.security.AccessController.doPrivileged
|
|
||||||
(new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
|
|
||||||
public sun.misc.Unsafe run() throws Exception {
|
|
||||||
Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
|
|
||||||
for (java.lang.reflect.Field f : k.getDeclaredFields()) {
|
|
||||||
f.setAccessible(true);
|
|
||||||
Object x = f.get(null);
|
|
||||||
if (k.isInstance(x))
|
|
||||||
return k.cast(x);
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldError("the Unsafe");
|
|
||||||
}});
|
|
||||||
} catch (java.security.PrivilegedActionException e) {
|
|
||||||
throw new RuntimeException("Could not initialize intrinsics",
|
|
||||||
e.getCause());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
|
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public abstract class AbstractExtentPattern extends AbstractPattern {
|
||||||
|
private transient final Extent extent;
|
||||||
|
|
||||||
|
public AbstractExtentPattern(Extent extent) {
|
||||||
|
checkNotNull(extent);
|
||||||
|
this.extent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Extent getExtent() {
|
||||||
|
return extent;
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +1,31 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.object.DataAngleMask;
|
import com.boydti.fawe.object.DataAngleMask;
|
||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class AngleColorPattern extends DataAngleMask {
|
public class AngleColorPattern extends DataAngleMask {
|
||||||
private final TextureUtil util;
|
private static final double FACTOR = 1d/196;
|
||||||
private final int maxY;
|
private transient TextureUtil util;
|
||||||
private final double factor = 1d/196;
|
|
||||||
|
|
||||||
public AngleColorPattern(TextureUtil util, Extent extent) {
|
private final boolean randomize;
|
||||||
|
private final int complexity;
|
||||||
|
|
||||||
|
public AngleColorPattern(Extent extent, int complexity, boolean randomize) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.util = util;
|
this.complexity = complexity;
|
||||||
this.maxY = extent.getMaximumPoint().getBlockY();
|
this.randomize = randomize;
|
||||||
|
this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColor(int color, int slope) {
|
public int getColor(int color, int slope) {
|
||||||
if (slope == 0) return color;
|
if (slope == 0) return color;
|
||||||
double newFactor = (196 - Math.min(196, slope)) * factor;
|
double newFactor = (196 - Math.min(196, slope)) * FACTOR;
|
||||||
int newRed = (int) (((color >> 16) & 0xFF) * newFactor);
|
int newRed = (int) (((color >> 16) & 0xFF) * newFactor);
|
||||||
int newGreen = (int) (((color >> 8) & 0xFF) * newFactor);
|
int newGreen = (int) (((color >> 8) & 0xFF) * newFactor);
|
||||||
int newBlue = (int) (((color >> 0) & 0xFF) * newFactor);
|
int newBlue = (int) (((color >> 0) & 0xFF) * newFactor);
|
||||||
@ -50,4 +55,9 @@ public class AngleColorPattern extends DataAngleMask {
|
|||||||
if (newBlock == null) return false;
|
if (newBlock == null) return false;
|
||||||
return extent.setBlock(setPosition, newBlock);
|
return extent.setBlock(setPosition, newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,27 +1,31 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class AverageColorPattern extends AbstractPattern {
|
public class AverageColorPattern extends AbstractExtentPattern {
|
||||||
|
private transient TextureUtil util;
|
||||||
|
private final boolean randomize;
|
||||||
|
private final int complexity;
|
||||||
private final int color;
|
private final int color;
|
||||||
private final Extent extent;
|
|
||||||
private final TextureUtil util;
|
|
||||||
|
|
||||||
public AverageColorPattern(Extent extent, TextureUtil util, int color) {
|
public AverageColorPattern(Extent extent, int color, int complexity, boolean randomize) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.util = util;
|
this.complexity = complexity;
|
||||||
|
this.randomize = randomize;
|
||||||
|
this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
this.color = new Color(color).getRGB();
|
this.color = new Color(color).getRGB();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
BaseBlock block = extent.getBlock(position);
|
BaseBlock block = getExtent().getBlock(position);
|
||||||
int currentColor = util.getColor(block);
|
int currentColor = util.getColor(block);
|
||||||
int newColor = util.averageColor(currentColor, color);
|
int newColor = util.averageColor(currentColor, color);
|
||||||
return util.getNearestBlock(newColor);
|
return util.getNearestBlock(newColor);
|
||||||
@ -37,4 +41,9 @@ public class AverageColorPattern extends AbstractPattern {
|
|||||||
if (newBlock.equals(block)) return false;
|
if (newBlock.equals(block)) return false;
|
||||||
return extent.setBlock(setPosition, newBlock);
|
return extent.setBlock(setPosition, newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,21 +6,20 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class BiomePattern extends ExistingPattern {
|
public class BiomePattern extends ExistingPattern {
|
||||||
|
private transient MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||||
private final BaseBiome biome;
|
private final BaseBiome biome;
|
||||||
private BiomePatternException exception;
|
|
||||||
private MutableBlockVector2D mutable = new MutableBlockVector2D();
|
|
||||||
|
|
||||||
public BiomePattern(Extent extent, BaseBiome biome) {
|
public BiomePattern(Extent extent, BaseBiome biome) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
this.exception = new BiomePatternException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
throw exception;
|
throw new BiomePatternException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -29,10 +28,7 @@ public class BiomePattern extends ExistingPattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class BiomePatternException extends RuntimeException {
|
public class BiomePatternException extends RuntimeException {
|
||||||
|
private BiomePatternException() {}
|
||||||
public BiomePatternException() {
|
|
||||||
super("Haha, you failed Empire92! Should've done things properly instead of some hacky AF biome pattern.\nHey, you! The one reading this stacktrace, can you do me a favor and report this on GitHub so I can get around to fixing it?");
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiomePattern getPattern() {
|
public BiomePattern getPattern() {
|
||||||
return BiomePattern.this;
|
return BiomePattern.this;
|
||||||
@ -47,4 +43,9 @@ public class BiomePattern extends ExistingPattern {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
mutable = new MutableBlockVector2D();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,21 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BufferedPattern extends AbstractPattern implements ResettablePattern {
|
public class BufferedPattern extends AbstractPattern implements ResettablePattern {
|
||||||
private final Pattern pattern;
|
protected transient LocalBlockVectorSet set = new LocalBlockVectorSet();
|
||||||
private final LocalBlockVectorSet set = new LocalBlockVectorSet();
|
protected transient FaweTimer timer;
|
||||||
private final FaweTimer timer;
|
protected transient long[] actionTime;
|
||||||
private final long[] actionTime;
|
|
||||||
|
protected final Pattern pattern;
|
||||||
|
protected final UUID uuid;
|
||||||
|
|
||||||
public BufferedPattern(FawePlayer fp, Pattern parent) {
|
public BufferedPattern(FawePlayer fp, Pattern parent) {
|
||||||
long[] actionTime = fp.getMeta("lastActionTime");
|
this.uuid = fp.getUUID();
|
||||||
|
this.actionTime = fp.getMeta("lastActionTime");
|
||||||
if (actionTime == null) fp.setMeta("lastActionTime", actionTime = new long[2]);
|
if (actionTime == null) fp.setMeta("lastActionTime", actionTime = new long[2]);
|
||||||
this.actionTime = actionTime;
|
|
||||||
this.pattern = parent;
|
this.pattern = parent;
|
||||||
this.timer = Fawe.get().getTimer();
|
this.timer = Fawe.get().getTimer();
|
||||||
}
|
}
|
||||||
@ -34,7 +38,7 @@ public class BufferedPattern extends AbstractPattern implements ResettablePatter
|
|||||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||||
long now = timer.getTick();
|
long now = timer.getTick();
|
||||||
try {
|
try {
|
||||||
if (!set.add(setPosition)) {
|
if (!set(setPosition)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return pattern.apply(extent, setPosition, getPosition);
|
return pattern.apply(extent, setPosition, getPosition);
|
||||||
@ -42,6 +46,10 @@ public class BufferedPattern extends AbstractPattern implements ResettablePatter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean set(Vector pos) {
|
||||||
|
return set.add(pos);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
long now = timer.getTick();
|
long now = timer.getTick();
|
||||||
@ -51,4 +59,17 @@ public class BufferedPattern extends AbstractPattern implements ResettablePatter
|
|||||||
actionTime[1] = actionTime[0];
|
actionTime[1] = actionTime[0];
|
||||||
actionTime[0] = now;
|
actionTime[0] = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
set = new LocalBlockVectorSet();
|
||||||
|
timer = Fawe.get().getTimer();
|
||||||
|
FawePlayer fp = Fawe.get().getCachedPlayer(uuid);
|
||||||
|
if (fp != null) {
|
||||||
|
this.actionTime = fp.getMeta("lastActionTime");
|
||||||
|
if (actionTime == null) fp.setMeta("lastActionTime", actionTime = new long[2]);
|
||||||
|
} else {
|
||||||
|
actionTime = new long[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,54 +1,17 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
|
||||||
import com.boydti.fawe.util.FaweTimer;
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
public class BufferedPattern2D extends AbstractPattern implements ResettablePattern {
|
public class BufferedPattern2D extends BufferedPattern {
|
||||||
private final Pattern pattern;
|
|
||||||
private final LocalBlockVectorSet set = new LocalBlockVectorSet();
|
|
||||||
private final FaweTimer timer;
|
|
||||||
private final long[] actionTime;
|
|
||||||
|
|
||||||
public BufferedPattern2D(FawePlayer fp, Pattern parent) {
|
public BufferedPattern2D(FawePlayer fp, Pattern parent) {
|
||||||
long[] actionTime = fp.getMeta("lastActionTime");
|
super(fp, parent);
|
||||||
if (actionTime == null) fp.setMeta("lastActionTime", actionTime = new long[2]);
|
|
||||||
this.actionTime = actionTime;
|
|
||||||
this.pattern = parent;
|
|
||||||
this.timer = Fawe.get().getTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public boolean set(Vector pos) {
|
||||||
return pattern.apply(position);
|
return set.add(pos.getBlockX(), 0, pos.getBlockY());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
|
||||||
long now = timer.getTick();
|
|
||||||
try {
|
|
||||||
if (!set.add(setPosition.getBlockX(), 0, setPosition.getBlockZ())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return pattern.apply(extent, setPosition, getPosition);
|
|
||||||
} catch (UnsupportedOperationException ignore) {}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
long now = timer.getTick();
|
|
||||||
if (now - actionTime[1] > 5) {
|
|
||||||
set.clear();
|
|
||||||
}
|
|
||||||
actionTime[1] = actionTime[0];
|
|
||||||
actionTime[0] = now;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,26 +4,23 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class DataPattern extends AbstractPattern {
|
public class DataPattern extends AbstractExtentPattern {
|
||||||
private final Extent extent;
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
|
||||||
public DataPattern(Extent extent, Pattern parent) {
|
public DataPattern(Extent extent, Pattern parent) {
|
||||||
checkNotNull(extent);
|
super(extent);
|
||||||
checkNotNull(parent);
|
checkNotNull(parent);
|
||||||
this.extent = extent;
|
|
||||||
this.pattern = parent;
|
this.pattern = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
BaseBlock oldBlock = extent.getBlock(position);
|
BaseBlock oldBlock = getExtent().getBlock(position);
|
||||||
BaseBlock newBlock = pattern.apply(position);
|
BaseBlock newBlock = pattern.apply(position);
|
||||||
return FaweCache.getBlock(oldBlock.getId(), newBlock.getData());
|
return FaweCache.getBlock(oldBlock.getId(), newBlock.getData());
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,26 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class DesaturatePattern extends AbstractPattern{
|
public class DesaturatePattern extends AbstractPattern{
|
||||||
private final TextureUtil util;
|
private transient TextureUtil util;
|
||||||
|
private final boolean randomize;
|
||||||
|
private final int complexity;
|
||||||
private final Extent extent;
|
private final Extent extent;
|
||||||
private final double value;
|
private final double value;
|
||||||
|
|
||||||
public DesaturatePattern(Extent extent, TextureUtil util, double value) {
|
public DesaturatePattern(Extent extent, double value, int complexity, boolean randomize) {
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.util = util;
|
this.complexity = complexity;
|
||||||
|
this.randomize = randomize;
|
||||||
|
this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
this.value = Math.max(0, Math.min(1, value));
|
this.value = Math.max(0, Math.min(1, value));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@ -55,4 +61,9 @@ public class DesaturatePattern extends AbstractPattern{
|
|||||||
}
|
}
|
||||||
return extent.setBlock(setPosition, newBlock);
|
return extent.setBlock(setPosition, newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,18 +4,15 @@ import com.sk89q.worldedit.Vector;
|
|||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
|
|
||||||
public class ExistingPattern extends AbstractPattern {
|
|
||||||
private final Extent extent;
|
|
||||||
|
|
||||||
|
public class ExistingPattern extends AbstractExtentPattern {
|
||||||
public ExistingPattern(Extent extent) {
|
public ExistingPattern(Extent extent) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
return extent.getBlock(position);
|
return getExtent().getBlock(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,6 +9,7 @@ import com.sk89q.worldedit.internal.expression.Expression;
|
|||||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||||
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
|
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
|
||||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -21,7 +22,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public class ExpressionPattern extends AbstractPattern {
|
public class ExpressionPattern extends AbstractPattern {
|
||||||
|
|
||||||
private final Expression expression;
|
public String input;
|
||||||
|
private transient Expression expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
@ -29,9 +31,10 @@ public class ExpressionPattern extends AbstractPattern {
|
|||||||
* @param expression the expression
|
* @param expression the expression
|
||||||
* @throws ExpressionException thrown if there is an error with the expression
|
* @throws ExpressionException thrown if there is an error with the expression
|
||||||
*/
|
*/
|
||||||
public ExpressionPattern(String expression) throws ExpressionException {
|
public ExpressionPattern(String input) throws ExpressionException {
|
||||||
checkNotNull(expression);
|
checkNotNull(input);
|
||||||
this.expression = Expression.compile(expression, "x", "y", "z");
|
this.input = input;
|
||||||
|
this.expression = Expression.compile(input, "x", "y", "z");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,4 +59,13 @@ public class ExpressionPattern extends AbstractPattern {
|
|||||||
return EditSession.nullBlock;
|
return EditSession.nullBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
try {
|
||||||
|
this.expression = Expression.compile(input, "x", "y", "z");
|
||||||
|
} catch (ExpressionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,8 +9,9 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|||||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.NotSerializableException;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -18,8 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
/**
|
/**
|
||||||
* A pattern that reads from {@link Clipboard}.
|
* A pattern that reads from {@link Clipboard}.
|
||||||
*/
|
*/
|
||||||
public class FullClipboardPattern extends AbstractPattern {
|
public class FullClipboardPattern extends AbstractExtentPattern {
|
||||||
private final Extent extent;
|
|
||||||
private final Clipboard clipboard;
|
private final Clipboard clipboard;
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
@ -29,9 +29,9 @@ public class FullClipboardPattern extends AbstractPattern {
|
|||||||
* @param clipboard the clipboard
|
* @param clipboard the clipboard
|
||||||
*/
|
*/
|
||||||
public FullClipboardPattern(Extent extent, Clipboard clipboard) {
|
public FullClipboardPattern(Extent extent, Clipboard clipboard) {
|
||||||
|
super(extent);
|
||||||
checkNotNull(clipboard);
|
checkNotNull(clipboard);
|
||||||
this.clipboard = clipboard;
|
this.clipboard = clipboard;
|
||||||
this.extent = extent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,4 +47,8 @@ public class FullClipboardPattern extends AbstractPattern {
|
|||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!");
|
throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
throw new NotSerializableException("Clipboard cannot be serialized!");
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,26 +4,24 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
public class IdDataMaskPattern extends AbstractPattern {
|
public class IdDataMaskPattern extends AbstractExtentPattern {
|
||||||
private final Extent extent;
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final int mask;
|
private final int bitMask;
|
||||||
|
|
||||||
public IdDataMaskPattern(Extent extent, Pattern parent, int mask) {
|
public IdDataMaskPattern(Extent extent, Pattern parent, int bitMask) {
|
||||||
this.extent = extent;
|
super(extent);
|
||||||
this.pattern = parent;
|
this.pattern = parent;
|
||||||
this.mask = mask;
|
this.bitMask = bitMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
BaseBlock oldBlock = extent.getBlock(position);
|
BaseBlock oldBlock = getExtent().getBlock(position);
|
||||||
BaseBlock newBlock = pattern.apply(position);
|
BaseBlock newBlock = pattern.apply(position);
|
||||||
int oldData = oldBlock.getData();
|
int oldData = oldBlock.getData();
|
||||||
int newData = newBlock.getData() + oldData - (oldData & mask);
|
int newData = newBlock.getData() + oldData - (oldData & bitMask);
|
||||||
return FaweCache.getBlock(newBlock.getId(), newData);
|
return FaweCache.getBlock(newBlock.getId(), newData);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,26 +4,23 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class IdPattern extends AbstractPattern {
|
public class IdPattern extends AbstractExtentPattern {
|
||||||
private final Extent extent;
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
|
||||||
public IdPattern(Extent extent, Pattern parent) {
|
public IdPattern(Extent extent, Pattern parent) {
|
||||||
checkNotNull(extent);
|
super(extent);
|
||||||
checkNotNull(parent);
|
checkNotNull(parent);
|
||||||
this.extent = extent;
|
|
||||||
this.pattern = parent;
|
this.pattern = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
BaseBlock oldBlock = extent.getBlock(position);
|
BaseBlock oldBlock = getExtent().getBlock(position);
|
||||||
BaseBlock newBlock = pattern.apply(position);
|
BaseBlock newBlock = pattern.apply(position);
|
||||||
return FaweCache.getBlock(newBlock.getId(), oldBlock.getData());
|
return FaweCache.getBlock(newBlock.getId(), oldBlock.getData());
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,13 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class Linear3DBlockPattern extends AbstractPattern {
|
public class Linear3DBlockPattern extends AbstractPattern {
|
||||||
|
|
||||||
private final Collection<Pattern> patterns;
|
|
||||||
private final Pattern[] patternsArray;
|
private final Pattern[] patternsArray;
|
||||||
|
|
||||||
public Linear3DBlockPattern(Pattern[] patterns) {
|
public Linear3DBlockPattern(Pattern[] patterns) {
|
||||||
this.patternsArray = patterns;
|
this.patternsArray = patterns;
|
||||||
this.patterns = Arrays.asList(patterns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,18 +6,14 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class LinearBlockPattern extends AbstractPattern implements ResettablePattern {
|
public class LinearBlockPattern extends AbstractPattern implements ResettablePattern {
|
||||||
|
|
||||||
private final Collection<Pattern> patterns;
|
|
||||||
private final Pattern[] patternsArray;
|
private final Pattern[] patternsArray;
|
||||||
private int index;
|
private transient int index;
|
||||||
|
|
||||||
public LinearBlockPattern(Pattern[] patterns) {
|
public LinearBlockPattern(Pattern[] patterns) {
|
||||||
this.patternsArray = patterns;
|
this.patternsArray = patterns;
|
||||||
this.patterns = Arrays.asList(patterns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,21 +7,17 @@ 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.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MaskedPattern extends AbstractPattern {
|
public class MaskedPattern extends AbstractPattern {
|
||||||
|
|
||||||
private final PatternExtent patternExtent;
|
private final PatternExtent patternExtent;
|
||||||
private final Pattern secondaryPattern;
|
private final Pattern secondaryPattern;
|
||||||
private final List<Pattern> patterns;
|
|
||||||
private Mask mask;
|
private Mask mask;
|
||||||
|
|
||||||
public MaskedPattern(Mask mask, PatternExtent primary, Pattern secondary) {
|
public MaskedPattern(Mask mask, PatternExtent primary, Pattern secondary) {
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
this.patternExtent = primary;
|
this.patternExtent = primary;
|
||||||
this.secondaryPattern = secondary;
|
this.secondaryPattern = secondary;
|
||||||
this.patterns = Arrays.asList(primary, secondary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,17 +7,17 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class NoXPattern extends AbstractPattern {
|
public class NoXPattern extends AbstractPattern {
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
public NoXPattern(Pattern pattern) {
|
public NoXPattern(Pattern pattern) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector pos) {
|
public BaseBlock apply(Vector pos) {
|
||||||
mutable.mutY((pos.getY()));
|
mutable.mutY((pos.getY()));
|
||||||
@ -31,4 +31,9 @@ public class NoXPattern extends AbstractPattern {
|
|||||||
mutable.mutZ((get.getZ()));
|
mutable.mutZ((get.getZ()));
|
||||||
return pattern.apply(extent, set, mutable);
|
return pattern.apply(extent, set, mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class NoYPattern extends AbstractPattern {
|
public class NoYPattern extends AbstractPattern {
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ public class NoYPattern extends AbstractPattern {
|
|||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector pos) {
|
public BaseBlock apply(Vector pos) {
|
||||||
@ -31,4 +32,9 @@ public class NoYPattern extends AbstractPattern {
|
|||||||
mutable.mutZ((get.getZ()));
|
mutable.mutZ((get.getZ()));
|
||||||
return pattern.apply(extent, set, mutable);
|
return pattern.apply(extent, set, mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class NoZPattern extends AbstractPattern {
|
public class NoZPattern extends AbstractPattern {
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ public class NoZPattern extends AbstractPattern {
|
|||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector pos) {
|
public BaseBlock apply(Vector pos) {
|
||||||
@ -31,4 +32,9 @@ public class NoZPattern extends AbstractPattern {
|
|||||||
mutable.mutY((get.getY()));
|
mutable.mutY((get.getY()));
|
||||||
return pattern.apply(extent, set, mutable);
|
return pattern.apply(extent, set, mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,12 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class OffsetPattern extends AbstractPattern {
|
public class OffsetPattern extends AbstractPattern {
|
||||||
|
|
||||||
private final int dx,dy,dz;
|
private final int dx,dy,dz;
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
|
||||||
public OffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
public OffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
||||||
@ -36,4 +37,9 @@ public class OffsetPattern extends AbstractPattern {
|
|||||||
mutable.mutZ((get.getZ() + dz));
|
mutable.mutZ((get.getZ() + dz));
|
||||||
return pattern.apply(extent, set, mutable);
|
return pattern.apply(extent, set, mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,19 +13,25 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class PatternExtent extends AbstractPattern implements Extent {
|
public class PatternExtent extends AbstractPattern implements Extent {
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private BaseBlock block;
|
private transient BaseBlock block;
|
||||||
private Vector target = new Vector();
|
private transient Vector target = new Vector();
|
||||||
|
|
||||||
public PatternExtent(Pattern pattern) {
|
public PatternExtent(Pattern pattern) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
target = new Vector();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector getMinimumPoint() {
|
public Vector getMinimumPoint() {
|
||||||
return new Vector(Integer.MIN_VALUE,0,Integer.MIN_VALUE);
|
return new Vector(Integer.MIN_VALUE,0,Integer.MIN_VALUE);
|
||||||
|
@ -13,6 +13,8 @@ import com.sk89q.worldedit.math.transform.AffineTransform;
|
|||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.NotSerializableException;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -62,4 +64,8 @@ public class RandomFullClipboardPattern extends AbstractPattern {
|
|||||||
public BaseBlock apply(Vector position) {
|
public BaseBlock apply(Vector position) {
|
||||||
throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!");
|
throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
throw new NotSerializableException("Clipboard cannot be serialized!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
@ -8,12 +7,16 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.SplittableRandom;
|
||||||
|
|
||||||
public class RandomOffsetPattern extends AbstractPattern {
|
public class RandomOffsetPattern extends AbstractPattern {
|
||||||
private final PseudoRandom r = new PseudoRandom();
|
private final int dx, dy, dz;
|
||||||
private final int dx, dy, dz, dx2, dy2, dz2;
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
|
||||||
|
private transient int dx2, dy2, dz2;
|
||||||
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
private transient SplittableRandom r;
|
||||||
|
|
||||||
public RandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
public RandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
@ -23,6 +26,7 @@ public class RandomOffsetPattern extends AbstractPattern {
|
|||||||
this.dx2 = dx * 2 + 1;
|
this.dx2 = dx * 2 + 1;
|
||||||
this.dy2 = dy * 2 + 1;
|
this.dy2 = dy * 2 + 1;
|
||||||
this.dz2 = dz * 2 + 1;
|
this.dz2 = dz * 2 + 1;
|
||||||
|
this.r = new SplittableRandom();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,4 +45,13 @@ public class RandomOffsetPattern extends AbstractPattern {
|
|||||||
mutable.mutZ((get.getZ() + r.nextInt(dz2) - dz));
|
mutable.mutZ((get.getZ() + r.nextInt(dz2) - dz));
|
||||||
return pattern.apply(extent, set, mutable);
|
return pattern.apply(extent, set, mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
this.dx2 = dx * 2 + 1;
|
||||||
|
this.dy2 = dy * 2 + 1;
|
||||||
|
this.dz2 = dz * 2 + 1;
|
||||||
|
this.r = new SplittableRandom();
|
||||||
|
this.mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
}
|
}
|
@ -7,18 +7,18 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class RelativePattern extends AbstractPattern implements ResettablePattern {
|
public class RelativePattern extends AbstractPattern implements ResettablePattern {
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
|
private transient Vector origin;
|
||||||
|
private transient MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
public RelativePattern(Pattern pattern) {
|
public RelativePattern(Pattern pattern) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector origin;
|
|
||||||
private MutableBlockVector mutable = new MutableBlockVector();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector pos) {
|
public BaseBlock apply(Vector pos) {
|
||||||
if (origin == null) {
|
if (origin == null) {
|
||||||
@ -41,6 +41,11 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter
|
|||||||
return pattern.apply(extent, set, mutable);
|
return pattern.apply(extent, set, mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
mutable = new MutableBlockVector();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
origin = null;
|
origin = null;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
@ -7,15 +8,21 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SaturatePattern extends AbstractPattern {
|
public class SaturatePattern extends AbstractPattern {
|
||||||
|
private transient TextureUtil util;
|
||||||
|
private final boolean randomize;
|
||||||
|
private final int complexity;
|
||||||
private final int color;
|
private final int color;
|
||||||
private final Extent extent;
|
private final Extent extent;
|
||||||
private final TextureUtil util;
|
|
||||||
|
|
||||||
public SaturatePattern(Extent extent, TextureUtil util, int color) {
|
|
||||||
|
public SaturatePattern(Extent extent, int color, int complexity, boolean randomize) {
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.util = util;
|
this.complexity = complexity;
|
||||||
|
this.randomize = randomize;
|
||||||
|
this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
this.color = new Color(color).getRGB();
|
this.color = new Color(color).getRGB();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,4 +44,9 @@ public class SaturatePattern extends AbstractPattern {
|
|||||||
if (newBlock.equals(block)) return false;
|
if (newBlock.equals(block)) return false;
|
||||||
return extent.setBlock(setPosition, newBlock);
|
return extent.setBlock(setPosition, newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,24 +1,29 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.util.TextureUtil;
|
import com.boydti.fawe.util.TextureUtil;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class ShadePattern extends AbstractPattern{
|
public class ShadePattern extends AbstractPattern{
|
||||||
private final TextureUtil util;
|
private transient TextureUtil util;
|
||||||
|
private final boolean randomize;
|
||||||
|
private final int complexity;
|
||||||
private final Extent extent;
|
private final Extent extent;
|
||||||
private final boolean darken;
|
private final boolean darken;
|
||||||
|
|
||||||
public ShadePattern(Extent extent, TextureUtil util, boolean darken) {
|
public ShadePattern(Extent extent, boolean darken, int complexity, boolean randomize) {
|
||||||
checkNotNull(extent);
|
checkNotNull(extent);
|
||||||
checkNotNull(util);
|
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.util = util;
|
this.complexity = complexity;
|
||||||
|
this.randomize = randomize;
|
||||||
|
this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
this.darken = darken;
|
this.darken = darken;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@ -26,4 +31,9 @@ public class ShadePattern extends AbstractPattern{
|
|||||||
BaseBlock block = extent.getBlock(position);
|
BaseBlock block = extent.getBlock(position);
|
||||||
return darken ? util.getDarkerBlock(block) : util.getLighterBlock(block);
|
return darken ? util.getDarkerBlock(block) : util.getLighterBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package com.boydti.fawe.object.pattern;
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.object.PseudoRandom;
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
@ -10,19 +9,28 @@ import com.sk89q.worldedit.blocks.BlockType;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.SplittableRandom;
|
||||||
|
|
||||||
public class SolidRandomOffsetPattern extends AbstractPattern {
|
public class SolidRandomOffsetPattern extends AbstractPattern {
|
||||||
private final PseudoRandom r = new PseudoRandom();
|
private final int dx, dy, dz;
|
||||||
private final int dx, dy, dz, dx2, dy2, dz2;
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
|
||||||
boolean[] solid;
|
private transient int dx2, dy2, dz2;
|
||||||
|
private transient MutableBlockVector mutable;
|
||||||
|
private transient boolean[] solid;
|
||||||
|
private SplittableRandom r;
|
||||||
|
|
||||||
|
|
||||||
public SolidRandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
public SolidRandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
this.dx = dx;
|
this.dx = dx;
|
||||||
this.dy = dy;
|
this.dy = dy;
|
||||||
this.dz = dz;
|
this.dz = dz;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
this.dx2 = dx * 2 + 1;
|
this.dx2 = dx * 2 + 1;
|
||||||
this.dy2 = dy * 2 + 1;
|
this.dy2 = dy * 2 + 1;
|
||||||
this.dz2 = dz * 2 + 1;
|
this.dz2 = dz * 2 + 1;
|
||||||
@ -34,6 +42,8 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.r = new SplittableRandom();
|
||||||
|
this.mutable = new MutableBlockVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -61,4 +71,9 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
|
|||||||
return pattern.apply(extent, set, get);
|
return pattern.apply(extent, set, get);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
stream.defaultReadObject();
|
||||||
|
init();
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,26 +5,28 @@ import com.boydti.fawe.object.PseudoRandom;
|
|||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SurfaceRandomOffsetPattern extends AbstractPattern {
|
public class SurfaceRandomOffsetPattern extends AbstractPattern {
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final Extent extent;
|
|
||||||
|
|
||||||
private int moves;
|
private int moves;
|
||||||
|
|
||||||
private final MutableBlockVector cur = new MutableBlockVector();
|
private transient MutableBlockVector cur;
|
||||||
private final MutableBlockVector[] buffer;
|
private transient MutableBlockVector[] buffer;
|
||||||
private final MutableBlockVector[] allowed;
|
private transient MutableBlockVector[] allowed;
|
||||||
private MutableBlockVector next;
|
private transient MutableBlockVector next;
|
||||||
|
|
||||||
public SurfaceRandomOffsetPattern(Extent extent, Pattern pattern, int distance) {
|
public SurfaceRandomOffsetPattern(Pattern pattern, int distance) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
this.extent = extent;
|
|
||||||
this.moves = Math.min(255, distance);
|
this.moves = Math.min(255, distance);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
cur = new MutableBlockVector();
|
||||||
this.buffer = new MutableBlockVector[BreadthFirstSearch.DIAGONAL_DIRECTIONS.length];
|
this.buffer = new MutableBlockVector[BreadthFirstSearch.DIAGONAL_DIRECTIONS.length];
|
||||||
for (int i = 0; i < buffer.length; i++) {
|
for (int i = 0; i < buffer.length; i++) {
|
||||||
buffer[i] = new MutableBlockVector();
|
buffer[i] = new MutableBlockVector();
|
||||||
@ -88,40 +90,9 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern {
|
|||||||
BaseBlock block = pattern.apply(v);
|
BaseBlock block = pattern.apply(v);
|
||||||
return FaweCache.canPassThrough(block.getId(), block.getData());
|
return FaweCache.canPassThrough(block.getId(), block.getData());
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// @Override
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
// public BaseBlock apply(Vector position) {
|
stream.defaultReadObject();
|
||||||
// mutable.mutX((position.getX() + r.nextInt(dx2) - dx));
|
init();
|
||||||
// mutable.mutY((position.getY() + r.nextInt(dy2) - dy));
|
}
|
||||||
// mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
|
|
||||||
// BaseBlock block = pattern.apply(mutable);
|
|
||||||
// if (solid[FaweCache.getCombined(block)]) {
|
|
||||||
// if (solid[FaweCache.getCombined(mutable)])
|
|
||||||
// mutable.mutY(mutable.getY() + 1);
|
|
||||||
// if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
|
|
||||||
// return block;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return pattern.apply(position);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private Vector get(Vector input) {
|
|
||||||
// for (dir :
|
|
||||||
// BreadthFirstSearch.DIAGONAL_DIRECTIONS)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean apply(Extent extent, Vector set, Vector get) throws WorldEditException {
|
|
||||||
// mutable.mutX((get.getX() + r.nextInt(dx2) - dx));
|
|
||||||
// mutable.mutY((get.getY() + r.nextInt(dy2) - dy));
|
|
||||||
// mutable.mutZ((get.getZ() + r.nextInt(dz2) - dz));
|
|
||||||
// BaseBlock block = pattern.apply(mutable);
|
|
||||||
// if (solid[FaweCache.getCombined(block)]) {
|
|
||||||
// mutable.mutY(mutable.getY() + 1);
|
|
||||||
// if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
|
|
||||||
// return pattern.apply(extent, set, mutable);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return pattern.apply(extent, set, get);
|
|
||||||
// }
|
|
||||||
}
|
}
|
@ -1,30 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class BaseBlockSerializer extends JsonSerializable<BaseBlock> {
|
|
||||||
@Override
|
|
||||||
public BaseBlock deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
JsonArray jsonArray = json.getAsJsonArray();
|
|
||||||
if (jsonArray.size() != 2) {
|
|
||||||
throw new JsonParseException("Expected array of 3 length for Vector");
|
|
||||||
}
|
|
||||||
return FaweCache.getBlock(jsonArray.get(0).getAsInt(), jsonArray.get(1).getAsInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(BaseBlock src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
JsonArray array = new JsonArray();
|
|
||||||
array.add(new JsonPrimitive(src.getId()));
|
|
||||||
array.add(new JsonPrimitive(src.getData()));
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
|
||||||
import com.sk89q.worldedit.Vector;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class BlockVectorSerializer extends JsonSerializable<Vector> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(Vector src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
JsonArray array = new JsonArray();
|
|
||||||
array.add(new JsonPrimitive(src.getBlockX()));
|
|
||||||
array.add(new JsonPrimitive(src.getBlockY()));
|
|
||||||
array.add(new JsonPrimitive(src.getBlockZ()));
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
JsonArray jsonArray = json.getAsJsonArray();
|
|
||||||
if (jsonArray.size() != 3) {
|
|
||||||
throw new JsonParseException("Expected array of 3 length for Vector");
|
|
||||||
}
|
|
||||||
int x = jsonArray.get(0).getAsInt();
|
|
||||||
int y = jsonArray.get(1).getAsInt();
|
|
||||||
int z = jsonArray.get(2).getAsInt();
|
|
||||||
return new MutableBlockVector(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
|
||||||
import com.boydti.fawe.util.EditSessionBuilder;
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class EditSessionSerializer extends JsonSerializable<EditSession> {
|
|
||||||
|
|
||||||
private final Player player;
|
|
||||||
|
|
||||||
public EditSessionSerializer(Player player) {
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EditSession deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
return new EditSessionBuilder(player.getWorld()).player(FawePlayer.wrap(player)).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(EditSession src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.google.gson.ExclusionStrategy;
|
|
||||||
import com.google.gson.FieldAttributes;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public class InheritedExclusion implements ExclusionStrategy {
|
|
||||||
public boolean shouldSkipClass(Class<?> arg0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldSkipField(FieldAttributes fieldAttributes)
|
|
||||||
{
|
|
||||||
String fieldName = fieldAttributes.getName();
|
|
||||||
Class<?> theClass = fieldAttributes.getDeclaringClass();
|
|
||||||
|
|
||||||
return isFieldInSuperclass(theClass, fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isFieldInSuperclass(Class<?> subclass, String fieldName)
|
|
||||||
{
|
|
||||||
Class<?> superclass = subclass.getSuperclass();
|
|
||||||
Field field;
|
|
||||||
|
|
||||||
while(superclass != null)
|
|
||||||
{
|
|
||||||
field = getField(superclass, fieldName);
|
|
||||||
|
|
||||||
if(field != null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
superclass = superclass.getSuperclass();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field getField(Class<?> theClass, String fieldName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return theClass.getDeclaredField(fieldName);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
|
|
||||||
public abstract class JsonSerializable<T> implements JsonSerializer<T>, JsonDeserializer<T> {
|
|
||||||
|
|
||||||
public JsonSerializable() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.sk89q.worldedit.LocalSession;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class LocalSessionSerializer extends JsonSerializable<LocalSession> {
|
|
||||||
private final Player player;
|
|
||||||
|
|
||||||
public LocalSessionSerializer(Player player) {
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalSession deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
return WorldEdit.getInstance().getSessionManager().get(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(LocalSession src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package com.boydti.fawe.object.serializer;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class PlayerSerializer extends JsonSerializable<Player> {
|
|
||||||
private final Player player;
|
|
||||||
|
|
||||||
public PlayerSerializer(Player player) {
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Player deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(Player src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,9 +6,9 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||||||
|
|
||||||
public class CachedTextureUtil extends DelegateTextureUtil {
|
public class CachedTextureUtil extends DelegateTextureUtil {
|
||||||
private final TextureUtil parent;
|
private final TextureUtil parent;
|
||||||
private Int2ObjectOpenHashMap<Integer> colorBlockMap;
|
private transient Int2ObjectOpenHashMap<Integer> colorBlockMap;
|
||||||
private Int2ObjectOpenHashMap<Integer> colorBiomeMap;
|
private transient Int2ObjectOpenHashMap<Integer> colorBiomeMap;
|
||||||
private Int2ObjectOpenHashMap<char[]> colorLayerMap;
|
private transient Int2ObjectOpenHashMap<char[]> colorLayerMap;
|
||||||
|
|
||||||
public CachedTextureUtil(TextureUtil parent) {
|
public CachedTextureUtil(TextureUtil parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
|
@ -10,7 +10,7 @@ public class CleanTextureUtil extends TextureUtil {
|
|||||||
long min = parent.distances[minIndex];
|
long min = parent.distances[minIndex];
|
||||||
long max = parent.distances[maxIndex];
|
long max = parent.distances[maxIndex];
|
||||||
for (; minIndex > 0 && parent.distances[minIndex - 1] == min; minIndex--);
|
for (; minIndex > 0 && parent.distances[minIndex - 1] == min; minIndex--);
|
||||||
for (; maxIndex < parent.distances.length - 2 && parent.distances[maxIndex + 1] == max; maxIndex++);
|
for (; maxIndex < parent.distances.length - 1 && parent.distances[maxIndex + 1] == max; maxIndex++);
|
||||||
int num = maxIndex - minIndex + 1;
|
int num = maxIndex - minIndex + 1;
|
||||||
this.validBiomes = parent.validBiomes;
|
this.validBiomes = parent.validBiomes;
|
||||||
this.blockColors = parent.blockColors;
|
this.blockColors = parent.blockColors;
|
||||||
|
@ -25,13 +25,14 @@ import com.sk89q.minecraft.util.commands.CommandPermissions;
|
|||||||
import com.sk89q.minecraft.util.commands.NestedCommand;
|
import com.sk89q.minecraft.util.commands.NestedCommand;
|
||||||
import com.sk89q.worldedit.command.BiomeCommands;
|
import com.sk89q.worldedit.command.BiomeCommands;
|
||||||
import com.sk89q.worldedit.command.BrushCommands;
|
import com.sk89q.worldedit.command.BrushCommands;
|
||||||
|
import com.sk89q.worldedit.command.BrushOptionsCommands;
|
||||||
import com.sk89q.worldedit.command.ChunkCommands;
|
import com.sk89q.worldedit.command.ChunkCommands;
|
||||||
import com.sk89q.worldedit.command.ClipboardCommands;
|
import com.sk89q.worldedit.command.ClipboardCommands;
|
||||||
import com.sk89q.worldedit.command.GeneralCommands;
|
|
||||||
import com.sk89q.worldedit.command.GenerationCommands;
|
import com.sk89q.worldedit.command.GenerationCommands;
|
||||||
import com.sk89q.worldedit.command.HistoryCommands;
|
import com.sk89q.worldedit.command.HistoryCommands;
|
||||||
import com.sk89q.worldedit.command.MaskCommands;
|
import com.sk89q.worldedit.command.MaskCommands;
|
||||||
import com.sk89q.worldedit.command.NavigationCommands;
|
import com.sk89q.worldedit.command.NavigationCommands;
|
||||||
|
import com.sk89q.worldedit.command.OptionsCommands;
|
||||||
import com.sk89q.worldedit.command.PatternCommands;
|
import com.sk89q.worldedit.command.PatternCommands;
|
||||||
import com.sk89q.worldedit.command.RegionCommands;
|
import com.sk89q.worldedit.command.RegionCommands;
|
||||||
import com.sk89q.worldedit.command.SchematicCommands;
|
import com.sk89q.worldedit.command.SchematicCommands;
|
||||||
@ -41,7 +42,6 @@ import com.sk89q.worldedit.command.SnapshotCommands;
|
|||||||
import com.sk89q.worldedit.command.SnapshotUtilCommands;
|
import com.sk89q.worldedit.command.SnapshotUtilCommands;
|
||||||
import com.sk89q.worldedit.command.SuperPickaxeCommands;
|
import com.sk89q.worldedit.command.SuperPickaxeCommands;
|
||||||
import com.sk89q.worldedit.command.ToolCommands;
|
import com.sk89q.worldedit.command.ToolCommands;
|
||||||
import com.sk89q.worldedit.command.ToolUtilCommands;
|
|
||||||
import com.sk89q.worldedit.command.TransformCommands;
|
import com.sk89q.worldedit.command.TransformCommands;
|
||||||
import com.sk89q.worldedit.command.UtilityCommands;
|
import com.sk89q.worldedit.command.UtilityCommands;
|
||||||
import com.sk89q.worldedit.command.WorldEditCommands;
|
import com.sk89q.worldedit.command.WorldEditCommands;
|
||||||
@ -97,7 +97,6 @@ public final class DocumentationPrinter {
|
|||||||
stream.println();
|
stream.println();
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
writePermissionsWikiTable(stream, builder, "/we ", WorldEditCommands.class);
|
writePermissionsWikiTable(stream, builder, "/we ", WorldEditCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", GeneralCommands.class);
|
|
||||||
writePermissionsWikiTable(stream, builder, "/", UtilityCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", UtilityCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", RegionCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", RegionCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", SelectionCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", SelectionCommands.class);
|
||||||
@ -106,16 +105,17 @@ public final class DocumentationPrinter {
|
|||||||
writePermissionsWikiTable(stream, builder, "/", ClipboardCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", ClipboardCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", GenerationCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", GenerationCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", BiomeCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", BiomeCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/tool ", ToolCommands.class);
|
|
||||||
writePermissionsWikiTable(stream, builder, "/", ToolUtilCommands.class);
|
|
||||||
writePermissionsWikiTable(stream, builder, "/brush ", BrushCommands.class);
|
|
||||||
writePermissionsWikiTable(stream, builder, "/anvil ", AnvilCommands.class);
|
writePermissionsWikiTable(stream, builder, "/anvil ", AnvilCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/sp ", SuperPickaxeCommands.class);
|
writePermissionsWikiTable(stream, builder, "/sp ", SuperPickaxeCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", NavigationCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", NavigationCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", SnapshotCommands.class);
|
writePermissionsWikiTable(stream, builder, "/snapshot", SnapshotCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", SnapshotUtilCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", SnapshotUtilCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", ScriptingCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", ScriptingCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/", ChunkCommands.class);
|
writePermissionsWikiTable(stream, builder, "/", ChunkCommands.class);
|
||||||
|
writePermissionsWikiTable(stream, builder, "/", OptionsCommands.class);
|
||||||
|
writePermissionsWikiTable(stream, builder, "/", BrushOptionsCommands.class);
|
||||||
|
writePermissionsWikiTable(stream, builder, "/tool ", ToolCommands.class);
|
||||||
|
writePermissionsWikiTable(stream, builder, "/brush ", BrushCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/masks ", MaskCommands.class);
|
writePermissionsWikiTable(stream, builder, "/masks ", MaskCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/patterns ", PatternCommands.class);
|
writePermissionsWikiTable(stream, builder, "/patterns ", PatternCommands.class);
|
||||||
writePermissionsWikiTable(stream, builder, "/transforms ", TransformCommands.class);
|
writePermissionsWikiTable(stream, builder, "/transforms ", TransformCommands.class);
|
||||||
|
@ -41,6 +41,11 @@ public class StringMan {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toProperCase(String s) {
|
||||||
|
return s.substring(0, 1).toUpperCase() +
|
||||||
|
s.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<String> split(String input, char delim) {
|
public static List<String> split(String input, char delim) {
|
||||||
List<String> result = new ArrayList<String>();
|
List<String> result = new ArrayList<String>();
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
//
|
|
||||||
// Source code recreated from a .class file by IntelliJ IDEA
|
|
||||||
// (powered by Fernflower decompiler)
|
|
||||||
//
|
|
||||||
|
|
||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
|
@ -31,7 +31,6 @@ import com.boydti.fawe.object.changeset.FaweChangeSet;
|
|||||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||||
import com.boydti.fawe.util.EditSessionBuilder;
|
import com.boydti.fawe.util.EditSessionBuilder;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
|
||||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||||
import com.sk89q.jchronic.Chronic;
|
import com.sk89q.jchronic.Chronic;
|
||||||
import com.sk89q.jchronic.Options;
|
import com.sk89q.jchronic.Options;
|
||||||
@ -984,10 +983,12 @@ public class LocalSession {
|
|||||||
return getBrushTool(item, 0, null, true);
|
return getBrushTool(item, 0, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public BrushTool getBrushTool(Player player) throws InvalidToolBindException {
|
public BrushTool getBrushTool(Player player) throws InvalidToolBindException {
|
||||||
return getBrushTool(player, true);
|
return getBrushTool(player, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public BrushTool getBrushTool(Player player, boolean create) throws InvalidToolBindException {
|
public BrushTool getBrushTool(Player player, boolean create) throws InvalidToolBindException {
|
||||||
BaseBlock block;
|
BaseBlock block;
|
||||||
try {
|
try {
|
||||||
@ -1000,12 +1001,13 @@ public class LocalSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public BrushTool getBrushTool(int id, int data, Player player, boolean create) throws InvalidToolBindException {
|
public BrushTool getBrushTool(int id, int data, Player player, boolean create) throws InvalidToolBindException {
|
||||||
Tool tool = getTool(id, data);
|
Tool tool = getTool(id, data);
|
||||||
|
|
||||||
if ((tool == null || !(tool instanceof BrushTool))) {
|
if ((tool == null || !(tool instanceof BrushTool))) {
|
||||||
if (create) {
|
if (create) {
|
||||||
tool = new BrushTool("worldedit.brush.sphere");
|
tool = new BrushTool();
|
||||||
setTool(id, data, tool, player);
|
setTool(id, data, tool, player);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
public class MutableBlockVector extends BlockVector {
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class MutableBlockVector extends BlockVector implements Serializable {
|
||||||
|
private transient int x,y,z;
|
||||||
|
|
||||||
private static ThreadLocal<MutableBlockVector> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector>() {
|
private static ThreadLocal<MutableBlockVector> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector>() {
|
||||||
@Override
|
@Override
|
||||||
protected MutableBlockVector initialValue() {
|
protected MutableBlockVector initialValue() {
|
||||||
@ -12,8 +17,6 @@ public class MutableBlockVector extends BlockVector {
|
|||||||
return MUTABLE_CACHE.get().setComponents(x, y, z);
|
return MUTABLE_CACHE.get().setComponents(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int x,y,z;
|
|
||||||
|
|
||||||
public MutableBlockVector(Vector v) {
|
public MutableBlockVector(Vector v) {
|
||||||
this(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
this(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
||||||
}
|
}
|
||||||
@ -105,4 +108,16 @@ public class MutableBlockVector extends BlockVector {
|
|||||||
public int getBlockZ() {
|
public int getBlockZ() {
|
||||||
return this.z;
|
return this.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
stream.writeInt(x);
|
||||||
|
stream.writeByte((byte) y);
|
||||||
|
stream.writeInt(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
this.x = stream.readInt();
|
||||||
|
this.y = stream.readByte() & 0xFF;
|
||||||
|
this.z = stream.readInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
public final class MutableBlockVector2D extends Vector2D {
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public final class MutableBlockVector2D extends Vector2D implements Serializable {
|
||||||
private static ThreadLocal<MutableBlockVector2D> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector2D>() {
|
private static ThreadLocal<MutableBlockVector2D> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector2D>() {
|
||||||
@Override
|
@Override
|
||||||
protected MutableBlockVector2D initialValue() {
|
protected MutableBlockVector2D initialValue() {
|
||||||
@ -12,7 +15,7 @@ public final class MutableBlockVector2D extends Vector2D {
|
|||||||
return MUTABLE_CACHE.get().setComponents(x, z);
|
return MUTABLE_CACHE.get().setComponents(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int x, z;
|
private transient int x, z;
|
||||||
|
|
||||||
public MutableBlockVector2D() {
|
public MutableBlockVector2D() {
|
||||||
this.x = 0;
|
this.x = 0;
|
||||||
@ -64,4 +67,14 @@ public final class MutableBlockVector2D extends Vector2D {
|
|||||||
public void mutZ(double z) {
|
public void mutZ(double z) {
|
||||||
this.z = (int) z;
|
this.z = (int) z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
stream.writeInt(x);
|
||||||
|
stream.writeInt(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
this.x = stream.readInt();
|
||||||
|
this.z = stream.readInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,14 @@ package com.sk89q.worldedit;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immutable 3-dimensional vector.
|
* An immutable 3-dimensional vector.
|
||||||
*/
|
*/
|
||||||
public class Vector implements Comparable<Vector> {
|
public class Vector implements Comparable<Vector>, Serializable {
|
||||||
|
|
||||||
public static final Vector ZERO = new Vector(0, 0, 0);
|
public static final Vector ZERO = new Vector(0, 0, 0);
|
||||||
public static final Vector UNIT_X = new Vector(1, 0, 0);
|
public static final Vector UNIT_X = new Vector(1, 0, 0);
|
||||||
@ -34,9 +36,7 @@ public class Vector implements Comparable<Vector> {
|
|||||||
public static final Vector UNIT_Z = new Vector(0, 0, 1);
|
public static final Vector UNIT_Z = new Vector(0, 0, 1);
|
||||||
public static final Vector ONE = new Vector(1, 1, 1);
|
public static final Vector ONE = new Vector(1, 1, 1);
|
||||||
|
|
||||||
private double x;
|
private transient double x, y, z;
|
||||||
private double y;
|
|
||||||
private double z;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an instance.
|
* Construct an instance.
|
||||||
@ -888,6 +888,21 @@ public class Vector implements Comparable<Vector> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
if (!(this instanceof Vector)) {
|
||||||
|
stream.writeDouble(x);
|
||||||
|
stream.writeDouble(y);
|
||||||
|
stream.writeDouble(z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
if (this instanceof MutableBlockVector) return;
|
||||||
|
this.x = stream.readDouble();
|
||||||
|
this.y = stream.readDouble();
|
||||||
|
this.z = stream.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<?> inject() {
|
public static Class<?> inject() {
|
||||||
return Vector.class;
|
return Vector.class;
|
||||||
}
|
}
|
||||||
|
@ -20,18 +20,19 @@
|
|||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immutable 2-dimensional vector.
|
* An immutable 2-dimensional vector.
|
||||||
*/
|
*/
|
||||||
public class Vector2D {
|
public class Vector2D implements Serializable {
|
||||||
public static final Vector2D ZERO = new Vector2D(0, 0);
|
public static final Vector2D ZERO = new Vector2D(0, 0);
|
||||||
public static final Vector2D UNIT_X = new Vector2D(1, 0);
|
public static final Vector2D UNIT_X = new Vector2D(1, 0);
|
||||||
public static final Vector2D UNIT_Z = new Vector2D(0, 1);
|
public static final Vector2D UNIT_Z = new Vector2D(0, 1);
|
||||||
public static final Vector2D ONE = new Vector2D(1, 1);
|
public static final Vector2D ONE = new Vector2D(1, 1);
|
||||||
|
|
||||||
public double x;
|
public transient double x, z;
|
||||||
public double z;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an instance.
|
* Construct an instance.
|
||||||
@ -665,6 +666,18 @@ public class Vector2D {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
if (this instanceof MutableBlockVector2D) return;
|
||||||
|
stream.writeDouble(x);
|
||||||
|
stream.writeDouble(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
if (this instanceof MutableBlockVector2D) return;
|
||||||
|
this.x = stream.readDouble();
|
||||||
|
this.z = stream.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<?> inject() {
|
public static Class<?> inject() {
|
||||||
return Vector2D.class;
|
return Vector2D.class;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ package com.sk89q.worldedit.blocks;
|
|||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
import com.sk89q.jnbt.StringTag;
|
import com.sk89q.jnbt.StringTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
|
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
|
||||||
@ -31,9 +33,11 @@ import com.sk89q.worldedit.foundation.Block;
|
|||||||
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.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import javax.annotation.Nullable;
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a mutable "snapshot" of a block.
|
* Represents a mutable "snapshot" of a block.
|
||||||
@ -59,7 +63,7 @@ import java.util.Collection;
|
|||||||
* more appropriate.</p>
|
* more appropriate.</p>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class BaseBlock extends Block implements TileEntityBlock, Pattern {
|
public class BaseBlock extends Block implements TileEntityBlock, Pattern, Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates the highest possible block ID (inclusive) that can be used.
|
* Indicates the highest possible block ID (inclusive) that can be used.
|
||||||
@ -79,10 +83,10 @@ public class BaseBlock extends Block implements TileEntityBlock, Pattern {
|
|||||||
// Instances of this class should be _as small as possible_ because there will
|
// Instances of this class should be _as small as possible_ because there will
|
||||||
// be millions of instances of this object.
|
// be millions of instances of this object.
|
||||||
|
|
||||||
private short id;
|
private transient short id;
|
||||||
private short data;
|
private transient short data;
|
||||||
@Nullable
|
@Nullable
|
||||||
private CompoundTag nbtData;
|
private transient CompoundTag nbtData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a block with the given ID and a data value of 0.
|
* Construct a block with the given ID and a data value of 0.
|
||||||
@ -170,6 +174,11 @@ public class BaseBlock extends Block implements TileEntityBlock, Pattern {
|
|||||||
internalSetId(id);
|
internalSetId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCombined(int combined) {
|
||||||
|
setId(FaweCache.getId(combined));
|
||||||
|
setData(FaweCache.getData(combined));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the block's data value.
|
* Get the block's data value.
|
||||||
*
|
*
|
||||||
@ -442,6 +451,21 @@ public class BaseBlock extends Block implements TileEntityBlock, Pattern {
|
|||||||
return extent.setBlock(setPosition, this);
|
return extent.setBlock(setPosition, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
|
||||||
|
stream.writeChar(getCombined());
|
||||||
|
stream.writeBoolean(nbtData != null);
|
||||||
|
if (nbtData != null) {
|
||||||
|
new NBTOutputStream(stream).writeTag(nbtData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||||
|
setCombined(stream.readChar());
|
||||||
|
if (stream.readBoolean()) {
|
||||||
|
this.nbtData = (CompoundTag) new NBTInputStream(new DataInputStream(stream)).readTag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<BaseBlock> inject() {
|
public static Class<BaseBlock> inject() {
|
||||||
return BaseBlock.class;
|
return BaseBlock.class;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
|
|||||||
/**
|
/**
|
||||||
* Implements biome-related commands such as "/biomelist".
|
* Implements biome-related commands such as "/biomelist".
|
||||||
*/
|
*/
|
||||||
@Command(aliases = "/biome", desc = "Change, list and inspect biomes")
|
@Command(aliases = {}, desc = "Change, list and inspect biomes")
|
||||||
public class BiomeCommands {
|
public class BiomeCommands {
|
||||||
|
|
||||||
private final WorldEdit worldEdit;
|
private final WorldEdit worldEdit;
|
||||||
|
@ -26,6 +26,7 @@ import com.boydti.fawe.config.Settings;
|
|||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.brush.BlendBall;
|
import com.boydti.fawe.object.brush.BlendBall;
|
||||||
|
import com.boydti.fawe.object.brush.BrushSettings;
|
||||||
import com.boydti.fawe.object.brush.CircleBrush;
|
import com.boydti.fawe.object.brush.CircleBrush;
|
||||||
import com.boydti.fawe.object.brush.CommandBrush;
|
import com.boydti.fawe.object.brush.CommandBrush;
|
||||||
import com.boydti.fawe.object.brush.CopyPastaBrush;
|
import com.boydti.fawe.object.brush.CopyPastaBrush;
|
||||||
@ -50,6 +51,7 @@ import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap;
|
|||||||
import com.boydti.fawe.object.mask.IdMask;
|
import com.boydti.fawe.object.mask.IdMask;
|
||||||
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.CommandLocals;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.EmptyClipboardException;
|
import com.sk89q.worldedit.EmptyClipboardException;
|
||||||
@ -60,7 +62,7 @@ import com.sk89q.worldedit.WorldEdit;
|
|||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.blocks.BlockID;
|
import com.sk89q.worldedit.blocks.BlockID;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
||||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||||
import com.sk89q.worldedit.command.tool.brush.ButcherBrush;
|
import com.sk89q.worldedit.command.tool.brush.ButcherBrush;
|
||||||
import com.sk89q.worldedit.command.tool.brush.ClipboardBrush;
|
import com.sk89q.worldedit.command.tool.brush.ClipboardBrush;
|
||||||
@ -99,7 +101,7 @@ import javafx.scene.paint.Color;
|
|||||||
/**
|
/**
|
||||||
* Commands to set brush shape.
|
* Commands to set brush shape.
|
||||||
*/
|
*/
|
||||||
@Command(aliases = { "brush", "br" },
|
@Command(aliases = { "brush", "br", "/b" },
|
||||||
desc = "Commands to build and draw from far away. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Brushes)"
|
desc = "Commands to build and draw from far away. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Brushes)"
|
||||||
)
|
)
|
||||||
public class BrushCommands extends MethodCommands {
|
public class BrushCommands extends MethodCommands {
|
||||||
@ -108,6 +110,20 @@ public class BrushCommands extends MethodCommands {
|
|||||||
super(worldEdit);
|
super(worldEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BrushSettings get(CommandContext context) throws InvalidToolBindException {
|
||||||
|
BrushSettings bs = new BrushSettings();
|
||||||
|
bs.addPermissions(getPermissions());
|
||||||
|
CommandLocals locals = context.getLocals();
|
||||||
|
if (locals != null) {
|
||||||
|
String args = (String) locals.get("arguments");
|
||||||
|
if (args != null) {
|
||||||
|
bs.addSetting(BrushSettings.SettingType.BRUSH, args.substring(args.indexOf(' ') + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "blendball", "bb", "blend" },
|
aliases = { "blendball", "bb", "blend" },
|
||||||
usage = "[radius=5]",
|
usage = "[radius=5]",
|
||||||
@ -118,12 +134,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.blendball")
|
@CommandPermissions("worldedit.brush.blendball")
|
||||||
public void blendBallBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
|
public BrushSettings blendBallBrush(Player player, LocalSession session, @Optional("5") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context).setBrush(new BlendBall()).setSize(radius);
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new BlendBall(), "worldedit.brush.blendball", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_BLEND_BALL.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -135,12 +148,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.erode")
|
@CommandPermissions("worldedit.brush.erode")
|
||||||
public void erodeBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
|
public BrushSettings erodeBrush(Player player, LocalSession session, @Optional("5") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context).setBrush(new ErodeBrush()).setSize(radius);
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new ErodeBrush(), "worldedit.brush.erode", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_ERODE.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -152,12 +162,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.pull")
|
@CommandPermissions("worldedit.brush.pull")
|
||||||
public void pullBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException {
|
public BrushSettings pullBrush(Player player, LocalSession session, @Optional("5") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context).setBrush(new RaiseBrush()).setSize(radius);
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new RaiseBrush(), "worldedit.brush.pull", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_ERODE.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -170,13 +177,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 2
|
max = 2
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.sphere")
|
@CommandPermissions("worldedit.brush.sphere")
|
||||||
public void circleBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius) throws WorldEditException {
|
public BrushSettings circleBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context).setBrush(new CircleBrush(player)).setSize(radius).setFill(fill);
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setBrush(new CircleBrush(player), "worldedit.brush.circle", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_CIRCLE.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -190,14 +193,13 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 3
|
max = 3
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.recursive")
|
@CommandPermissions("worldedit.brush.recursive")
|
||||||
public void recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("5") double radius, @Switch('d') boolean depthFirst) throws WorldEditException {
|
public BrushSettings recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("5") double radius, @Switch('d') boolean depthFirst, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context)
|
||||||
tool.setSize(radius);
|
.setBrush(new RecurseBrush(depthFirst))
|
||||||
tool.setBrush(new RecurseBrush(depthFirst), "worldedit.brush.recursive", player);
|
.setSize(radius)
|
||||||
tool.setMask(new IdMask(editSession));
|
.setFill(fill)
|
||||||
tool.setFill(fill);
|
.setMask(new IdMask(editSession));
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_RECURSIVE.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -214,13 +216,12 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 2
|
max = 2
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.line")
|
@CommandPermissions("worldedit.brush.line")
|
||||||
public void lineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException {
|
public BrushSettings lineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context)
|
||||||
tool.setFill(fill);
|
.setBrush(new LineBrush(shell, select, flat))
|
||||||
tool.setSize(radius);
|
.setSize(radius)
|
||||||
tool.setBrush(new LineBrush(shell, select, flat), "worldedit.brush.line", player);
|
.setFill(fill);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_LINE.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -235,13 +236,13 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 2
|
max = 2
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.spline")
|
@CommandPermissions("worldedit.brush.spline")
|
||||||
public void splineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("25") double radius) throws WorldEditException {
|
public BrushSettings splineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("25") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new SplineBrush(player, session), "worldedit.brush.spline", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
|
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
|
||||||
|
return get(context)
|
||||||
|
.setBrush(new SplineBrush(player, session))
|
||||||
|
.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
// final double tension, final double bias, final double continuity, final double quality
|
// final double tension, final double bias, final double continuity, final double quality
|
||||||
@ -256,13 +257,12 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 2
|
max = 2
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0,
|
@CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0,
|
||||||
public void surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality) throws WorldEditException {
|
public BrushSettings surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new SurfaceSpline(tension, bias, continuity, quality), "worldedit.brush.spline", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
|
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
|
||||||
|
worldEdit.checkMaxBrushRadius(radius);return get(context)
|
||||||
|
.setBrush(new SurfaceSpline(tension, bias, continuity, quality))
|
||||||
|
.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -277,30 +277,28 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 2
|
max = 2
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.sphere")
|
@CommandPermissions("worldedit.brush.sphere")
|
||||||
public void sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException {
|
public BrushSettings sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
|
|
||||||
BrushTool tool = session.getBrushTool(player);
|
Brush brush;
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
|
|
||||||
if (hollow) {
|
if (hollow) {
|
||||||
tool.setBrush(new HollowSphereBrush(), "worldedit.brush.sphere", player);
|
brush = new HollowSphereBrush();
|
||||||
} else {
|
} else {
|
||||||
tool.setBrush(new SphereBrush(), "worldedit.brush.sphere", player);
|
brush = new SphereBrush();
|
||||||
}
|
}
|
||||||
if (fill instanceof BlockPattern) {
|
if (fill instanceof BlockPattern) {
|
||||||
BaseBlock block = ((BlockPattern) fill).getBlock();
|
BaseBlock block = ((BlockPattern) fill).getBlock();
|
||||||
switch (block.getId()) {
|
switch (block.getId()) {
|
||||||
case BlockID.SAND:
|
case BlockID.SAND:
|
||||||
case BlockID.GRAVEL:
|
case BlockID.GRAVEL:
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPHERE.f(radius));
|
|
||||||
BBC.BRUSH_TRY_OTHER.send(player);
|
BBC.BRUSH_TRY_OTHER.send(player);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPHERE.f(radius));
|
return get(context)
|
||||||
if (!FawePlayer.wrap(player).hasPermission("fawe.tips")) BBC.TIP_BRUSH_COMMAND.or(BBC.TIP_BRUSH_RELATIVE, BBC.TIP_BRUSH_TRANSFORM, BBC.TIP_BRUSH_MASK_SOURCE, BBC.TIP_BRUSH_MASK, BBC.TIP_BRUSH_COPY, BBC.TIP_BRUSH_HEIGHT, BBC.TIP_BRUSH_SPLINE).send(player);
|
.setBrush(brush)
|
||||||
|
.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -314,15 +312,13 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = -1
|
max = -1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.shatter")
|
@CommandPermissions("worldedit.brush.shatter")
|
||||||
public void shatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("10") double radius, @Optional("10") int count) throws WorldEditException {
|
public BrushSettings shatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("10") double radius, @Optional("10") int count, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
|
return get(context)
|
||||||
BrushTool tool = session.getBrushTool(player);
|
.setBrush(new ShatterBrush(count))
|
||||||
tool.setFill(fill);
|
.setSize(radius)
|
||||||
tool.setSize(radius);
|
.setFill(fill)
|
||||||
tool.setMask(new ExistingBlockMask(editSession));
|
.setMask(new ExistingBlockMask(editSession));
|
||||||
tool.setBrush(new ShatterBrush(count), "worldedit.brush.shatter");
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SHATTER.f(radius, count));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -337,23 +333,22 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = -1
|
max = -1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.stencil")
|
@CommandPermissions("worldedit.brush.stencil")
|
||||||
public void stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate) throws WorldEditException {
|
public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
InputStream stream = getHeightmapStream(filename);
|
InputStream stream = getHeightmapStream(filename);
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
HeightBrush brush;
|
HeightBrush brush;
|
||||||
try {
|
try {
|
||||||
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null);
|
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null);
|
||||||
} catch (EmptyClipboardException ignore) {
|
} catch (EmptyClipboardException ignore) {
|
||||||
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, null);
|
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, null);
|
||||||
}
|
}
|
||||||
tool.setBrush(brush, "worldedit.brush.height", player);
|
|
||||||
if (randomRotate) {
|
if (randomRotate) {
|
||||||
brush.setRandomRotate(true);
|
brush.setRandomRotate(true);
|
||||||
}
|
}
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_STENCIL.f(radius));
|
return get(context)
|
||||||
|
.setBrush(brush)
|
||||||
|
.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -368,13 +363,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = -1
|
max = -1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.surface")
|
@CommandPermissions("worldedit.brush.surface")
|
||||||
public void surfaceBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius) throws WorldEditException {
|
public BrushSettings surfaceBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context).setBrush(new SurfaceSphereBrush()).setFill(fill).setSize(radius);
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new SurfaceSphereBrush(), "worldedit.brush.surface");
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SURFACE.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -390,19 +381,18 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 4
|
max = 4
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.scatter")
|
@CommandPermissions("worldedit.brush.scatter")
|
||||||
public void scatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("5") double points, @Optional("1") double distance, @Switch('o') boolean overlay) throws WorldEditException {
|
public BrushSettings scatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("5") double points, @Optional("1") double distance, @Switch('o') boolean overlay, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
Brush brush;
|
Brush brush;
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
brush = new ScatterOverlayBrush((int) points, (int) distance);
|
brush = new ScatterOverlayBrush((int) points, (int) distance);
|
||||||
} else {
|
} else {
|
||||||
brush = new ScatterBrush((int) points, (int) distance);
|
brush = new ScatterBrush((int) points, (int) distance);
|
||||||
}
|
}
|
||||||
tool.setBrush(brush, "worldedit.brush.scatter", player);
|
return get(context)
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SCATTER.f(radius, points));
|
.setBrush(brush)
|
||||||
|
.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -417,18 +407,18 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 4
|
max = 4
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.populateschematic")
|
@CommandPermissions("worldedit.brush.populateschematic")
|
||||||
public void scatterSchemBrush(Player player, EditSession editSession, LocalSession session, Mask mask, String clipboard, @Optional("30") double radius, @Optional("50") double density, @Switch('r') boolean rotate) throws WorldEditException {
|
public BrushSettings scatterSchemBrush(Player player, EditSession editSession, LocalSession session, Mask mask, String clipboard, @Optional("30") double radius, @Optional("50") double density, @Switch('r') boolean rotate, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setSize(radius);
|
|
||||||
try {
|
try {
|
||||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), clipboard, true);
|
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), clipboard, true);
|
||||||
if (clipboards == null) {
|
if (clipboards == null) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
Brush brush = new PopulateSchem(mask, clipboards, (int) density, rotate);
|
return get(context)
|
||||||
tool.setBrush(brush, "worldedit.brush.populateschematic", player);
|
.setBrush(new PopulateSchem(mask, clipboards, (int) density, rotate))
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_POPULATE.f(radius, density));
|
.setSize(radius);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -445,10 +435,8 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 999
|
max = 999
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.layer")
|
@CommandPermissions("worldedit.brush.layer")
|
||||||
public void surfaceLayer(Player player, EditSession editSession, LocalSession session, double radius, CommandContext args) throws WorldEditException, InvalidUsageException {
|
public BrushSettings surfaceLayer(Player player, EditSession editSession, LocalSession session, double radius, CommandContext args, CommandContext context) throws WorldEditException, InvalidUsageException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setSize(radius);
|
|
||||||
ParserContext parserContext = new ParserContext();
|
ParserContext parserContext = new ParserContext();
|
||||||
parserContext.setActor(player);
|
parserContext.setActor(player);
|
||||||
parserContext.setWorld(player.getWorld());
|
parserContext.setWorld(player.getWorld());
|
||||||
@ -471,8 +459,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
blocks.add(worldEdit.getBlockFactory().parseFromInput(arg, parserContext));
|
blocks.add(worldEdit.getBlockFactory().parseFromInput(arg, parserContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tool.setBrush(new LayerBrush(blocks.toArray(new BaseBlock[blocks.size()])), "worldedit.brush.layer", player);
|
return get(context)
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_LAYER.f(radius, args.getJoinedStrings(1)));
|
.setBrush(new LayerBrush(blocks.toArray(new BaseBlock[blocks.size()])))
|
||||||
|
.setSize(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -487,13 +476,12 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 5
|
max = 5
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.splatter")
|
@CommandPermissions("worldedit.brush.splatter")
|
||||||
public void splatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("1") double points, @Optional("5") double recursion, @Optional("true") boolean solid) throws WorldEditException {
|
public BrushSettings splatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("1") double points, @Optional("5") double recursion, @Optional("true") boolean solid, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context)
|
||||||
tool.setFill(fill);
|
.setBrush(new SplatterBrush((int) points, (int) recursion, solid))
|
||||||
tool.setSize(radius);
|
.setSize(radius)
|
||||||
tool.setBrush(new SplatterBrush((int) points, (int) recursion, solid), "worldedit.brush.splatter", player);
|
.setFill(fill);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SCATTER.f(radius, points));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -509,12 +497,11 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = -1
|
max = -1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.scattercommand")
|
@CommandPermissions("worldedit.brush.scattercommand")
|
||||||
public void scatterCommandBrush(Player player, EditSession editSession, LocalSession session, double radius, double points, double distance, CommandContext args) throws WorldEditException {
|
public BrushSettings scatterCommandBrush(Player player, EditSession editSession, LocalSession session, double radius, double points, double distance, CommandContext args, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context)
|
||||||
tool.setSize(radius);
|
.setBrush(new ScatterCommand((int) points, (int) distance, args.getJoinedStrings(3)))
|
||||||
tool.setBrush(new ScatterCommand((int) points, (int) distance, args.getJoinedStrings(3)), "worldedit.brush.scattercommand", player);
|
.setSize(radius);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SCATTER.f(radius, points));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -529,21 +516,20 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 3
|
max = 3
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.cylinder")
|
@CommandPermissions("worldedit.brush.cylinder")
|
||||||
public void cylinderBrush(Player player, EditSession editSession, LocalSession session, Pattern fill,
|
public BrushSettings cylinderBrush(Player player, EditSession editSession, LocalSession session, Pattern fill,
|
||||||
@Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException {
|
@Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
worldEdit.checkMaxBrushRadius(height);
|
worldEdit.checkMaxBrushRadius(height);
|
||||||
|
BrushSettings settings = get(context);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setFill(fill);
|
|
||||||
tool.setSize(radius);
|
|
||||||
|
|
||||||
if (hollow) {
|
if (hollow) {
|
||||||
tool.setBrush(new HollowCylinderBrush(height), "worldedit.brush.cylinder", player);
|
settings.setBrush(new HollowCylinderBrush(height));
|
||||||
} else {
|
} else {
|
||||||
tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder", player);
|
settings.setBrush(new CylinderBrush(height));
|
||||||
}
|
}
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPHERE.f(radius, height));
|
settings.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -558,7 +544,7 @@ public class BrushCommands extends MethodCommands {
|
|||||||
"stood relative to the copied area when you copied it."
|
"stood relative to the copied area when you copied it."
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.clipboard")
|
@CommandPermissions("worldedit.brush.clipboard")
|
||||||
public void clipboardBrush(Player player, LocalSession session, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin) throws WorldEditException {
|
public BrushSettings clipboardBrush(Player player, LocalSession session, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin, CommandContext context) throws WorldEditException {
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
Clipboard clipboard = holder.getClipboard();
|
Clipboard clipboard = holder.getClipboard();
|
||||||
|
|
||||||
@ -567,10 +553,7 @@ public class BrushCommands extends MethodCommands {
|
|||||||
worldEdit.checkMaxBrushRadius(size.getBlockX());
|
worldEdit.checkMaxBrushRadius(size.getBlockX());
|
||||||
worldEdit.checkMaxBrushRadius(size.getBlockY());
|
worldEdit.checkMaxBrushRadius(size.getBlockY());
|
||||||
worldEdit.checkMaxBrushRadius(size.getBlockZ());
|
worldEdit.checkMaxBrushRadius(size.getBlockZ());
|
||||||
|
return get(context).setBrush(new ClipboardBrush(holder, ignoreAir, usingOrigin));
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setBrush(new ClipboardBrush(holder, ignoreAir, usingOrigin), "worldedit.brush.clipboard", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_CLIPBOARD.s());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -585,20 +568,19 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 2
|
max = 2
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.smooth")
|
@CommandPermissions("worldedit.brush.smooth")
|
||||||
public void smoothBrush(Player player, LocalSession session, EditSession editSession,
|
public BrushSettings smoothBrush(Player player, LocalSession session, EditSession editSession,
|
||||||
@Optional("2") double radius, @Optional("4") int iterations, @Switch('n')
|
@Optional("2") double radius, @Optional("4") int iterations, @Switch('n')
|
||||||
boolean naturalBlocksOnly) throws WorldEditException {
|
boolean naturalBlocksOnly, CommandContext context) throws WorldEditException {
|
||||||
|
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
|
|
||||||
FawePlayer fp = FawePlayer.wrap(player);
|
FawePlayer fp = FawePlayer.wrap(player);
|
||||||
FaweLimit limit = Settings.IMP.getLimit(fp);
|
FaweLimit limit = Settings.IMP.getLimit(fp);
|
||||||
iterations = Math.min(limit.MAX_ITERATIONS, iterations);
|
iterations = Math.min(limit.MAX_ITERATIONS, iterations);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new SmoothBrush(iterations, naturalBlocksOnly), "worldedit.brush.smooth", player);
|
|
||||||
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SMOOTH.f(radius, iterations, (naturalBlocksOnly ? "natural blocks only" : "any block")));
|
return get(context)
|
||||||
|
.setBrush(new SmoothBrush(iterations, naturalBlocksOnly))
|
||||||
|
.setSize(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -609,17 +591,15 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.ex")
|
@CommandPermissions("worldedit.brush.ex")
|
||||||
public void extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException {
|
public BrushSettings extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
|
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
Pattern fill = new BlockPattern(new BaseBlock(0));
|
Pattern fill = new BlockPattern(new BaseBlock(0));
|
||||||
tool.setFill(fill);
|
return get(context)
|
||||||
tool.setSize(radius);
|
.setBrush(new SphereBrush())
|
||||||
tool.setMask(new BlockMask(editSession, new BaseBlock(BlockID.FIRE)));
|
.setSize(radius)
|
||||||
tool.setBrush(new SphereBrush(), "worldedit.brush.ex", player);
|
.setFill(fill)
|
||||||
BBC.BRUSH_EXTINGUISHER.send(player, radius);
|
.setMask(new BlockMask(editSession, new BaseBlock(BlockID.FIRE)));
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_EXTINGUISHER.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -635,13 +615,12 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.gravity")
|
@CommandPermissions("worldedit.brush.gravity")
|
||||||
public void gravityBrush(Player player, LocalSession session, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException {
|
public BrushSettings gravityBrush(Player player, LocalSession session, @Optional("5") double radius, @Switch('h') boolean fromMaxY, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
|
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context)
|
||||||
tool.setSize(radius);
|
.setBrush(new GravityBrush(fromMaxY))
|
||||||
tool.setBrush(new GravityBrush(fromMaxY, tool), "worldedit.brush.gravity", player);
|
.setSize(radius);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_GRAVITY.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -660,8 +639,8 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 4
|
max = 4
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.height")
|
@CommandPermissions("worldedit.brush.height")
|
||||||
public void heightBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth) throws WorldEditException {
|
public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
|
||||||
terrainBrush(player, session, radius, filename, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE);
|
return terrainBrush(player, session, radius, filename, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -678,8 +657,8 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 4
|
max = 4
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.height")
|
@CommandPermissions("worldedit.brush.height")
|
||||||
public void cliffBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth) throws WorldEditException {
|
public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
|
||||||
terrainBrush(player, session, radius, filename, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER);
|
return terrainBrush(player, session, radius, filename, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -695,8 +674,8 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 4
|
max = 4
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.height")
|
@CommandPermissions("worldedit.brush.height")
|
||||||
public void flattenBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth) throws WorldEditException {
|
public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
|
||||||
terrainBrush(player, session, radius, filename, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE);
|
return terrainBrush(player, session, radius, filename, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream getHeightmapStream(String filename) {
|
private InputStream getHeightmapStream(String filename) {
|
||||||
@ -730,11 +709,9 @@ public class BrushCommands extends MethodCommands {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void terrainBrush(Player player, LocalSession session, double radius, String filename, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape) throws WorldEditException {
|
private BrushSettings terrainBrush(Player player, LocalSession session, double radius, String filename, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
InputStream stream = getHeightmapStream(filename);
|
InputStream stream = getHeightmapStream(filename);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setSize(radius);
|
|
||||||
HeightBrush brush;
|
HeightBrush brush;
|
||||||
if (flat) {
|
if (flat) {
|
||||||
try {
|
try {
|
||||||
@ -749,11 +726,12 @@ public class BrushCommands extends MethodCommands {
|
|||||||
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, null);
|
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tool.setBrush(brush, "worldedit.brush.height", player);
|
|
||||||
if (randomRotate) {
|
if (randomRotate) {
|
||||||
brush.setRandomRotate(true);
|
brush.setRandomRotate(true);
|
||||||
}
|
}
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_HEIGHT.f(radius));
|
return get(context)
|
||||||
|
.setBrush(brush)
|
||||||
|
.setSize(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -771,12 +749,12 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.copy")
|
@CommandPermissions("worldedit.brush.copy")
|
||||||
public void copy(Player player, LocalSession session, @Optional("5") double radius, @Switch('r') boolean rotate) throws WorldEditException {
|
public BrushSettings copy(Player player, LocalSession session, @Optional("5") double radius, @Switch('r') boolean rotate, CommandContext context) throws WorldEditException {
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
tool.setSize(radius);
|
|
||||||
tool.setBrush(new CopyPastaBrush(player, session, rotate), "worldedit.brush.copy", player);
|
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
|
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
|
||||||
|
return get(context)
|
||||||
|
.setBrush(new CopyPastaBrush(player, session, rotate))
|
||||||
|
.setSize(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -792,12 +770,11 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 99
|
max = 99
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.command")
|
@CommandPermissions("worldedit.brush.command")
|
||||||
public void command(Player player, LocalSession session, double radius, CommandContext args) throws WorldEditException {
|
public BrushSettings command(Player player, LocalSession session, double radius, CommandContext args, CommandContext context) throws WorldEditException {
|
||||||
BrushTool tool = session.getBrushTool(player);
|
|
||||||
String cmd = args.getJoinedStrings(1);
|
String cmd = args.getJoinedStrings(1);
|
||||||
tool.setBrush(new CommandBrush(cmd, radius), "worldedit.brush.copy", player);
|
return get(context)
|
||||||
tool.setSize(radius);
|
.setBrush(new CommandBrush(cmd, radius))
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_COMMAND.f(cmd));
|
.setSize(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -820,7 +797,7 @@ public class BrushCommands extends MethodCommands {
|
|||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.butcher")
|
@CommandPermissions("worldedit.brush.butcher")
|
||||||
public void butcherBrush(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
public BrushSettings butcherBrush(Player player, LocalSession session, CommandContext args, CommandContext context) throws WorldEditException {
|
||||||
LocalConfiguration config = worldEdit.getConfiguration();
|
LocalConfiguration config = worldEdit.getConfiguration();
|
||||||
|
|
||||||
double radius = args.argsLength() > 0 ? args.getDouble(0) : 5;
|
double radius = args.argsLength() > 0 ? args.getDouble(0) : 5;
|
||||||
@ -833,16 +810,15 @@ public class BrushCommands extends MethodCommands {
|
|||||||
}
|
}
|
||||||
if (radius > maxRadius && maxRadius != -1) {
|
if (radius > maxRadius && maxRadius != -1) {
|
||||||
BBC.TOOL_RADIUS_ERROR.send(player, maxRadius);
|
BBC.TOOL_RADIUS_ERROR.send(player, maxRadius);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureButcher flags = new CreatureButcher(player);
|
CreatureButcher flags = new CreatureButcher(player);
|
||||||
flags.fromCommand(args);
|
flags.fromCommand(args);
|
||||||
|
|
||||||
BrushTool tool = session.getBrushTool(player);
|
return get(context)
|
||||||
tool.setSize(radius);
|
.setBrush(new ButcherBrush(flags))
|
||||||
tool.setBrush(new ButcherBrush(flags), "worldedit.brush.butcher", player);
|
.setSize(radius);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_BUTCHER.f(radius));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> inject() {
|
public static Class<?> inject() {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user