Fix populator random seed / algorithm differing from chunk generator

This commit is contained in:
Jesse Boyd 2015-11-18 16:42:19 +11:00
parent 1e1259b81d
commit 7ed693dfc8
5 changed files with 52 additions and 51 deletions

View File

@ -49,7 +49,7 @@ public abstract class BukkitPlotGenerator extends ChunkGenerator {
public int Z;
private boolean loaded = false;
private short[][] result;
private final PseudoRandom random = new PseudoRandom();
public final PseudoRandom random = new PseudoRandom();
public BukkitPlotGenerator(final String world) {
WorldEvents.lastWorld = world;

View File

@ -17,7 +17,7 @@ import com.intellectualcrafters.plot.util.SetBlockQueue;
public abstract class BukkitPlotPopulator extends BlockPopulator {
private final PseudoRandom random = new PseudoRandom();
public final PseudoRandom random = new PseudoRandom();
public int X;
public int Z;
@ -29,8 +29,15 @@ public abstract class BukkitPlotPopulator extends BlockPopulator {
try {
this.chunk = chunk;
worldname = world.getName();
X = this.chunk.getX() << 4;
Z = this.chunk.getZ() << 4;
int cx = this.chunk.getX();
int cz = this.chunk.getZ();
X = cx << 4;
Z = cz << 4;
final int prime = 13;
int h = 1;
h = (prime * h) + cx;
h = (prime * h) + cz;
random.state = h;
if (ChunkManager.FORCE_PASTE) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
@ -43,7 +50,7 @@ public abstract class BukkitPlotPopulator extends BlockPopulator {
}
return;
}
populate(world, ChunkManager.CURRENT_PLOT_CLEAR, random, X, Z);
populate(world, ChunkManager.CURRENT_PLOT_CLEAR, random, cx, cz);
if (ChunkManager.CURRENT_PLOT_CLEAR != null) {
PlotLoc loc;
for (final Entry<PlotLoc, HashMap<Short, Byte>> entry : ChunkManager.GENERATE_DATA.entrySet()) {
@ -96,6 +103,14 @@ public abstract class BukkitPlotPopulator extends BlockPopulator {
}
}
public void setBlock(final short x, final short y, final short z, final byte[] datas) {
if (datas.length == 1) {
setBlock(x, y, z, datas[0]);
} else {
setBlock(x, y, z, datas[random.random(datas.length)]);
}
}
/**
* Like setblock, but lacks the data != 0 check
* @param x

View File

@ -131,7 +131,7 @@ public class HybridGen extends BukkitPlotGenerator {
for (int i = 0; i < cached.length; i++) {
cached[i] = new short[4096];
}
final PseudoRandom random = new PseudoRandom();
random.state = 7919;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
cached[CACHE_I[plotheight][x][z]][CACHE_J[plotheight][x][z]] = plotfloors[random.random(plotfloors.length)];
@ -209,22 +209,16 @@ public class HybridGen extends BukkitPlotGenerator {
}
}
if (plotworld.PLOT_BEDROCK) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
setBlock(x, 0, z, (short) 7);
}
}
}
if (region != null) {
for (short x = 0; x < 16; x++) {
final int absX = ((sx + x) % size);
for (short z = 0; z < 16; z++) {
if (contains(region, x, z)) {
setBlock(x, 0, z, (short) 7);
setBlock(x, plotheight, z, plotfloors);
for (short y = 1; y < plotheight; y++) {
setBlock(x, y, z, filling);
}
setBlock(x, plotheight, z, plotfloors);
final int absZ = ((sz + z) % size);
final PlotLoc loc = new PlotLoc(absX, absZ);
final HashMap<Short, Short> blocks = plotworld.G_SCH.get(loc);
@ -239,6 +233,14 @@ public class HybridGen extends BukkitPlotGenerator {
return;
}
if (plotworld.PLOT_BEDROCK) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
setBlock(x, 0, z, (short) 7);
}
}
}
for (short x = 0; x < 16; x++) {
final int absX = ((sx + x) % size);
final boolean gx = absX > pathWidthLower;
@ -249,10 +251,10 @@ public class HybridGen extends BukkitPlotGenerator {
final boolean lz = absZ < pathWidthUpper;
// inside plot
if (gx && gz && lx && lz) {
setBlock(x, plotheight, z, plotfloors);
for (short y = 1; y < plotheight; y++) {
setBlock(x, y, z, filling);
}
setBlock(x, plotheight, z, plotfloors);
if (plotworld.PLOT_SCHEMATIC) {
final PlotLoc loc = new PlotLoc(absX, absZ);
final HashMap<Short, Short> blocks = plotworld.G_SCH.get(loc);

View File

@ -38,9 +38,9 @@ public class HybridPop extends BukkitPlotPopulator {
final short pathWidthUpper;
private final HybridPlotWorld plotworld;
Biome biome;
private long state;
private boolean doFilling = false;
private boolean doFloor = false;
private boolean cached;
public HybridPop(final PlotWorld pw) {
plotworld = (HybridPlotWorld) pw;
@ -84,24 +84,10 @@ public class HybridPop extends BukkitPlotPopulator {
}
pathWidthUpper = (short) (pathWidthLower + plotsize + 1);
}
}
public final long nextLong() {
final long a = state;
state = xorShift64(a);
return a;
if (!this.plotworld.PLOT_SCHEMATIC) {
this.cached = true;
}
public final long xorShift64(long a) {
a ^= (a << 21);
a ^= (a >>> 35);
a ^= (a << 4);
return a;
}
public final int random(final int n) {
final long result = ((nextLong() >>> 32) * n) >> 32;
return (int) result;
}
@Override
@ -116,18 +102,25 @@ public class HybridPop extends BukkitPlotPopulator {
sz += size;
}
if (cached) {
if ((sx > pathWidthLower) && (sz > pathWidthLower) && ((sx + 15) < pathWidthUpper) && ((sz + 15) < pathWidthUpper)) {
random.state = 7919;
}
}
if (requiredRegion != null) {
if (!doFloor && !doFilling && plotworld.G_SCH_STATE == null) {
return;
}
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
if (contains(requiredRegion, x, z)) {
setBlock(x, (short) plotheight, z, plotfloors);
if (doFilling) {
for (short y = 1; y < plotheight; y++) {
setBlock(x, y, z, filling);
}
}
if (doFloor) {
setBlock(x, (short) plotheight, z, plotfloors);
}
if (plotworld.PLOT_SCHEMATIC) {
final int absX = ((sx + x) % size);
final int absZ = ((sz + z) % size);
@ -154,19 +147,19 @@ public class HybridPop extends BukkitPlotPopulator {
}
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
final int absX = ((sx + x) % size);
final int absZ = ((sz + z) % size);
final boolean gx = absX > pathWidthLower;
final boolean gz = absZ > pathWidthLower;
final boolean lx = absX < pathWidthUpper;
for (short z = 0; z < 16; z++) {
final int absZ = ((sz + z) % size);
final boolean gz = absZ > pathWidthLower;
final boolean lz = absZ < pathWidthUpper;
// inside plot
if (gx && gz && lx && lz) {
setBlock(x, (short) plotheight, z, plotfloors);
for (short y = 1; y < plotheight; y++) {
setBlock(x, y, z, filling);
}
setBlock(x, (short) plotheight, z, plotfloors);
if (plotworld.PLOT_SCHEMATIC) {
final PlotLoc loc = new PlotLoc(absX, absZ);
final HashMap<Short, Byte> blocks = plotworld.G_SCH_DATA.get(loc);
@ -215,13 +208,4 @@ public class HybridPop extends BukkitPlotPopulator {
}
}
}
private void setBlock(final short x, final short y, final short z, final byte[] blkids) {
if (blkids.length == 1) {
setBlock(x, y, z, blkids[0]);
} else {
final int i = random(blkids.length);
setBlock(x, y, z, blkids[i]);
}
}
}

Binary file not shown.