diff --git a/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java b/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java index 4e84e77f..b049c029 100644 --- a/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java +++ b/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java @@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.ResettableExtent; +import com.boydti.fawe.util.TextureUtil; import com.boydti.fawe.util.image.ImageUtil; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; @@ -78,6 +79,18 @@ public class FawePrimitiveBinding extends BindingHelper { return ImageUtil.getImage(context.next()); } + @BindingMatch( + type = {TextureUtil.class}, + behavior = BindingBehavior.PROVIDES + ) + public TextureUtil getTexture(ArgumentStack context) { + Actor actor = context.getContext().getLocals().get(Actor.class); + if (actor == null) return Fawe.get().getCachedTextureUtil(true, 0, 100); + LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor); + return session.getTextureUtil(); + } + + @BindingMatch( type = {Extent.class}, behavior = BindingBehavior.PROVIDES diff --git a/core/src/main/java/com/boydti/fawe/config/BBC.java b/core/src/main/java/com/boydti/fawe/config/BBC.java index 79dbdc1a..b244cd15 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -62,6 +62,8 @@ public enum BBC { MASK_DISABLED("Global mask disabled", "WorldEdit.General"), MASK("Global mask set", "WorldEdit.General"), + TEXTURE_DISABLED("Texturing reset", "WorldEdit.General"), + TEXTURE_SET("Set texturing to %s1", "WorldEdit.General"), SOURCE_MASK_DISABLED("Global source mask disabled", "WorldEdit.General"), SOURCE_MASK("Global source mask set", "WorldEdit.General"), TRANSFORM_DISABLED("Global transform disabled", "WorldEdit.General"), diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java index d7d2d039..738f2b54 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java @@ -116,36 +116,36 @@ public class MCAQueue extends NMSMappedFaweQueue> 4; int otherTCX = (otx) >> 4; int otherTCZ = (otz) >> 4; - int cx = newChunk.getX(); - int cz = newChunk.getZ(); - int cbx = (cx << 4) - oX; - int cbz = (cz << 4) - oZ; + int cx = newChunk.getX(); + int cz = newChunk.getZ(); + int cbx = (cx << 4) - oX; + int cbz = (cz << 4) - oZ; - boolean changed = false; - for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) { - for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) { - FaweChunk chunk; - synchronized (this) { - chunk = this.getFaweChunk(otherCX, otherCZ); - } - if (!(chunk instanceof NullFaweChunk)) { - changed = true; - MCAChunk other = (MCAChunk) chunk; - int ocbx = otherCX << 4; - int ocbz = otherCZ << 4; - int octx = ocbx + 15; - int octz = ocbz + 15; - int offsetY = 0; - int minX = obx > ocbx ? (obx - ocbx) & 15 : 0; - int maxX = otx < octx ? (otx - ocbx) : 15; - int minZ = obz > ocbz ? (obz - ocbz) & 15 : 0; - int maxZ = otz < octz ? (otz - ocbz) : 15; - int offsetX = ocbx - cbx; - int offsetZ = ocbz - cbz; - newChunk.copyFrom(other, minX, maxX, 0, 255, minZ, maxZ, offsetX, offsetY, offsetZ); + boolean changed = false; + for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) { + for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) { + FaweChunk chunk; + synchronized (this) { + chunk = this.getFaweChunk(otherCX, otherCZ); + } + if (!(chunk instanceof NullFaweChunk)) { + changed = true; + MCAChunk other = (MCAChunk) chunk; + int ocbx = otherCX << 4; + int ocbz = otherCZ << 4; + int octx = ocbx + 15; + int octz = ocbz + 15; + int offsetY = 0; + int minX = obx > ocbx ? (obx - ocbx) & 15 : 0; + int maxX = otx < octx ? (otx - ocbx) : 15; + int minZ = obz > ocbz ? (obz - ocbz) & 15 : 0; + int maxZ = otz < octz ? (otz - ocbz) : 15; + int offsetX = ocbx - cbx; + int offsetZ = ocbz - cbz; + newChunk.copyFrom(other, minX, maxX, 0, 255, minZ, maxZ, offsetX, offsetY, offsetZ); + } } } - } return changed; } @@ -530,7 +530,7 @@ public class MCAQueue extends NMSMappedFaweQueue= 255 || PseudoRandom.random.random(maxY) < val) { + editSession.setBlock(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), pattern); + } + return true; + } + } + return false; + } + }, new RegionFunction() { + @Override + public boolean apply(Vector vector) throws WorldEditException { + return true; + } + }, Integer.MAX_VALUE, editSession); + visitor.setDirections(Arrays.asList(visitor.DIAGONAL_DIRECTIONS)); + visitor.visit(position); + Operations.completeBlindly(visitor); + } + + private void apply(double val) { + + } +} \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java b/core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java index 4eb8caf9..031f903c 100644 --- a/core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java +++ b/core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java @@ -1,5 +1,6 @@ package com.boydti.fawe.object.collection; +import com.boydti.fawe.util.MainUtil; import java.lang.ref.Reference; import java.lang.reflect.Array; import java.lang.reflect.Field; @@ -40,17 +41,7 @@ public abstract class IterableThreadLocal extends ThreadLocal implements I public static void clean(ThreadLocal instance) { try { - ThreadGroup rootGroup = Thread.currentThread( ).getThreadGroup( ); - ThreadGroup parentGroup; - while ( ( parentGroup = rootGroup.getParent() ) != null ) { - rootGroup = parentGroup; - } - Thread[] threads = new Thread[ rootGroup.activeCount() ]; - if (threads.length != 0) { - while (rootGroup.enumerate(threads, true) == threads.length) { - threads = new Thread[threads.length * 2]; - } - } + Thread[] threads = MainUtil.getThreads(); Field tl = Thread.class.getDeclaredField("threadLocals"); tl.setAccessible(true); Method methodRemove = null; diff --git a/core/src/main/java/com/boydti/fawe/object/io/RandomAccessInputStream.java b/core/src/main/java/com/boydti/fawe/object/io/RandomAccessInputStream.java index 9ecaec8c..cca1cd95 100644 --- a/core/src/main/java/com/boydti/fawe/object/io/RandomAccessInputStream.java +++ b/core/src/main/java/com/boydti/fawe/object/io/RandomAccessInputStream.java @@ -16,6 +16,16 @@ public class RandomAccessInputStream extends InputStream { return raf.read(); } + @Override + public int read(byte[] b, int off, int len) throws IOException { + return raf.read(b, off, len); + } + + @Override + public int read(byte[] b) throws IOException { + return raf.read(b); + } + @Override public int available() throws IOException { return (int) (raf.length() - raf.getFilePointer()); diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java index cf69be61..b59a7cb4 100644 --- a/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java +++ b/core/src/main/java/com/boydti/fawe/object/pattern/AngleColorPattern.java @@ -3,7 +3,7 @@ package com.boydti.fawe.object.pattern; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.DataAnglePattern; -import com.boydti.fawe.util.TextureUtil; +import com.boydti.fawe.util.TextureHolder; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; @@ -11,16 +11,11 @@ import com.sk89q.worldedit.extent.Extent; import java.io.IOException; public class AngleColorPattern extends DataAnglePattern { - private transient TextureUtil util; + protected transient TextureHolder util; - private final boolean randomize; - private final int complexity; - - public AngleColorPattern(Extent extent, int complexity, boolean randomize, int distance) { + public AngleColorPattern(Extent extent, TextureHolder util, int distance) { super(extent, distance); - this.complexity = complexity; - this.randomize = randomize; - this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + this.util = util; } public int getColor(int color, int slope) { @@ -37,10 +32,10 @@ public class AngleColorPattern extends DataAnglePattern { BaseBlock block = extent.getBlock(position); int slope = getSlope(block, position); if (slope == -1) return block; - int color = util.getColor(block); + int color = util.getTextureUtil().getColor(block); if (color == 0) return block; int newColor = getColor(color, slope); - return util.getNearestBlock(newColor); + return util.getTextureUtil().getNearestBlock(newColor); } @Override @@ -66,16 +61,16 @@ public class AngleColorPattern extends DataAnglePattern { BaseBlock block = extent.getBlock(getPosition); int slope = getSlope(block, getPosition); if (slope == -1) return false; - int color = util.getColor(block); + int color = util.getTextureUtil().getColor(block); if (color == 0) return false; int newColor = getColor(color, slope); - BaseBlock newBlock = util.getNearestBlock(newColor); + BaseBlock newBlock = util.getTextureUtil().getNearestBlock(newColor); if (newBlock == null) return false; return extent.setBlock(setPosition, newBlock); } private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + util = Fawe.get().getCachedTextureUtil(true, 0, 100); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/AverageColorPattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/AverageColorPattern.java index 405c45ae..12a6195d 100644 --- a/core/src/main/java/com/boydti/fawe/object/pattern/AverageColorPattern.java +++ b/core/src/main/java/com/boydti/fawe/object/pattern/AverageColorPattern.java @@ -1,6 +1,7 @@ package com.boydti.fawe.object.pattern; import com.boydti.fawe.Fawe; +import com.boydti.fawe.util.TextureHolder; import com.boydti.fawe.util.TextureUtil; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; @@ -10,22 +11,19 @@ import java.awt.Color; import java.io.IOException; public class AverageColorPattern extends AbstractExtentPattern { - private transient TextureUtil util; - private final boolean randomize; - private final int complexity; + private transient TextureHolder holder; private final int color; - public AverageColorPattern(Extent extent, int color, int complexity, boolean randomize) { + public AverageColorPattern(Extent extent, int color, TextureHolder util) { super(extent); - this.complexity = complexity; - this.randomize = randomize; - this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + this.holder = util; this.color = new Color(color).getRGB(); } @Override public BaseBlock apply(Vector position) { BaseBlock block = getExtent().getBlock(position); + TextureUtil util = holder.getTextureUtil(); int currentColor = util.getColor(block); int newColor = util.averageColor(currentColor, color); return util.getNearestBlock(newColor); @@ -34,6 +32,7 @@ public class AverageColorPattern extends AbstractExtentPattern { @Override public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException { BaseBlock block = extent.getBlock(getPosition); + TextureUtil util = holder.getTextureUtil(); int currentColor = util.getColor(block); if (currentColor == 0) return false; int newColor = util.averageColor(currentColor, color); @@ -44,6 +43,6 @@ public class AverageColorPattern extends AbstractExtentPattern { private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + holder = Fawe.get().getCachedTextureUtil(true, 0, 100); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/DesaturatePattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/DesaturatePattern.java index 3af507ff..db0529f9 100644 --- a/core/src/main/java/com/boydti/fawe/object/pattern/DesaturatePattern.java +++ b/core/src/main/java/com/boydti/fawe/object/pattern/DesaturatePattern.java @@ -1,6 +1,7 @@ package com.boydti.fawe.object.pattern; import com.boydti.fawe.Fawe; +import com.boydti.fawe.util.TextureHolder; import com.boydti.fawe.util.TextureUtil; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; @@ -10,23 +11,20 @@ import com.sk89q.worldedit.function.pattern.AbstractPattern; import java.io.IOException; public class DesaturatePattern extends AbstractPattern { - private transient TextureUtil util; - private final boolean randomize; - private final int complexity; + private transient TextureHolder holder; private final Extent extent; private final double value; - public DesaturatePattern(Extent extent, double value, int complexity, boolean randomize) { + public DesaturatePattern(Extent extent, double value, TextureHolder util) { this.extent = extent; - this.complexity = complexity; - this.randomize = randomize; - this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + this.holder = util; this.value = Math.max(0, Math.min(1, value)); } @Override public BaseBlock apply(Vector position) { BaseBlock block = extent.getBlock(position); + TextureUtil util = holder.getTextureUtil(); int color = util.getColor(block); int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; @@ -43,6 +41,7 @@ public class DesaturatePattern extends AbstractPattern { @Override public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException { BaseBlock block = extent.getBlock(getPosition); + TextureUtil util = holder.getTextureUtil(); int color = util.getColor(block); int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; @@ -65,6 +64,6 @@ public class DesaturatePattern extends AbstractPattern { private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + holder = Fawe.get().getCachedTextureUtil(true, 0, 100); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/SaturatePattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/SaturatePattern.java index f55f8993..a3568433 100644 --- a/core/src/main/java/com/boydti/fawe/object/pattern/SaturatePattern.java +++ b/core/src/main/java/com/boydti/fawe/object/pattern/SaturatePattern.java @@ -1,6 +1,7 @@ package com.boydti.fawe.object.pattern; import com.boydti.fawe.Fawe; +import com.boydti.fawe.util.TextureHolder; import com.boydti.fawe.util.TextureUtil; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; @@ -11,24 +12,21 @@ import java.awt.Color; import java.io.IOException; public class SaturatePattern extends AbstractPattern { - private transient TextureUtil util; - private final boolean randomize; - private final int complexity; + private transient TextureHolder holder; private final int color; private final Extent extent; - public SaturatePattern(Extent extent, int color, int complexity, boolean randomize) { + public SaturatePattern(Extent extent, int color, TextureHolder texture) { this.extent = extent; - this.complexity = complexity; - this.randomize = randomize; - this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + this.holder = texture; this.color = new Color(color).getRGB(); } @Override public BaseBlock apply(Vector position) { BaseBlock block = extent.getBlock(position); + TextureUtil util = holder.getTextureUtil(); int currentColor = util.getColor(block); int newColor = util.multiplyColor(currentColor, color); return util.getNearestBlock(newColor); @@ -37,6 +35,7 @@ public class SaturatePattern extends AbstractPattern { @Override public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException { BaseBlock block = extent.getBlock(getPosition); + TextureUtil util = holder.getTextureUtil(); int currentColor = util.getColor(block); if (currentColor == 0) return false; int newColor = util.multiplyColor(currentColor, color); @@ -47,6 +46,6 @@ public class SaturatePattern extends AbstractPattern { private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + holder = Fawe.get().getCachedTextureUtil(true, 0, 100); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/pattern/ShadePattern.java b/core/src/main/java/com/boydti/fawe/object/pattern/ShadePattern.java index 79e64d53..1c44a0ce 100644 --- a/core/src/main/java/com/boydti/fawe/object/pattern/ShadePattern.java +++ b/core/src/main/java/com/boydti/fawe/object/pattern/ShadePattern.java @@ -13,17 +13,13 @@ import static com.google.common.base.Preconditions.checkNotNull; public class ShadePattern extends AbstractPattern { private transient TextureUtil util; - private final boolean randomize; - private final int complexity; private final Extent extent; private final boolean darken; - public ShadePattern(Extent extent, boolean darken, int complexity, boolean randomize) { + public ShadePattern(Extent extent, boolean darken, TextureUtil util) { checkNotNull(extent); this.extent = extent; - this.complexity = complexity; - this.randomize = randomize; - this.util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + this.util = util; this.darken = darken; } @@ -35,6 +31,6 @@ public class ShadePattern extends AbstractPattern { private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); - util = Fawe.get().getCachedTextureUtil(randomize, 0, complexity); + util = Fawe.get().getCachedTextureUtil(true, 0, 100); } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/util/MainUtil.java b/core/src/main/java/com/boydti/fawe/util/MainUtil.java index 899a6882..c3230611 100644 --- a/core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -488,7 +488,7 @@ public class MainUtil { private static final Class[] parameters = new Class[]{URL.class}; - public static void loadURLClasspath(URL u) throws IOException { + public static ClassLoader loadURLClasspath(URL u) throws IOException { ClassLoader sysloader = ClassLoader.getSystemClassLoader(); Class sysclass = URLClassLoader.class; @@ -496,11 +496,27 @@ public class MainUtil { try { Method method = sysclass.getDeclaredMethod("addURL", parameters); method.setAccessible(true); - method.invoke(sysloader, new Object[]{u}); - } catch (Throwable t) { - t.printStackTrace(); - throw new IOException("Error, could not add URL to system classloader"); + if (sysloader instanceof URLClassLoader) { + System.out.println("Sys loader"); + method.invoke(sysloader, new Object[]{u}); + } else { + System.out.println("Not sys loader"); + ClassLoader loader = MainUtil.class.getClassLoader(); + while (!(loader instanceof URLClassLoader) && loader.getParent() != null) { + loader = loader.getParent(); + } + if (loader instanceof URLClassLoader) { + method.invoke(sysloader, new Object[]{u}); + } else { + loader = new URLClassLoader(new URL[]{u}, MainUtil.class.getClassLoader()); + System.out.println("Loaded true"); + return loader; + } + } + } catch (Throwable ignore) { + ignore.printStackTrace(); } + return sysloader; } public static String getText(String url) throws IOException { @@ -578,6 +594,21 @@ public class MainUtil { } } + public static Thread[] getThreads() { + ThreadGroup rootGroup = Thread.currentThread( ).getThreadGroup( ); + ThreadGroup parentGroup; + while ( ( parentGroup = rootGroup.getParent() ) != null ) { + rootGroup = parentGroup; + } + Thread[] threads = new Thread[ rootGroup.activeCount() ]; + if (threads.length != 0) { + while (rootGroup.enumerate(threads, true) == threads.length) { + threads = new Thread[threads.length * 2]; + } + } + return threads; + } + public static File copyFile(File sourceFile, File destFile) throws IOException { if (!destFile.exists()) { File parent = destFile.getParentFile(); diff --git a/core/src/main/java/com/boydti/fawe/util/TextureHolder.java b/core/src/main/java/com/boydti/fawe/util/TextureHolder.java new file mode 100644 index 00000000..8d6496f3 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/util/TextureHolder.java @@ -0,0 +1,5 @@ +package com.boydti.fawe.util; + +public interface TextureHolder { + TextureUtil getTextureUtil(); +} diff --git a/core/src/main/java/com/boydti/fawe/util/TextureUtil.java b/core/src/main/java/com/boydti/fawe/util/TextureUtil.java index addd58e8..f5ed4d90 100644 --- a/core/src/main/java/com/boydti/fawe/util/TextureUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/TextureUtil.java @@ -3,12 +3,17 @@ package com.boydti.fawe.util; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.pattern.PatternExtent; import com.boydti.fawe.util.image.ImageUtil; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; +import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.world.registry.BundledBlockData; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -26,7 +31,42 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.imageio.ImageIO; -public class TextureUtil { +public class TextureUtil implements TextureHolder { + public static TextureUtil fromClipboard(Clipboard clipboard) throws FileNotFoundException { + boolean[] ids = new boolean[Character.MAX_VALUE + 1]; + for (Vector pt : clipboard.getRegion()) { + ids[clipboard.getBlock(pt).getCombined()] = true; + } + HashSet blocks = new HashSet<>(); + for (int combined = 0; combined < ids.length; combined++) { + if (ids[combined]) blocks.add(FaweCache.CACHE_BLOCK[combined]); + } + return fromBlocks(blocks); + } + + public static TextureUtil fromBlocks(Set blocks) throws FileNotFoundException { + return new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks); + } + + public static TextureUtil fromMask(Mask mask) throws FileNotFoundException { + HashSet blocks = new HashSet<>(); + BlockPattern pattern = new BlockPattern(new BaseBlock(BlockID.AIR)); + PatternExtent extent = new PatternExtent(pattern); + new MaskTraverser(mask).reset(extent); + TextureUtil tu = Fawe.get().getTextureUtil(); + for (int combinedId : tu.getValidBlockIds()) { + BaseBlock block = FaweCache.CACHE_BLOCK[combinedId]; + pattern.setBlock(block); + if (mask.test(Vector.ZERO)) blocks.add(block); + } + return fromBlocks(blocks); + } + + @Override + public TextureUtil getTextureUtil() { + return this; + } + private final File folder; private static final int[] FACTORS = new int[766]; diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java index 0fa32e6a..9809e1a5 100644 --- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -33,9 +33,7 @@ import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.clipboard.MultiClipboardHolder; import com.boydti.fawe.object.collection.SparseBitSet; import com.boydti.fawe.object.extent.ResettableExtent; -import com.boydti.fawe.util.EditSessionBuilder; -import com.boydti.fawe.util.MainUtil; -import com.boydti.fawe.util.StringMan; +import com.boydti.fawe.util.*; import com.boydti.fawe.util.cui.CUI; import com.boydti.fawe.wrappers.WorldWrapper; import com.sk89q.jchronic.Chronic; @@ -74,7 +72,7 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Stores session information. */ -public class LocalSession { +public class LocalSession implements TextureHolder { @Deprecated public transient static int MAX_HISTORY_SIZE = 15; @@ -117,6 +115,7 @@ public class LocalSession { private transient boolean fastMode = false; private transient Mask mask; private transient Mask sourceMask; + private transient TextureUtil texture; private transient ResettableExtent transform = null; private transient TimeZone timezone = TimeZone.getDefault(); @@ -1430,6 +1429,28 @@ public class LocalSession { setSourceMask(mask != null ? Masks.wrap(mask) : null); } + public void setTextureUtil(TextureUtil texture) { + synchronized (this) { + this.texture = texture; + } + } + + /** + * Get the TextureUtil currently being used + * @return + */ + @Override + public TextureUtil getTextureUtil() { + TextureUtil tmp = texture; + if (tmp == null) { + synchronized (this) { + tmp = Fawe.get().getCachedTextureUtil(true, 0, 100); + this.texture = tmp; + } + } + return tmp; + } + public ResettableExtent getTransform() { return transform; } diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index fe1ee8c1..70f9ddd4 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -391,6 +391,36 @@ public class BrushCommands extends MethodCommands { .setFill(fill); } + @Command( + aliases = {"stencil", "color"}, + usage = " [radius=5] [file|#clipboard|imgur=null] [rotation=360] [yscale=1.0]", + desc = "Use a height map to paint a surface", + help = + "Use a height map to paint any surface.\n" + + "The -w flag will only apply at maximum saturation\n" + + "The -r flag will apply random rotation", + min = 1, + max = -1 + ) + @CommandPermissions("worldedit.brush.stencil") + public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + InputStream stream = getHeightmapStream(image); + HeightBrush brush; + try { + brush = new StencilBrush(stream, rotation, yscale, onlyWhite, image.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null); + } catch (EmptyClipboardException ignore) { + brush = new StencilBrush(stream, rotation, yscale, onlyWhite, null); + } + if (randomRotate) { + brush.setRandomRotate(true); + } + return set(session, context, + brush) + .setSize(radius) + .setFill(fill); + } + // @Command( // aliases = {"image", "img"} // // TODO directional image coloring diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushOptionsCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushOptionsCommands.java index a075db12..e04fe2f8 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushOptionsCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushOptionsCommands.java @@ -345,7 +345,7 @@ public class BrushOptionsCommands extends MethodCommands { min = 0, max = -1 ) - @CommandPermissions("worldedit.brush.options.mask") + @CommandPermissions({"worldedit.brush.options.mask", "worldedit.mask.brush"}) public void mask(Player player, LocalSession session, EditSession editSession, @Optional @Switch('h') boolean offHand, CommandContext context) throws WorldEditException { BrushTool tool = session.getBrushTool(player, false); if (tool == null) { @@ -378,7 +378,7 @@ public class BrushOptionsCommands extends MethodCommands { min = 0, max = -1 ) - @CommandPermissions("worldedit.brush.options.mask") + @CommandPermissions({"worldedit.brush.options.mask", "worldedit.mask.brush"}) public void smask(Player player, LocalSession session, EditSession editSession, @Optional @Switch('h') boolean offHand, CommandContext context) throws WorldEditException { BrushTool tool = session.getBrushTool(player, false); if (tool == null) { @@ -410,7 +410,7 @@ public class BrushOptionsCommands extends MethodCommands { min = 0, max = -1 ) - @CommandPermissions("worldedit.brush.options.transform") + @CommandPermissions({"worldedit.brush.options.transform", "worldedit.transform.brush"}) public void transform(Player player, LocalSession session, EditSession editSession, @Optional @Switch('h') boolean offHand, CommandContext context) throws WorldEditException { BrushTool tool = session.getBrushTool(player, false); if (tool == null) { diff --git a/core/src/main/java/com/sk89q/worldedit/command/OptionsCommands.java b/core/src/main/java/com/sk89q/worldedit/command/OptionsCommands.java index 30d64085..0b99bfcd 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/OptionsCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/OptionsCommands.java @@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.extent.ResettableExtent; +import com.boydti.fawe.util.*; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; @@ -11,12 +12,17 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.ItemType; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.util.command.parametric.ParameterException; +import java.io.FileNotFoundException; +import java.util.HashSet; import static com.google.common.base.Preconditions.checkNotNull; @@ -82,6 +88,68 @@ public class OptionsCommands { } } + @Command( + aliases = {"/gtexture", "gtexture"}, + usage = "[mask|#clipboard|complexity] [randomization=true]", + help = "The global destination mask applies to all edits you do and masks based on the destination blocks (i.e. the blocks in the world).", + desc = "Set the global mask", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.global-texture") + public void gtexture(FawePlayer player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException, FileNotFoundException, ParameterException { + if (context == null || context.argsLength() == 0) { + session.setTextureUtil(null); + BBC.TEXTURE_DISABLED.send(player); + } else { + String arg = context.getString(0); + String argLower = arg.toLowerCase(); + + TextureUtil util = Fawe.get().getTextureUtil(); + int randomIndex = 1; + boolean checkRandomization = true; + if (context.argsLength() >= 2 && MathMan.isInteger(context.getString(0)) && MathMan.isInteger(context.getString(1))) { + // complexity + int min = Integer.parseInt(context.getString(0)); + int max = Integer.parseInt(context.getString(1)); + if (min < 0 || max > 100) throw new ParameterException("Complexity must be in the range 0-100"); + + System.out.println("Clean " + min + " | " + max); + if (min != 0 || max != 100) util = new CleanTextureUtil(util, min, max); + + randomIndex = 2; + } else if (context.argsLength() == 1 && argLower.equals("true") || argLower.equals("false")) { + if (argLower.equals("true")) util = new RandomTextureUtil(util); + checkRandomization = false; + } else { + HashSet blocks = null; + if (argLower.equals("#copy") || argLower.equals("#clipboard")) { + Clipboard clipboard = player.getSession().getClipboard().getClipboard(); + util = TextureUtil.fromClipboard(clipboard); + } else if (argLower.equals("*") || argLower.equals("true")) { + util = Fawe.get().getTextureUtil(); + } else { + ParserContext parserContext = new ParserContext(); + parserContext.setActor(player.getPlayer()); + parserContext.setWorld(player.getWorld()); + parserContext.setSession(session); + parserContext.setExtent(editSession); + Mask mask = worldEdit.getMaskFactory().parseFromInput(arg, parserContext); + util = TextureUtil.fromMask(mask); + } + } + if (checkRandomization) { + if (context.argsLength() > randomIndex) { + boolean random = Boolean.parseBoolean(context.getString(randomIndex)); + if (random) util = new RandomTextureUtil(util); + } + } + if (!(util instanceof CachedTextureUtil)) util = new CachedTextureUtil(util); + session.setTextureUtil(util); + BBC.TEXTURE_SET.send(player, context.getJoinedStrings(0)); + } + } + @Command( aliases = {"/gmask", "gmask", "globalmask", "/globalmask"}, usage = "[mask]", @@ -90,7 +158,7 @@ public class OptionsCommands { min = 0, max = -1 ) - @CommandPermissions("worldedit.global-mask") + @CommandPermissions({"worldedit.global-mask", "worldedit.mask.global"}) public void gmask(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException { if (context == null || context.argsLength() == 0) { session.setMask((Mask) null); @@ -115,7 +183,7 @@ public class OptionsCommands { min = 0, max = -1 ) - @CommandPermissions("worldedit.global-mask") + @CommandPermissions({"worldedit.global-mask", "worldedit.mask.global"}) public void gsmask(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException { if (context == null || context.argsLength() == 0) { session.setSourceMask((Mask) null); @@ -139,7 +207,7 @@ public class OptionsCommands { min = 0, max = -1 ) - @CommandPermissions("worldedit.global-transform") + @CommandPermissions({"worldedit.global-transform", "worldedit.transform.global"}) public void gtransform(Player player, EditSession editSession, LocalSession session, @Optional CommandContext context) throws WorldEditException { if (context == null || context.argsLength() == 0) { session.setTransform(null); diff --git a/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java b/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java index 4b0610c4..037c3bba 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java @@ -1,38 +1,10 @@ package com.sk89q.worldedit.command; -import com.boydti.fawe.Fawe; import com.boydti.fawe.object.DataAnglePattern; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.clipboard.MultiClipboardHolder; import com.boydti.fawe.object.collection.RandomCollection; -import com.boydti.fawe.object.pattern.AngleColorPattern; -import com.boydti.fawe.object.pattern.AverageColorPattern; -import com.boydti.fawe.object.pattern.BiomePattern; -import com.boydti.fawe.object.pattern.BufferedPattern; -import com.boydti.fawe.object.pattern.BufferedPattern2D; -import com.boydti.fawe.object.pattern.DataPattern; -import com.boydti.fawe.object.pattern.DesaturatePattern; -import com.boydti.fawe.object.pattern.ExistingPattern; -import com.boydti.fawe.object.pattern.ExpressionPattern; -import com.boydti.fawe.object.pattern.FullClipboardPattern; -import com.boydti.fawe.object.pattern.IdDataMaskPattern; -import com.boydti.fawe.object.pattern.IdPattern; -import com.boydti.fawe.object.pattern.Linear2DBlockPattern; -import com.boydti.fawe.object.pattern.Linear3DBlockPattern; -import com.boydti.fawe.object.pattern.LinearBlockPattern; -import com.boydti.fawe.object.pattern.MaskedPattern; -import com.boydti.fawe.object.pattern.NoXPattern; -import com.boydti.fawe.object.pattern.NoYPattern; -import com.boydti.fawe.object.pattern.NoZPattern; -import com.boydti.fawe.object.pattern.OffsetPattern; -import com.boydti.fawe.object.pattern.PatternExtent; -import com.boydti.fawe.object.pattern.RandomFullClipboardPattern; -import com.boydti.fawe.object.pattern.RandomOffsetPattern; -import com.boydti.fawe.object.pattern.RelativePattern; -import com.boydti.fawe.object.pattern.SaturatePattern; -import com.boydti.fawe.object.pattern.ShadePattern; -import com.boydti.fawe.object.pattern.SolidRandomOffsetPattern; -import com.boydti.fawe.object.pattern.SurfaceRandomOffsetPattern; +import com.boydti.fawe.object.pattern.*; import com.boydti.fawe.object.random.SimplexRandom; import com.boydti.fawe.util.ColorUtil; import com.boydti.fawe.util.TextureUtil; @@ -116,9 +88,9 @@ public class PatternCommands extends MethodCommands { min = 1, max = 1 ) - public Pattern color(String arg) { + public Pattern color(TextureUtil textureUtil, String arg) { Color color = ColorUtil.parseColor(arg); - return Fawe.get().getTextureUtil().getNearestBlock(color.getRGB()); + return textureUtil.getNearestBlock(color.getRGB()); } @Command( @@ -128,9 +100,8 @@ public class PatternCommands extends MethodCommands { min = 0, max = 3 ) - public Pattern anglecolor(Extent extent, @Optional("true") boolean randomize, @Optional("100") double maxComplexity, @Optional("1") int distance) { - TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity); - return new AngleColorPattern(extent, (int) maxComplexity, randomize, distance); + public Pattern anglecolor(Extent extent, LocalSession session, @Optional("true") boolean randomize, @Optional("100") double maxComplexity, @Optional("1") int distance) { + return new AngleColorPattern(extent, session, distance); } @Command( @@ -145,27 +116,25 @@ public class PatternCommands extends MethodCommands { @Command( aliases = {"#saturate"}, desc = "Saturate the existing block with a color", - usage = " [randomize=true] [max-complexity=100]", + usage = "", min = 1, max = 3 ) - public Pattern saturate(Extent extent, String arg, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) { - TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity); + public Pattern saturate(Extent extent, LocalSession session, String arg) { Color color = ColorUtil.parseColor(arg); - return new SaturatePattern(extent, color.getRGB(), (int) maxComplexity, randomize); + return new SaturatePattern(extent, color.getRGB(), session); } @Command( aliases = {"#averagecolor"}, desc = "Average between the existing block and a color", - usage = " [randomize=true] [max-complexity=100]", + usage = "", min = 1, max = 3 ) - public Pattern averagecolor(Extent extent, String arg, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) { - TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity); + public Pattern averagecolor(Extent extent, LocalSession session, String arg) { Color color = ColorUtil.parseColor(arg); - return new AverageColorPattern(extent, color.getRGB(), (int) maxComplexity, randomize); + return new AverageColorPattern(extent, color.getRGB(), session); } @Command( @@ -175,33 +144,28 @@ public class PatternCommands extends MethodCommands { min = 0, max = 3 ) - public Pattern desaturate(Extent extent, @Optional("100") double percent, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) { - TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity); - return new DesaturatePattern(extent, percent / 100d, (int) maxComplexity, randomize); + public Pattern desaturate(Extent extent, LocalSession session, @Optional("100") double percent) { + return new DesaturatePattern(extent, percent / 100d, session); } @Command( aliases = {"#lighten"}, desc = "Lighten the existing block", - usage = "[randomize=true] [max-complexity=100]", min = 0, max = 2 ) - public Pattern lighten(Extent extent, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) { - TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity); - return new ShadePattern(extent, false, (int) maxComplexity, randomize); + public Pattern lighten(Extent extent, TextureUtil util) { + return new ShadePattern(extent, false, util); } @Command( aliases = {"#darken"}, desc = "Darken the existing block", - usage = "[randomize=true] [max-complexity=100]", min = 0, max = 2 ) - public Pattern darken(Extent extent, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) { - TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity); - return new ShadePattern(extent, true, (int) maxComplexity, randomize); + public Pattern darken(Extent extent, TextureUtil util) { + return new ShadePattern(extent, true, util); } @Command(