2018-08-12 14:03:07 +00:00
|
|
|
package com.boydti.fawe.object.pattern;
|
|
|
|
|
2019-05-28 20:31:22 +00:00
|
|
|
import com.boydti.fawe.beta.FilterBlock;
|
2018-12-27 00:39:10 +00:00
|
|
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
2018-08-12 14:03:07 +00:00
|
|
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
|
|
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
|
|
|
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
2018-12-23 16:19:33 +00:00
|
|
|
import com.sk89q.worldedit.math.BlockVector3;
|
2019-03-31 16:09:20 +00:00
|
|
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
2018-08-12 14:03:07 +00:00
|
|
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2019-03-26 17:41:09 +00:00
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
2018-08-12 14:03:07 +00:00
|
|
|
|
|
|
|
public class SurfaceRandomOffsetPattern extends AbstractPattern {
|
|
|
|
private final Pattern pattern;
|
2019-05-28 20:31:22 +00:00
|
|
|
private final int moves;
|
2018-08-12 14:03:07 +00:00
|
|
|
|
2019-05-28 20:31:22 +00:00
|
|
|
private final MutableBlockVector3 cur;
|
|
|
|
private final MutableBlockVector3[] buffer;
|
|
|
|
private final MutableBlockVector3[] allowed;
|
|
|
|
private MutableBlockVector3 next;
|
2018-08-12 14:03:07 +00:00
|
|
|
|
|
|
|
public SurfaceRandomOffsetPattern(Pattern pattern, int distance) {
|
|
|
|
this.pattern = pattern;
|
|
|
|
this.moves = Math.min(255, distance);
|
2019-03-31 16:09:20 +00:00
|
|
|
cur = new MutableBlockVector3();
|
|
|
|
this.buffer = new MutableBlockVector3[BreadthFirstSearch.DIAGONAL_DIRECTIONS.length];
|
2018-08-12 14:03:07 +00:00
|
|
|
for (int i = 0; i < buffer.length; i++) {
|
2019-03-31 16:09:20 +00:00
|
|
|
buffer[i] = new MutableBlockVector3();
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
2019-03-31 16:09:20 +00:00
|
|
|
allowed = new MutableBlockVector3[buffer.length];
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-12-27 00:39:10 +00:00
|
|
|
public BaseBlock apply(BlockVector3 position) {
|
2018-08-12 14:03:07 +00:00
|
|
|
return pattern.apply(travel(position));
|
|
|
|
}
|
|
|
|
|
2018-12-23 16:19:33 +00:00
|
|
|
private BlockVector3 travel(BlockVector3 pos) {
|
2018-08-12 14:03:07 +00:00
|
|
|
cur.setComponents(pos);
|
|
|
|
for (int move = 0; move < moves; move++) {
|
|
|
|
int index = 0;
|
2019-06-23 18:00:22 +00:00
|
|
|
MutableBlockVector3 next;
|
2018-08-12 14:03:07 +00:00
|
|
|
for (int i = 0; i < allowed.length; i++) {
|
|
|
|
next = buffer[i];
|
2018-12-23 16:19:33 +00:00
|
|
|
BlockVector3 dir = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i];
|
2018-08-12 14:03:07 +00:00
|
|
|
next.setComponents(cur.getBlockX() + dir.getBlockX(), cur.getBlockY() + dir.getBlockY(), cur.getBlockZ() + dir.getBlockZ());
|
2019-03-31 16:09:20 +00:00
|
|
|
if (allowed(next)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
allowed[index++] = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (index == 0) {
|
2019-03-31 16:09:20 +00:00
|
|
|
return cur;
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
2019-03-26 17:41:09 +00:00
|
|
|
next = allowed[ThreadLocalRandom.current().nextInt(index)];
|
2018-08-12 14:03:07 +00:00
|
|
|
cur.setComponents(next.getBlockX(), next.getBlockY(), next.getBlockZ());
|
|
|
|
}
|
2019-03-31 16:09:20 +00:00
|
|
|
return cur;
|
2018-08-12 14:03:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-23 16:19:33 +00:00
|
|
|
private boolean allowed(BlockVector3 bv) {
|
2019-03-31 16:09:20 +00:00
|
|
|
MutableBlockVector3 v = new MutableBlockVector3(bv);
|
2019-01-09 07:13:44 +00:00
|
|
|
BlockStateHolder block = pattern.apply(bv);
|
2018-08-12 14:03:07 +00:00
|
|
|
if (!block.getBlockType().getMaterial().isMovementBlocker()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int x = v.getBlockX();
|
|
|
|
int y = v.getBlockY();
|
|
|
|
int z = v.getBlockZ();
|
|
|
|
v.mutY(y + 1);
|
2019-03-31 16:09:20 +00:00
|
|
|
if (canPassthrough(v)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
v.mutY(y);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
v.mutY(y - 1);
|
2019-03-31 16:09:20 +00:00
|
|
|
if (canPassthrough(v)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
v.mutY(y);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
v.mutY(y);
|
|
|
|
v.mutX(x + 1);
|
2019-03-31 16:09:20 +00:00
|
|
|
if (canPassthrough(v)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
v.mutX(x);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
v.mutX(x - 1);
|
2019-03-31 16:09:20 +00:00
|
|
|
if (canPassthrough(v)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
v.mutX(x);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
v.mutX(x);
|
|
|
|
v.mutZ(z + 1);
|
2019-03-31 16:09:20 +00:00
|
|
|
if (canPassthrough(v)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
v.mutZ(z);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
v.mutZ(z - 1);
|
2019-03-31 16:09:20 +00:00
|
|
|
if (canPassthrough(v)) {
|
2018-08-12 14:03:07 +00:00
|
|
|
v.mutZ(z);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
v.mutZ(z);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-23 16:19:33 +00:00
|
|
|
private boolean canPassthrough(BlockVector3 v) {
|
2018-08-12 14:03:07 +00:00
|
|
|
BlockStateHolder block = pattern.apply(v);
|
|
|
|
return !block.getBlockType().getMaterial().isMovementBlocker();
|
|
|
|
}
|
2019-03-26 17:41:09 +00:00
|
|
|
}
|