2014-11-08 22:47:45 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// PlotSquared - A plot manager and world generator for the Bukkit API /
|
|
|
|
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
|
|
|
|
// /
|
|
|
|
// This program is free software; you can redistribute it and/or modify /
|
|
|
|
// it under the terms of the GNU 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 General Public License for more details. /
|
|
|
|
// /
|
|
|
|
// You should have received a copy of the GNU General Public License /
|
|
|
|
// along with this program; if not, write to the Free Software Foundation, /
|
|
|
|
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
|
|
|
|
// /
|
|
|
|
// You can contact us via: support@intellectualsites.com /
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-07-26 18:14:34 +02:00
|
|
|
package com.plotsquared.bukkit.generator;
|
2014-10-08 07:53:09 +02:00
|
|
|
|
2015-07-30 16:25:16 +02:00
|
|
|
import com.intellectualcrafters.plot.PS;
|
2016-02-10 19:59:51 +01:00
|
|
|
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
|
|
|
|
import com.intellectualcrafters.plot.generator.HybridGen;
|
|
|
|
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
|
2016-02-26 07:29:31 +01:00
|
|
|
import com.intellectualcrafters.plot.object.*;
|
2015-07-30 16:25:16 +02:00
|
|
|
import com.intellectualcrafters.plot.util.ChunkManager;
|
2016-02-10 19:59:51 +01:00
|
|
|
import com.intellectualcrafters.plot.util.MainUtil;
|
|
|
|
import com.intellectualcrafters.plot.util.PlotChunk;
|
|
|
|
import com.intellectualcrafters.plot.util.SetQueue;
|
|
|
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
|
|
|
import com.plotsquared.bukkit.util.block.GenChunk;
|
2016-02-26 07:29:31 +01:00
|
|
|
import org.bukkit.Chunk;
|
|
|
|
import org.bukkit.World;
|
|
|
|
import org.bukkit.block.Biome;
|
|
|
|
import org.bukkit.generator.BlockPopulator;
|
|
|
|
import org.bukkit.generator.ChunkGenerator;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Random;
|
|
|
|
import java.util.Set;
|
2015-07-30 16:25:16 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> {
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
private final PlotChunk<Chunk> chunkSetter;
|
|
|
|
private final PseudoRandom random = new PseudoRandom();
|
|
|
|
private final IndependentPlotGenerator plotGenerator;
|
2016-02-14 02:01:18 +01:00
|
|
|
private final List<BlockPopulator> populators = new ArrayList<>();
|
|
|
|
private boolean loaded = false;
|
2016-02-10 19:59:51 +01:00
|
|
|
private ChunkGenerator platformGenerator;
|
|
|
|
private boolean full;
|
|
|
|
|
2016-02-19 19:42:06 +01:00
|
|
|
public BukkitPlotGenerator(IndependentPlotGenerator generator) {
|
2016-02-10 19:59:51 +01:00
|
|
|
this.plotGenerator = generator;
|
|
|
|
this.platformGenerator = this;
|
|
|
|
populators.add(new BlockPopulator() {
|
|
|
|
@Override
|
|
|
|
public void populate(World world, Random r, Chunk c) {
|
|
|
|
if (!(chunkSetter instanceof GenChunk)) {
|
|
|
|
PS.debug("Current PlotChunk is not relevant to population?");
|
|
|
|
PS.stacktrace();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
GenChunk result = (GenChunk) chunkSetter;
|
|
|
|
if (result.result_data != null) {
|
|
|
|
for (int i = 0; i < result.result_data.length; i++) {
|
|
|
|
byte[] section = result.result_data[i];
|
|
|
|
if (section == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (int j = 0; j < section.length; j++) {
|
|
|
|
int x = MainUtil.x_loc[i][j];
|
|
|
|
int y = MainUtil.y_loc[i][j];
|
|
|
|
int z = MainUtil.z_loc[i][j];
|
|
|
|
c.getBlock(x, y, z).setData(section[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-02-19 19:42:06 +01:00
|
|
|
chunkSetter = new GenChunk(null, null);
|
2016-02-10 19:59:51 +01:00
|
|
|
this.full = true;
|
|
|
|
MainUtil.initCache();
|
2015-07-03 04:11:41 +02:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
public BukkitPlotGenerator(final String world, final ChunkGenerator cg) {
|
|
|
|
if (cg instanceof BukkitPlotGenerator) {
|
|
|
|
throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName() + " is already a BukkitPlotGenerator!");
|
|
|
|
}
|
|
|
|
this.full = false;
|
|
|
|
PS.get().debug("BukkitPlotGenerator does not fully support: " + cg);
|
|
|
|
platformGenerator = cg;
|
|
|
|
plotGenerator = new IndependentPlotGenerator() {
|
|
|
|
@Override
|
|
|
|
public void processSetup(SetupObject setup) {}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void initialize(PlotArea area) {}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public PlotManager getNewPlotManager() {
|
|
|
|
return new HybridGen().getNewPlotManager();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return cg.getClass().getName();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) {
|
|
|
|
return new HybridGen().getNewPlotArea(world, id, min, max);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void generateChunk(final PlotChunk<?> result, final PlotArea settings, final PseudoRandom random) {
|
|
|
|
World w = BukkitUtil.getWorld(world);
|
|
|
|
Random r = new Random(result.getChunkWrapper().hashCode());
|
|
|
|
BiomeGrid grid = new BiomeGrid() {
|
|
|
|
@Override
|
|
|
|
public void setBiome(int x, int z, Biome biome) {
|
|
|
|
result.setBiome(x, z, biome.ordinal());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Biome getBiome(int arg0, int arg1) {
|
|
|
|
return Biome.FOREST;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
// ChunkData will spill a bit
|
|
|
|
ChunkData data = cg.generateChunkData(w, r, result.getX(), result.getZ(), grid);
|
|
|
|
if (data != null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Throwable e) {}
|
|
|
|
// Populator spillage
|
|
|
|
short[][] tmp = cg.generateExtBlockSections(w, r, result.getX(), result.getZ(), grid);
|
|
|
|
if (tmp != null) {
|
|
|
|
for (int i = 0; i < tmp.length; i++) {
|
|
|
|
short[] section = tmp[i];
|
|
|
|
if (section == null) {
|
|
|
|
if (i < 7) {
|
|
|
|
for (int x = 0; x < 16; x++) {
|
|
|
|
for (int z = 0; z < 16; z++) {
|
|
|
|
for (int y = i << 4; y < (i << 4) + 16; y++) {
|
|
|
|
result.setBlock(x, y, z, (short) 0, (byte) 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (int j = 0; j < section.length; j++) {
|
|
|
|
int x = MainUtil.x_loc[i][j];
|
|
|
|
int y = MainUtil.y_loc[i][j];
|
|
|
|
int z = MainUtil.z_loc[i][j];
|
|
|
|
result.setBlock(x, y, z, section[j], (byte) 0);
|
|
|
|
}
|
2015-07-03 04:11:41 +02:00
|
|
|
}
|
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
for (BlockPopulator populator : cg.getDefaultPopulators(w)) {
|
|
|
|
populator.populate(w, r, (Chunk) result.getChunk());
|
|
|
|
}
|
2015-07-03 04:11:41 +02:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
};
|
|
|
|
chunkSetter = new GenChunk(null, SetQueue.IMP.new ChunkWrapper(world, 0, 0));
|
|
|
|
if (cg != null) {
|
|
|
|
populators.addAll(cg.getDefaultPopulators(BukkitUtil.getWorld(world)));
|
2015-07-03 04:11:41 +02:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
MainUtil.initCache();
|
2015-05-09 08:24:03 +02:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
@Override
|
|
|
|
public void augment(PlotArea area) {
|
|
|
|
BukkitAugmentedGenerator.get(BukkitUtil.getWorld(area.worldname));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isFull() {
|
|
|
|
return full;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IndependentPlotGenerator getPlotGenerator() {
|
|
|
|
return plotGenerator;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ChunkGenerator getPlatformGenerator() {
|
|
|
|
return platformGenerator;
|
|
|
|
}
|
|
|
|
|
2015-02-24 12:27:30 +01:00
|
|
|
@Override
|
2015-09-13 06:04:31 +02:00
|
|
|
public List<BlockPopulator> getDefaultPopulators(final World world) {
|
|
|
|
try {
|
|
|
|
if (!loaded) {
|
2016-02-26 07:29:31 +01:00
|
|
|
final String name = world.getName();
|
2016-02-10 19:59:51 +01:00
|
|
|
PS.get().loadWorld(name, this);
|
|
|
|
Set<PlotArea> areas = PS.get().getPlotAreas(name);
|
2016-02-14 02:01:18 +01:00
|
|
|
if (!areas.isEmpty()) {
|
2016-02-10 19:59:51 +01:00
|
|
|
PlotArea area = areas.iterator().next();
|
|
|
|
if (!area.MOB_SPAWNING) {
|
|
|
|
if (!area.SPAWN_EGGS) {
|
|
|
|
world.setSpawnFlags(false, false);
|
|
|
|
}
|
|
|
|
world.setAmbientSpawnLimit(0);
|
|
|
|
world.setAnimalSpawnLimit(0);
|
|
|
|
world.setMonsterSpawnLimit(0);
|
|
|
|
world.setWaterAnimalSpawnLimit(0);
|
|
|
|
} else {
|
|
|
|
world.setSpawnFlags(true, true);
|
|
|
|
world.setAmbientSpawnLimit(-1);
|
|
|
|
world.setAnimalSpawnLimit(-1);
|
|
|
|
world.setMonsterSpawnLimit(-1);
|
|
|
|
world.setWaterAnimalSpawnLimit(-1);
|
2015-05-10 05:17:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
loaded = true;
|
2015-03-11 09:47:22 +01:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
} catch (final Exception e) {
|
2015-05-10 05:17:10 +02:00
|
|
|
e.printStackTrace();
|
2015-03-11 09:47:22 +01:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
return populators;
|
2015-07-18 19:03:59 +02:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2015-03-27 08:15:41 +01:00
|
|
|
@Override
|
2016-02-10 19:59:51 +01:00
|
|
|
public ChunkData generateChunkData(World world, Random random, int cx, int cz, BiomeGrid grid) {
|
|
|
|
if (!(chunkSetter instanceof GenChunk)) {
|
|
|
|
PS.debug("Current PlotChunk is not relevant to generation?");
|
|
|
|
PS.stacktrace();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
GenChunk result = (GenChunk) chunkSetter;
|
|
|
|
// Set the chunk location
|
|
|
|
result.setChunkWrapper(SetQueue.IMP.new ChunkWrapper(world.getName(), cx, cz));
|
|
|
|
// Set the result data
|
|
|
|
result.cd = createChunkData(world);
|
|
|
|
result.grid = grid;
|
|
|
|
// Catch any exceptions (as exceptions usually thrown
|
2015-09-13 06:04:31 +02:00
|
|
|
try {
|
2016-02-10 19:59:51 +01:00
|
|
|
// Fill the result data if necessary
|
|
|
|
if (platformGenerator != this) {
|
|
|
|
return platformGenerator.generateChunkData(world, random, cx, cz, grid);
|
|
|
|
} else {
|
|
|
|
generate(world, cx, cz, result);
|
2015-05-10 05:17:10 +02:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
} catch (Throwable e) {
|
2015-05-10 05:17:10 +02:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
// Return the result data
|
|
|
|
return result.cd;
|
2015-03-27 08:15:41 +01:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
public void generate(World world, int cx, int cz, GenChunk result) {
|
|
|
|
// Load if improperly loaded
|
|
|
|
if (!loaded) {
|
2016-02-26 07:29:31 +01:00
|
|
|
final String name = world.getName();
|
2016-02-10 19:59:51 +01:00
|
|
|
PS.get().loadWorld(name, this);
|
|
|
|
loaded = true;
|
|
|
|
}
|
|
|
|
// Set random seed
|
|
|
|
this.random.state = (cx << 16) | (cz & 0xFFFF);
|
|
|
|
// Process the chunk
|
|
|
|
result.modified = false;
|
|
|
|
ChunkManager.preProcessChunk(result);
|
|
|
|
if (result.modified) {
|
|
|
|
return;
|
2015-03-27 08:15:41 +01:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
PlotArea area = PS.get().getPlotArea(world.getName(), null);
|
|
|
|
plotGenerator.generateChunk(chunkSetter, area, this.random);
|
|
|
|
ChunkManager.postProcessChunk(result);
|
|
|
|
return;
|
2015-03-27 08:15:41 +01:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
@Override
|
|
|
|
public short[][] generateExtBlockSections(final World world, final Random r, final int cx, final int cz, final BiomeGrid grid) {
|
|
|
|
if (!(chunkSetter instanceof GenChunk)) {
|
|
|
|
PS.stacktrace();
|
|
|
|
return new short[16][];
|
2015-03-27 09:20:19 +01:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
GenChunk result = (GenChunk) chunkSetter;
|
|
|
|
// Set the chunk location
|
|
|
|
result.setChunkWrapper(SetQueue.IMP.new ChunkWrapper(world.getName(), cx, cz));
|
|
|
|
// Set the result data
|
|
|
|
result.result = new short[16][];
|
|
|
|
result.result_data = new byte[16][];
|
2016-02-28 18:08:29 +01:00
|
|
|
result.grid = grid;
|
2016-02-10 19:59:51 +01:00
|
|
|
// Catch any exceptions (as exceptions usually thrown
|
|
|
|
try {
|
|
|
|
// Fill the result data
|
|
|
|
if (platformGenerator != this) {
|
|
|
|
return platformGenerator.generateExtBlockSections(world, r, cx, cz, grid);
|
|
|
|
} else {
|
|
|
|
generate(world, cx, cz, result);
|
|
|
|
}
|
|
|
|
} catch (Throwable e) {
|
|
|
|
e.printStackTrace();
|
2015-03-27 09:20:19 +01:00
|
|
|
}
|
2016-02-10 19:59:51 +01:00
|
|
|
// Return the result data
|
|
|
|
return result.result;
|
2015-03-27 08:15:41 +01:00
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2015-03-27 09:20:19 +01:00
|
|
|
/**
|
|
|
|
* Allow spawning everywhere
|
|
|
|
*/
|
|
|
|
@Override
|
2015-09-13 06:04:31 +02:00
|
|
|
public boolean canSpawn(final World world, final int x, final int z) {
|
2015-03-27 09:20:19 +01:00
|
|
|
return true;
|
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
if (platformGenerator == this) {
|
|
|
|
return "" + plotGenerator;
|
|
|
|
}
|
|
|
|
return platformGenerator == null ? "null" : platformGenerator.getClass().getName();
|
|
|
|
}
|
2015-09-13 06:04:31 +02:00
|
|
|
|
2016-02-10 19:59:51 +01:00
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (obj == null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return (toString().equals(obj.toString()) || toString().equals(obj.getClass().getName()));
|
|
|
|
}
|
2014-10-08 07:53:09 +02:00
|
|
|
}
|