I forgot to commit everything

This commit is contained in:
Jesse Boyd 2016-09-28 22:48:20 +10:00
parent bd90df7635
commit 76b4bb4857
8 changed files with 372 additions and 8 deletions

View File

@ -76,6 +76,7 @@ import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.io.File;
@ -336,6 +337,7 @@ public class Fawe {
EditSessionEvent.inject(); // Add EditSession to event
LocalSession.inject(); // Add remember order / queue flushing
SessionManager.inject(); // Custom session saving
Request.inject(); // Custom pattern extent
// Commands
BrushCommands.inject(); // Translations + heightmap
ToolCommands.inject(); // Translations + inspect

View File

@ -0,0 +1,33 @@
package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import java.util.Arrays;
import java.util.List;
public class MaskedPattern extends AbstractPattern {
private final PatternExtent patternExtent;
private final Pattern secondaryPattern;
private final List<Pattern> patterns;
private Mask mask;
public MaskedPattern(Mask mask, PatternExtent primary, Pattern secondary) {
this.mask = mask;
this.patternExtent = primary;
this.secondaryPattern = secondary;
this.patterns = Arrays.asList(primary, secondary);
}
@Override
public BaseBlock apply(Vector position) {
if (mask.test(position)) {
return patternExtent.apply(position);
}
return secondaryPattern.apply(position);
}
}

View File

@ -0,0 +1,95 @@
package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
public class PatternExtent extends AbstractPattern implements Extent {
private final Pattern pattern;
private BaseBlock block;
public PatternExtent(Pattern pattern) {
this.pattern = pattern;
}
@Override
public Vector getMinimumPoint() {
return new Vector(Integer.MIN_VALUE,0,Integer.MIN_VALUE);
}
@Override
public Vector getMaximumPoint() {
return new Vector(Integer.MAX_VALUE,255,Integer.MAX_VALUE);
}
@Override
public List<? extends Entity> getEntities(Region region) {
return new ArrayList<>();
}
@Override
public List<? extends Entity> getEntities() {
return new ArrayList<>();
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
return null;
}
@Override
public BaseBlock getBlock(Vector position) {
return block = pattern.apply(position);
}
public BaseBlock getAndResetBlock() {
BaseBlock result = block;
block = null;
return result;
}
@Override
public BaseBlock getLazyBlock(Vector position) {
return getBlock(position);
}
@Override
public BaseBiome getBiome(Vector2D position) {
return new BaseBiome(0);
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
return false;
}
@Override
public boolean setBiome(Vector2D position, BaseBiome biome) {
return false;
}
@Nullable
@Override
public Operation commit() {
return null;
}
@Override
public BaseBlock apply(Vector position) {
return pattern.apply(position);
}
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.pattern;
import com.boydti.fawe.object.mask.ResettableMask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import java.lang.reflect.Field;
@ -23,6 +24,9 @@ public class PatternTraverser {
if (pattern instanceof ResettablePattern) {
((ResettablePattern) pattern).reset();
}
if (pattern instanceof ResettableMask) {
((ResettableMask) pattern).reset();
}
Class<?> current = pattern.getClass();
while(current.getSuperclass() != null) {
if (newExtent != null) {
@ -35,7 +39,13 @@ public class PatternTraverser {
try {
Field field = current.getDeclaredField("pattern");
field.setAccessible(true);
Pattern next = (Pattern) field.get(pattern);
Object next = field.get(pattern);
reset(next, newExtent);
} catch (NoSuchFieldException | IllegalAccessException ignore) {}
try {
Field field = current.getDeclaredField("mask");
field.setAccessible(true);
Object next = field.get(pattern);
reset(next, newExtent);
} catch (NoSuchFieldException | IllegalAccessException ignore) {}
try {

View File

@ -0,0 +1,33 @@
package com.boydti.fawe.object.pattern;
import com.boydti.fawe.object.PseudoRandom;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
public class RandomOffsetPattern extends AbstractPattern {
private final PseudoRandom r = new PseudoRandom();
private final int dx, dy, dz, dx2, dy2, dz2;
private final Pattern pattern;
private final Vector mutable = new Vector();
public RandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
this.pattern = pattern;
this.dx = dx;
this.dy = dy;
this.dz = dz;
this.dx2 = dx * 2 + 1;
this.dy2 = dy * 2 + 1;
this.dz2 = dz * 2 + 1;
}
@Override
public BaseBlock apply(Vector position) {
mutable.x = position.x + r.nextInt(dx2) - dx;
mutable.y = position.y + r.nextInt(dy2) - dy;
mutable.z = position.z + r.nextInt(dz2) - dz;
return pattern.apply(mutable);
}
}

View File

@ -97,7 +97,7 @@ public class DefaultMaskParser extends InputParser<Mask> {
}
private Mask getBlockMaskComponent(List<Mask> masks, String component, ParserContext context) throws InputParseException {
Extent extent = Request.request().getEditSession();
Extent extent = Request.request().getExtent();
final char firstChar = component.charAt(0);
switch (firstChar) {

View File

@ -3,9 +3,12 @@ package com.sk89q.worldedit.extension.factory;
import com.boydti.fawe.object.pattern.ExistingPattern;
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.PatternExtent;
import com.boydti.fawe.object.pattern.RandomOffsetPattern;
import com.boydti.fawe.object.pattern.RelativePattern;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
@ -13,13 +16,16 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
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.function.pattern.ClipboardPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.session.request.Request;
import java.util.ArrayList;
import java.util.List;
public class HashTagPatternParser extends InputParser<Pattern> {
@ -27,6 +33,26 @@ public class HashTagPatternParser extends InputParser<Pattern> {
super(worldEdit);
}
private List<String> split(String input, char delim) {
List<String> result = new ArrayList<String>();
int start = 0;
boolean inQuotes = false;
for (int current = 0; current < input.length(); current++) {
if (input.charAt(current) == '\"') inQuotes = !inQuotes; // toggle state
boolean atLastChar = (current == input.length() - 1);
if(atLastChar) result.add(input.substring(start));
else if (input.charAt(current) == delim && !inQuotes) {
String toAdd = input.substring(start, current);
if (toAdd.startsWith("\"")) {
toAdd = toAdd.substring(1, toAdd.length() - 1);
}
result.add(toAdd);
start = current + 1;
}
}
return result;
}
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
switch (input.toLowerCase().charAt(0)) {
@ -77,10 +103,43 @@ public class HashTagPatternParser extends InputParser<Pattern> {
case "#noz": {
return new NoZPattern(parseFromInput(rest, context));
}
case "#mask": {
List<String> split3 = split(rest, ':');
if (split3.size() != 3) {
throw new InputParseException("The correct format is #mask:<mask>:<pattern-if>:<pattern-else>");
}
Pattern primary = parseFromInput(split3.get(1), context);
Pattern secondary = parseFromInput(split3.get(2), context);
PatternExtent extent = new PatternExtent(primary);
Request request = Request.request();
request.setExtent(extent);
request.setSession(context.getSession());
request.setWorld(context.getWorld());
context.setExtent(extent);
MaskFactory factory = worldEdit.getMaskFactory();
Mask mask = factory.parseFromInput(split3.get(0), context);
if (mask == null | primary == null || secondary == null) {
throw new InputParseException("The correct format is #mask:<mask>;<pattern-if>;<pattern-else> (null provided)");
}
return new MaskedPattern(mask, extent, secondary);
}
case "#randomoffset":
case "#spread": {
try {
int x = Math.abs(Integer.parseInt(split2[1]));
int y = Math.abs(Integer.parseInt(split2[2]));
int z = Math.abs(Integer.parseInt(split2[3]));
rest = rest.substring(split2[1].length() + split2[2].length() + split2[3].length() + 3);
Pattern pattern = parseFromInput(rest, context);
return new RandomOffsetPattern(pattern, x, y, z);
} catch (NumberFormatException e) {
}
}
case "#l":
case "#linear": {
ArrayList<Pattern> patterns = new ArrayList<>();
for (String token : rest.split(",")) {
for (String token : split(rest, ',')) {
patterns.add(parseFromInput(token, context));
}
if (patterns.isEmpty()) {
@ -91,7 +150,7 @@ public class HashTagPatternParser extends InputParser<Pattern> {
case "#l3d":
case "#linear3D": {
ArrayList<Pattern> patterns = new ArrayList<>();
for (String token : rest.split(",")) {
for (String token : split(rest, ',')) {
patterns.add(parseFromInput(token, context));
}
if (patterns.isEmpty()) {
@ -104,13 +163,13 @@ public class HashTagPatternParser extends InputParser<Pattern> {
throw new InputParseException("Invalid, see: https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-and-FAWE-patterns");
}
default:
String[] items = input.split(",");
if (items.length == 1) {
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items[0], context));
List<String> items = split(input, ',');
if (items.size() == 1) {
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items.get(0), context));
}
BlockFactory blockRegistry = worldEdit.getBlockFactory();
RandomPattern randomPattern = new RandomPattern();
for (String token : input.split(",")) {
for (String token : items) {
Pattern pattern;
double chance;
// Parse special percentage syntax

View File

@ -0,0 +1,132 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.session.request;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
/**
* Describes the current request using a {@link ThreadLocal}.
*/
public final class Request {
private static final ThreadLocal<Request> threadLocal =
new ThreadLocal<Request>() {
@Override protected Request initialValue() {
return new Request();
}
};
private @Nullable World world;
private @Nullable LocalSession session;
private @Nullable EditSession editSession;
private @Nullable Extent extent;
private Request() {
}
/**
* Get the request world.
*
* @return the world, which may be null
*/
public @Nullable World getWorld() {
return world;
}
/**
* Set the request world.
*
* @param world the world, which may be null
*/
public void setWorld(@Nullable World world) {
this.world = world;
}
public void setExtent(@Nullable Extent extent) {
this.extent = extent;
}
public @Nullable Extent getExtent() {
if (extent != null) return extent;
if (editSession != null) return editSession;
if (world != null) return world;
return null;
}
/**
* Get the request session.
*
* @return the session, which may be null
*/
public @Nullable LocalSession getSession() {
return session;
}
/**
* Get the request session.
*
* @param session the session, which may be null
*/
public void setSession(@Nullable LocalSession session) {
this.session = session;
}
/**
* Get the {@link EditSession}.
*
* @return the edit session, which may be null
*/
public @Nullable EditSession getEditSession() {
return editSession;
}
/**
* Set the {@link EditSession}.
*
* @param editSession the edit session, which may be null
*/
public void setEditSession(@Nullable EditSession editSession) {
this.editSession = editSession;
}
/**
* Get the current request, which is specific to the current thread.
*
* @return the current request
*/
public static Request request() {
return threadLocal.get();
}
/**
* Reset the current request and clear all fields.
*/
public static void reset() {
threadLocal.remove();
}
public static Class<?> inject() {
return Request.class;
}
}