mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-25 22:56:45 +01:00
Fixed a couple issues related to world generation / clearing
- Fixed competition of multiple augmented populators if there are several augmented plot clusters of specific terrain type - Fixed fastmode clearing sometimes doing strange things if chunks connected to the road have not previously been generated - Fixed fastmode clearing not setting block data correctly on unloaded chunks under specific conditions.
This commit is contained in:
parent
00ab472ba6
commit
7db9c0b9a2
@ -120,6 +120,21 @@ public class AugmentedPopulator extends BlockPopulator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void populate(final World world, final Random rand, final Chunk chunk) {
|
public void populate(final World world, final Random rand, final Chunk chunk) {
|
||||||
|
final int cx = chunk.getX();
|
||||||
|
final int cz = chunk.getZ();
|
||||||
|
final int bx = cx << 4;
|
||||||
|
final int bz = cz << 4;
|
||||||
|
final int tx = bx + 15;
|
||||||
|
final int tz = bz + 15;
|
||||||
|
final boolean inX1 = ((bx >= this.bx) && (bx <= this.tx));
|
||||||
|
final boolean inX2 = ((tx >= this.bx) && (tx <= this.tx));
|
||||||
|
final boolean inZ1 = ((bz >= this.bz) && (bz <= this.tz));
|
||||||
|
final boolean inZ2 = ((tz >= this.bz) && (tz <= this.tz));
|
||||||
|
final boolean inX = inX1 || inX2;
|
||||||
|
final boolean inZ = inZ1 || inZ2;
|
||||||
|
if (!inX || !inZ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.plotworld.TERRAIN == 3) {
|
if (this.plotworld.TERRAIN == 3) {
|
||||||
int X = chunk.getX() << 4;
|
int X = chunk.getX() << 4;
|
||||||
int Z = chunk.getZ() << 4;
|
int Z = chunk.getZ() << 4;
|
||||||
@ -170,44 +185,29 @@ public class AugmentedPopulator extends BlockPopulator {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int X = chunk.getX();
|
|
||||||
final int Z = chunk.getZ();
|
|
||||||
final int x = X << 4;
|
|
||||||
final int z = Z << 4;
|
|
||||||
final int x2 = x + 15;
|
|
||||||
final int z2 = z + 15;
|
|
||||||
final boolean inX1 = ((x >= this.bx) && (x <= this.tx));
|
|
||||||
final boolean inX2 = ((x2 >= this.bx) && (x2 <= this.tx));
|
|
||||||
final boolean inZ1 = ((z >= this.bz) && (z <= this.tz));
|
|
||||||
final boolean inZ2 = ((z2 >= this.bz) && (z2 <= this.tz));
|
|
||||||
final boolean inX = inX1 || inX2;
|
|
||||||
final boolean inZ = inZ1 || inZ2;
|
|
||||||
if (!inX || !inZ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final boolean check;
|
final boolean check;
|
||||||
check = !inX1 || !inX2 || !inZ1 || !inZ2;
|
check = !inX1 || !inX2 || !inZ1 || !inZ2;
|
||||||
if (this.plotworld.TERRAIN > 1) {
|
if (this.plotworld.TERRAIN > 1) {
|
||||||
final PlotId plot1 = this.manager.getPlotIdAbs(this.plotworld, x, 0, z);
|
final PlotId plot1 = this.manager.getPlotIdAbs(this.plotworld, bx, 0, bz);
|
||||||
final PlotId plot2 = this.manager.getPlotIdAbs(this.plotworld, x2, 0, z2);
|
final PlotId plot2 = this.manager.getPlotIdAbs(this.plotworld, tx, 0, tz);
|
||||||
if ((plot1 != null) && (plot2 != null) && plot1.equals(plot2)) {
|
if ((plot1 != null) && (plot2 != null) && plot1.equals(plot2)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.o) {
|
if (this.o) {
|
||||||
populateBlocks(world, rand, X, Z, x, z, check);
|
populateBlocks(world, rand, cx, cz, bx, bz, check);
|
||||||
} else {
|
} else {
|
||||||
TaskManager.runTaskLater(new Runnable() {
|
TaskManager.runTaskLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
populateBiome(world, x, z);
|
populateBiome(world, bx, bz);
|
||||||
}
|
}
|
||||||
}, 20 + rand.nextInt(10));
|
}, 20 + rand.nextInt(10));
|
||||||
TaskManager.runTaskLater(new Runnable() {
|
TaskManager.runTaskLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
chunk.load(true);
|
chunk.load(true);
|
||||||
populateBlocks(world, rand, X, Z, x, z, check);
|
populateBlocks(world, rand, cx, cz, bx, bz, check);
|
||||||
}
|
}
|
||||||
}, 40 + rand.nextInt(40));
|
}, 40 + rand.nextInt(40));
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,15 @@ public abstract class ChunkManager {
|
|||||||
|
|
||||||
public abstract boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone);
|
public abstract boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assumptions:<br>
|
||||||
|
* - pos1 and pos2 are in the same plot<br>
|
||||||
|
* It can be harmful to the world if parameters outside this scope are provided
|
||||||
|
* @param pos1
|
||||||
|
* @param pos2
|
||||||
|
* @param whenDone
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public abstract boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone);
|
public abstract boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone);
|
||||||
|
|
||||||
public abstract void clearAllEntities(final Plot plot);
|
public abstract void clearAllEntities(final Plot plot);
|
||||||
|
@ -2,6 +2,8 @@ package com.intellectualcrafters.plot.util.bukkit;
|
|||||||
|
|
||||||
import com.intellectualcrafters.plot.BukkitMain;
|
import com.intellectualcrafters.plot.BukkitMain;
|
||||||
import com.intellectualcrafters.plot.PS;
|
import com.intellectualcrafters.plot.PS;
|
||||||
|
import com.intellectualcrafters.plot.generator.AugmentedPopulator;
|
||||||
|
import com.intellectualcrafters.plot.generator.HybridPlotWorld;
|
||||||
import com.intellectualcrafters.plot.object.BlockLoc;
|
import com.intellectualcrafters.plot.object.BlockLoc;
|
||||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||||
import com.intellectualcrafters.plot.object.Location;
|
import com.intellectualcrafters.plot.object.Location;
|
||||||
@ -10,12 +12,16 @@ import com.intellectualcrafters.plot.object.PlotBlock;
|
|||||||
import com.intellectualcrafters.plot.object.PlotId;
|
import com.intellectualcrafters.plot.object.PlotId;
|
||||||
import com.intellectualcrafters.plot.object.PlotLoc;
|
import com.intellectualcrafters.plot.object.PlotLoc;
|
||||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||||
|
import com.intellectualcrafters.plot.object.PlotWorld;
|
||||||
import com.intellectualcrafters.plot.object.RegionWrapper;
|
import com.intellectualcrafters.plot.object.RegionWrapper;
|
||||||
import com.intellectualcrafters.plot.object.entity.EntityWrapper;
|
import com.intellectualcrafters.plot.object.entity.EntityWrapper;
|
||||||
import com.intellectualcrafters.plot.util.ChunkManager;
|
import com.intellectualcrafters.plot.util.ChunkManager;
|
||||||
|
import com.intellectualcrafters.plot.util.ClusterManager;
|
||||||
import com.intellectualcrafters.plot.util.MainUtil;
|
import com.intellectualcrafters.plot.util.MainUtil;
|
||||||
|
import com.intellectualcrafters.plot.util.SetBlockQueue;
|
||||||
import com.intellectualcrafters.plot.util.SetBlockQueue.ChunkWrapper;
|
import com.intellectualcrafters.plot.util.SetBlockQueue.ChunkWrapper;
|
||||||
import com.intellectualcrafters.plot.util.TaskManager;
|
import com.intellectualcrafters.plot.util.TaskManager;
|
||||||
|
|
||||||
import org.apache.commons.lang.mutable.MutableInt;
|
import org.apache.commons.lang.mutable.MutableInt;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
@ -49,6 +55,7 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Vehicle;
|
import org.bukkit.entity.Vehicle;
|
||||||
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -59,6 +66,7 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class BukkitChunkManager extends ChunkManager {
|
public class BukkitChunkManager extends ChunkManager {
|
||||||
@Override
|
@Override
|
||||||
@ -296,99 +304,179 @@ public class BukkitChunkManager extends ChunkManager {
|
|||||||
TaskManager.tasks.put(currentIndex, loadTask);
|
TaskManager.tasks.put(currentIndex, loadTask);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveRegion(World world, int x1, int x2, int z1, int z2) {
|
||||||
|
if (z1 > z2) {
|
||||||
|
int tmp = z1;
|
||||||
|
z1 = z2;
|
||||||
|
z2 = tmp;
|
||||||
|
}
|
||||||
|
if (x1 > x2) {
|
||||||
|
int tmp = x1;
|
||||||
|
x1 = x2;
|
||||||
|
x2 = tmp;
|
||||||
|
}
|
||||||
|
for (int x = x1; x <= x2; x++) {
|
||||||
|
for (int z = z1; z <= z2; z++) {
|
||||||
|
saveBlocks(world, 255, x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone) {
|
public boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone) {
|
||||||
TaskManager.index.increment();
|
final String world = pos1.getWorld();
|
||||||
final Plugin plugin = BukkitMain.THIS;
|
PlotWorld plotworld = PS.get().getPlotWorld(world);
|
||||||
final World world = Bukkit.getWorld(pos1.getWorld());
|
final int p1x = pos1.getX();
|
||||||
final Chunk c1 = world.getChunkAt(pos1.getX() >> 4, pos1.getZ() >> 4);
|
final int p1z = pos1.getZ();
|
||||||
final Chunk c2 = world.getChunkAt(pos2.getX() >> 4, pos2.getZ() >> 4);
|
final int p2x = pos2.getX();
|
||||||
final int sx = pos1.getX();
|
final int p2z = pos2.getZ();
|
||||||
final int sz = pos1.getZ();
|
final int bcx = p1x >> 4;
|
||||||
final int ex = pos2.getX();
|
final int bcz = p1z >> 4;
|
||||||
final int ez = pos2.getZ();
|
final int tcx = p2x >> 4;
|
||||||
final int c1x = c1.getX();
|
final int tcz = p2z >> 4;
|
||||||
final int c1z = c1.getZ();
|
|
||||||
final int c2x = c2.getX();
|
final boolean canRegen = (plotworld.TYPE != 0 && plotworld.TERRAIN == 0);
|
||||||
final int c2z = c2.getZ();
|
|
||||||
final ArrayList<Chunk> chunks = new ArrayList<Chunk>();
|
final ArrayList<ChunkLoc> chunks = new ArrayList<ChunkLoc>();
|
||||||
for (int x = c1x; x <= c2x; x++) {
|
|
||||||
for (int z = c1z; z <= c2z; z++) {
|
for (int x = bcx; x <= tcx; x++) {
|
||||||
final Chunk chunk = world.getChunkAt(x, z);
|
for (int z = bcz; z <= tcz; z++) {
|
||||||
chunk.load(false);
|
chunks.add(new ChunkLoc(x, z));
|
||||||
chunks.add(chunk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int maxY = world.getMaxHeight();
|
|
||||||
final Integer currentIndex = TaskManager.index.toInteger();
|
AugmentedPopulator augpop = null;
|
||||||
final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
|
final World worldObj = Bukkit.getWorld(world);
|
||||||
@Override
|
List<BlockPopulator> populators = worldObj.getPopulators();
|
||||||
public void run() {
|
for (BlockPopulator populator : populators) {
|
||||||
final long start = System.currentTimeMillis();
|
if (populator instanceof AugmentedPopulator) {
|
||||||
while ((System.currentTimeMillis() - start) < 20) {
|
AugmentedPopulator current = ((AugmentedPopulator) populator);
|
||||||
if (chunks.size() == 0) {
|
if (current.cluster == null) {
|
||||||
TaskManager.runTaskLater(whenDone, 1);
|
augpop = current;
|
||||||
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
break;
|
||||||
TaskManager.tasks.remove(currentIndex);
|
}
|
||||||
return;
|
else if (ClusterManager.contains(current.cluster, pos1)) {
|
||||||
}
|
augpop = current;
|
||||||
CURRENT_PLOT_CLEAR = new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
break;
|
||||||
final Chunk chunk = chunks.get(0);
|
|
||||||
chunks.remove(0);
|
|
||||||
final int x = chunk.getX();
|
|
||||||
final int z = chunk.getZ();
|
|
||||||
boolean loaded = true;
|
|
||||||
if (!chunk.isLoaded()) {
|
|
||||||
final boolean result = chunk.load(false);
|
|
||||||
if (!result) {
|
|
||||||
loaded = false;
|
|
||||||
}
|
|
||||||
if (!chunk.isLoaded()) {
|
|
||||||
loaded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (loaded) {
|
|
||||||
initMaps();
|
|
||||||
final int absX = x << 4;
|
|
||||||
final int absZ = z << 4;
|
|
||||||
boolean save = false;
|
|
||||||
if ((x == c1x) || (z == c1z)) {
|
|
||||||
save = true;
|
|
||||||
for (int X = 0; X < 16; X++) {
|
|
||||||
for (int Z = 0; Z < 16; Z++) {
|
|
||||||
if ((((X + absX) < sx) || ((Z + absZ) < sz)) || (((X + absX) > ex) || ((Z + absZ) > ez))) {
|
|
||||||
saveBlocks(world, maxY, X + absX, Z + absZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((x == c2x) || (z == c2z)) {
|
|
||||||
for (int X = 0; X < 16; X++) {
|
|
||||||
save = true;
|
|
||||||
for (int Z = 0; Z < 16; Z++) {
|
|
||||||
if ((((X + absX) > ex) || ((Z + absZ) > ez)) || (((X + absX) < sx) || ((Z + absZ) < sz))) {
|
|
||||||
saveBlocks(world, maxY, X + absX, Z + absZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (save) {
|
|
||||||
saveEntitiesOut(chunk, CURRENT_PLOT_CLEAR);
|
|
||||||
}
|
|
||||||
ChunkLoc loc = new ChunkLoc(chunk.getX(), chunk.getZ());
|
|
||||||
regenerateChunk(world.getName(), loc);
|
|
||||||
if (save) {
|
|
||||||
restoreBlocks(world, 0, 0);
|
|
||||||
restoreEntities(world, 0, 0);
|
|
||||||
}
|
|
||||||
MainUtil.update(world.getName(), loc);
|
|
||||||
BukkitSetBlockManager.setBlockManager.update(Arrays.asList(new Chunk[] { chunk }));
|
|
||||||
}
|
|
||||||
CURRENT_PLOT_CLEAR = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1, 1);
|
}
|
||||||
TaskManager.tasks.put(currentIndex, task);
|
final AugmentedPopulator ap = augpop;
|
||||||
|
TaskManager.runTask(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
while (chunks.size() > 0 && System.currentTimeMillis() - start < 50) {
|
||||||
|
ChunkLoc chunk = chunks.remove(0);
|
||||||
|
int x = chunk.x;
|
||||||
|
int z = chunk.z;
|
||||||
|
int xxb = x << 4;
|
||||||
|
int zzb = z << 4;
|
||||||
|
int xxt = xxb + 15;
|
||||||
|
int zzt = zzb + 15;
|
||||||
|
CURRENT_PLOT_CLEAR = null;
|
||||||
|
Chunk chunkObj = worldObj.getChunkAt(x, z);
|
||||||
|
if (!chunkObj.load(false)) {
|
||||||
|
System.out.print("FAILED TO LOAD CHUNK!!!: " + x + "," + z);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CURRENT_PLOT_CLEAR = new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
||||||
|
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
|
||||||
|
if (canRegen && ap != null) {
|
||||||
|
ap.populate(worldObj, null, chunkObj);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
regenerateChunk(world, chunk);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean checkX1 = false;
|
||||||
|
boolean checkX2 = false;
|
||||||
|
boolean checkZ1 = false;
|
||||||
|
boolean checkZ2 = false;
|
||||||
|
|
||||||
|
int xxb2;
|
||||||
|
int zzb2;
|
||||||
|
int xxt2;
|
||||||
|
int zzt2;
|
||||||
|
|
||||||
|
if (x == bcx) {
|
||||||
|
xxb2 = p1x - 1;
|
||||||
|
checkX1 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xxb2 = xxb;
|
||||||
|
}
|
||||||
|
if (x == tcx) {
|
||||||
|
xxt2 = p2x + 1;
|
||||||
|
checkX2 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xxt2 = xxt;
|
||||||
|
}
|
||||||
|
if (z == bcz) {
|
||||||
|
zzb2 = p1z - 1;
|
||||||
|
checkZ1 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zzb2 = zzb;
|
||||||
|
}
|
||||||
|
if (z == tcz) {
|
||||||
|
zzt2 = p2z + 1;
|
||||||
|
checkZ2 = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zzt2 = zzt;
|
||||||
|
}
|
||||||
|
initMaps();
|
||||||
|
if (checkX1) {
|
||||||
|
saveRegion(worldObj, xxb , xxb2, zzb2, zzt2); //
|
||||||
|
}
|
||||||
|
if (checkX2) {
|
||||||
|
saveRegion(worldObj, xxt2 , xxt, zzb2, zzt2); //
|
||||||
|
}
|
||||||
|
if (checkZ1) {
|
||||||
|
saveRegion(worldObj, xxb2 , xxt2, zzb, zzb2); //
|
||||||
|
}
|
||||||
|
if (checkZ2) {
|
||||||
|
saveRegion(worldObj, xxb2 , xxt2, zzt2, zzt); //
|
||||||
|
}
|
||||||
|
if (checkX1 && checkZ1) {
|
||||||
|
saveRegion(worldObj, xxb , xxb2, zzb, zzb2); //
|
||||||
|
}
|
||||||
|
if (checkX2 && checkZ1) {
|
||||||
|
System.out.print("CX2 && CZ1");
|
||||||
|
System.out.print(xxt2 +',' + xxt + " | " + zzb + "," + zzb2);
|
||||||
|
saveRegion(worldObj, xxt2 , xxt, zzb, zzb2); // ?
|
||||||
|
}
|
||||||
|
if (checkX1 && checkZ2) {
|
||||||
|
System.out.print("CX1 && CZ2");
|
||||||
|
System.out.print(xxb +',' + xxb2 + " | " + zzt2 + "," + zzt);
|
||||||
|
saveRegion(worldObj, xxb , xxb2, zzt2, zzt); // ?
|
||||||
|
}
|
||||||
|
if (checkX2 && checkZ2) {
|
||||||
|
saveRegion(worldObj, xxt2 , xxt, zzt2, zzt); //
|
||||||
|
}
|
||||||
|
saveEntitiesOut(chunkObj, CURRENT_PLOT_CLEAR);
|
||||||
|
if (canRegen && ap != null) {
|
||||||
|
ap.populate(worldObj, null, chunkObj);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
regenerateChunk(world, chunk);
|
||||||
|
}
|
||||||
|
restoreBlocks(worldObj, 0, 0);
|
||||||
|
restoreEntities(worldObj, 0, 0);
|
||||||
|
}
|
||||||
|
CURRENT_PLOT_CLEAR = null;
|
||||||
|
if (chunks.size() != 0) {
|
||||||
|
TaskManager.runTaskLater(this, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TaskManager.runTaskLater(whenDone, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user