mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 10:32:30 +00:00
Implement chunk serialization
This commit is contained in:
parent
f727e9d297
commit
c8e564c2d3
8
pom.xml
8
pom.xml
@ -95,13 +95,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.polydev</groupId>
|
<groupId>org.polydev</groupId>
|
||||||
<artifactId>gaea</artifactId>
|
<artifactId>gaea</artifactId>
|
||||||
<version>1.10.17</version>
|
<version>1.10.42</version>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.vecmath</groupId>
|
|
||||||
<artifactId>vecmath</artifactId>
|
|
||||||
<version>1.5.2</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.lucko</groupId>
|
<groupId>me.lucko</groupId>
|
||||||
|
@ -2,10 +2,13 @@ package com.dfsek.terra;
|
|||||||
|
|
||||||
import com.dfsek.terra.config.ConfigUtil;
|
import com.dfsek.terra.config.ConfigUtil;
|
||||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||||
|
import com.dfsek.terra.structure.StructureManager;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
import me.lucko.commodore.Commodore;
|
import me.lucko.commodore.Commodore;
|
||||||
import me.lucko.commodore.CommodoreProvider;
|
import me.lucko.commodore.CommodoreProvider;
|
||||||
import me.lucko.commodore.file.CommodoreFileFormat;
|
import me.lucko.commodore.file.CommodoreFileFormat;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
@ -15,10 +18,13 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class Terra extends JavaPlugin {
|
public class Terra extends JavaPlugin {
|
||||||
private static FileConfiguration config;
|
private static FileConfiguration config;
|
||||||
private static Terra instance;
|
private static Terra instance;
|
||||||
|
private static StructureManager manager;
|
||||||
|
|
||||||
public static Terra getInstance() {
|
public static Terra getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
@ -26,13 +32,13 @@ public class Terra extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
super.onDisable();
|
TerraChunkGenerator.saveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
ConfigUtil.loadConfig(this);
|
ConfigUtil.loadConfig(this);
|
||||||
//getCommand("terra").setExecutor(new TerraCommand());
|
manager = new StructureManager(this);
|
||||||
|
|
||||||
PluginCommand command = getCommand("terra");
|
PluginCommand command = getCommand("terra");
|
||||||
command.setExecutor(new TerraCommand());
|
command.setExecutor(new TerraCommand());
|
||||||
@ -46,6 +52,7 @@ public class Terra extends JavaPlugin {
|
|||||||
} else getLogger().severe("Brigadier is not properly supported! Commands will NOT work properly!");
|
} else getLogger().severe("Brigadier is not properly supported! Commands will NOT work properly!");
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
config = getConfig();
|
config = getConfig();
|
||||||
|
Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, TerraChunkGenerator::saveAll, ConfigUtil.dataSave, ConfigUtil.dataSave);
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +67,10 @@ public class Terra extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StructureManager getStructureManager() {
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
|
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
|
||||||
return new TerraChunkGenerator();
|
return new TerraChunkGenerator();
|
||||||
|
@ -16,6 +16,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
@ -30,6 +31,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class TerraCommand implements CommandExecutor, TabExecutor {
|
public class TerraCommand implements CommandExecutor, TabExecutor {
|
||||||
@ -123,6 +125,10 @@ public class TerraCommand implements CommandExecutor, TabExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "save-data":
|
||||||
|
TerraChunkGenerator.saveAll();
|
||||||
|
sender.sendMessage("Saved population data.");
|
||||||
|
return true;
|
||||||
case "structure":
|
case "structure":
|
||||||
if(! (sender instanceof Player)) {
|
if(! (sender instanceof Player)) {
|
||||||
sender.sendMessage("Command is for players only.");
|
sender.sendMessage("Command is for players only.");
|
||||||
@ -152,13 +158,13 @@ public class TerraCommand implements CommandExecutor, TabExecutor {
|
|||||||
BlockVector3 max = selection.getMaximumPoint();
|
BlockVector3 max = selection.getMaximumPoint();
|
||||||
Location l1 = new Location(pl.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ());
|
Location l1 = new Location(pl.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ());
|
||||||
Location l2 = new Location(pl.getWorld(), max.getBlockX(), max.getBlockY(), max.getBlockZ());
|
Location l2 = new Location(pl.getWorld(), max.getBlockX(), max.getBlockY(), max.getBlockZ());
|
||||||
GaeaStructure structure = new GaeaStructure(l1, l2);
|
GaeaStructure structure = new GaeaStructure(l1, l2, args[2]);
|
||||||
try {
|
try {
|
||||||
File file = new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", args[2] + ".tstructure");
|
File file = new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", args[2] + ".tstructure");
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
structure.save(file);
|
structure.save(file);
|
||||||
sender.sendMessage("Saved to " + file.getPath());
|
sender.sendMessage("Saved structure with ID " + structure.getId() + ", UUID: " + structure.getUuid().toString() + " to " + file.getPath());
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -174,7 +180,7 @@ public class TerraCommand implements CommandExecutor, TabExecutor {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if("getspawn".equals(args[1])) {
|
} else if("getspawn".equals(args[1])) {
|
||||||
Vector v = new StructureSpawn(50, 25).getNearestSpawn(pl.getLocation().getBlockX(), pl.getLocation().getBlockZ(), pl.getWorld().getSeed());
|
Vector v = new StructureSpawn(500, 100).getNearestSpawn(pl.getLocation().getBlockX(), pl.getLocation().getBlockZ(), pl.getWorld().getSeed());
|
||||||
sender.sendMessage(v.getBlockX() + ":" + v.getBlockZ());
|
sender.sendMessage(v.getBlockX() + ":" + v.getBlockZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.dfsek.terra.biome;
|
package com.dfsek.terra.biome;
|
||||||
|
|
||||||
|
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||||
|
import com.dfsek.terra.generation.UserDefinedGenerator;
|
||||||
import org.polydev.gaea.biome.Biome;
|
import org.polydev.gaea.biome.Biome;
|
||||||
import org.polydev.gaea.biome.Generator;
|
import org.polydev.gaea.biome.Generator;
|
||||||
import org.polydev.gaea.biome.Decorator;
|
import org.polydev.gaea.biome.Decorator;
|
||||||
|
@ -13,17 +13,21 @@ import org.bukkit.configuration.file.FileConfiguration;
|
|||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ConfigUtil {
|
public class ConfigUtil {
|
||||||
public static boolean debug;
|
public static boolean debug;
|
||||||
|
public static long dataSave;
|
||||||
public static void loadConfig(JavaPlugin main) {
|
public static void loadConfig(JavaPlugin main) {
|
||||||
main.saveDefaultConfig();
|
main.saveDefaultConfig();
|
||||||
FileConfiguration config = main.getConfig();
|
FileConfiguration config = main.getConfig();
|
||||||
|
|
||||||
debug = config.getBoolean("debug", false);
|
debug = config.getBoolean("debug", false);
|
||||||
|
dataSave = Duration.parse(Objects.requireNonNull(config.getString("data-save", "PT6M"))).toMillis()/20L;
|
||||||
|
|
||||||
Logger logger = main.getLogger();
|
Logger logger = main.getLogger();
|
||||||
logger.info("Loading config values");
|
logger.info("Loading config values");
|
||||||
|
@ -3,8 +3,8 @@ package com.dfsek.terra.config.genconfig;
|
|||||||
import com.dfsek.terra.MaxMin;
|
import com.dfsek.terra.MaxMin;
|
||||||
import com.dfsek.terra.TerraTree;
|
import com.dfsek.terra.TerraTree;
|
||||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.biome.UserDefinedDecorator;
|
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||||
import com.dfsek.terra.biome.UserDefinedGenerator;
|
import com.dfsek.terra.generation.UserDefinedGenerator;
|
||||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||||
import com.dfsek.terra.config.ConfigUtil;
|
import com.dfsek.terra.config.ConfigUtil;
|
||||||
import com.dfsek.terra.config.TerraConfigObject;
|
import com.dfsek.terra.config.TerraConfigObject;
|
||||||
|
@ -2,14 +2,11 @@ package com.dfsek.terra.config.genconfig;
|
|||||||
|
|
||||||
import com.dfsek.terra.MaxMin;
|
import com.dfsek.terra.MaxMin;
|
||||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||||
import com.dfsek.terra.config.ConfigLoader;
|
|
||||||
import com.dfsek.terra.config.TerraConfigObject;
|
import com.dfsek.terra.config.TerraConfigObject;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.polydev.gaea.math.ProbabilityCollection;
|
import org.polydev.gaea.math.ProbabilityCollection;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -123,6 +120,8 @@ public class CarverConfig extends TerraConfigObject {
|
|||||||
|
|
||||||
replaceIsBlacklistInner = getBoolean("palette.inner.replace-blacklist", false);
|
replaceIsBlacklistInner = getBoolean("palette.inner.replace-blacklist", false);
|
||||||
replaceIsBlacklistOuter = getBoolean("palette.outer.replace-blacklist", false);
|
replaceIsBlacklistOuter = getBoolean("palette.outer.replace-blacklist", false);
|
||||||
|
replaceIsBlacklistTop = getBoolean("palette.top.replace-blacklist", false);
|
||||||
|
replaceIsBlacklistBottom = getBoolean("palette.bottom.replace-blacklist", false);
|
||||||
|
|
||||||
double[] start = new double[] {getDouble("start.x"), getDouble("start.y"), getDouble("start.z")};
|
double[] start = new double[] {getDouble("start.x"), getDouble("start.y"), getDouble("start.z")};
|
||||||
double[] mutate = new double[] {getDouble("mutate.x"), getDouble("mutate.y"), getDouble("mutate.z"), getDouble("mutate.radius")};
|
double[] mutate = new double[] {getDouble("mutate.x"), getDouble("mutate.y"), getDouble("mutate.z"), getDouble("mutate.radius")};
|
||||||
|
@ -5,6 +5,7 @@ import com.dfsek.terra.config.WorldConfig;
|
|||||||
import com.dfsek.terra.population.CavePopulator;
|
import com.dfsek.terra.population.CavePopulator;
|
||||||
import com.dfsek.terra.population.FloraPopulator;
|
import com.dfsek.terra.population.FloraPopulator;
|
||||||
import com.dfsek.terra.population.OrePopulator;
|
import com.dfsek.terra.population.OrePopulator;
|
||||||
|
import com.dfsek.terra.population.StructurePopulator;
|
||||||
import com.dfsek.terra.population.TreePopulator;
|
import com.dfsek.terra.population.TreePopulator;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -18,17 +19,25 @@ import org.polydev.gaea.math.ChunkInterpolator;
|
|||||||
import org.polydev.gaea.math.FastNoise;
|
import org.polydev.gaea.math.FastNoise;
|
||||||
import org.polydev.gaea.population.PopulationManager;
|
import org.polydev.gaea.population.PopulationManager;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class TerraChunkGenerator extends GaeaChunkGenerator {
|
public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||||
private static final BlockData STONE = Material.STONE.createBlockData();
|
private static final BlockData STONE = Material.STONE.createBlockData();
|
||||||
private static final BlockData WATER = Material.WATER.createBlockData();
|
private static final BlockData WATER = Material.WATER.createBlockData();
|
||||||
private final PopulationManager popMan = new PopulationManager();
|
private final PopulationManager popMan = new PopulationManager();
|
||||||
|
private boolean needsLoad = true;
|
||||||
|
private static final Map<World, PopulationManager> popMap = new HashMap<>();
|
||||||
|
|
||||||
public TerraChunkGenerator() {
|
public TerraChunkGenerator() {
|
||||||
super(ChunkInterpolator.InterpolationType.TRILINEAR);
|
super(ChunkInterpolator.InterpolationType.TRILINEAR);
|
||||||
|
popMan.attach(new StructurePopulator());
|
||||||
popMan.attach(new TreePopulator());
|
popMan.attach(new TreePopulator());
|
||||||
popMan.attach(new FloraPopulator());
|
popMan.attach(new FloraPopulator());
|
||||||
popMan.attach(new OrePopulator());
|
popMan.attach(new OrePopulator());
|
||||||
@ -36,6 +45,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkData generateBase(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, FastNoise fastNoise) {
|
public ChunkData generateBase(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, FastNoise fastNoise) {
|
||||||
|
if(needsLoad) load(world);
|
||||||
ChunkData chunk = createChunkData(world);
|
ChunkData chunk = createChunkData(world);
|
||||||
int sea = WorldConfig.fromWorld(world).seaLevel;
|
int sea = WorldConfig.fromWorld(world).seaLevel;
|
||||||
for(byte x = 0; x < 16; x++) {
|
for(byte x = 0; x < 16; x++) {
|
||||||
@ -49,6 +59,31 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void load(World w) {
|
||||||
|
try {
|
||||||
|
popMan.loadBlocks(w);
|
||||||
|
} catch(IOException e) {
|
||||||
|
if(e instanceof FileNotFoundException) {
|
||||||
|
Bukkit.getLogger().warning("[Terra] No population chunks were loaded. If this is your first time starting your server with Terra, or if you are creating a new world, this is normal.");
|
||||||
|
} else e.printStackTrace();
|
||||||
|
} catch(ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
popMap.put(w, popMan);
|
||||||
|
needsLoad = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveAll() {
|
||||||
|
for(Map.Entry<World, PopulationManager> e : popMap.entrySet()) {
|
||||||
|
try {
|
||||||
|
e.getValue().saveBlocks(e.getKey());
|
||||||
|
Bukkit.getLogger().info("[Terra] Saved data for world " + e.getKey().getName());
|
||||||
|
} catch(IOException ioException) {
|
||||||
|
ioException.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNoiseOctaves(World world) {
|
public int getNoiseOctaves(World world) {
|
||||||
return 4;
|
return 4;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.biome;
|
package com.dfsek.terra.generation;
|
||||||
|
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.polydev.gaea.biome.Decorator;
|
import org.polydev.gaea.biome.Decorator;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dfsek.terra.biome;
|
package com.dfsek.terra.generation;
|
||||||
|
|
||||||
import com.dfsek.terra.math.NoiseFunction2;
|
import com.dfsek.terra.math.NoiseFunction2;
|
||||||
import com.dfsek.terra.math.NoiseFunction3;
|
import com.dfsek.terra.math.NoiseFunction3;
|
@ -21,6 +21,7 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class CavePopulator extends BlockPopulator {
|
public class CavePopulator extends BlockPopulator {
|
||||||
|
private static final Map<Material, BlockData> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
|
||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
||||||
ProfileFuture cave = TerraProfiler.fromWorld(world).measure("CaveTime");
|
ProfileFuture cave = TerraProfiler.fromWorld(world).measure("CaveTime");
|
||||||
@ -34,16 +35,16 @@ public class CavePopulator extends BlockPopulator {
|
|||||||
Material m = b.getType();
|
Material m = b.getType();
|
||||||
if(e.getValue().equals(CarvingData.CarvingType.CENTER) && c.isReplaceableInner(m)) {
|
if(e.getValue().equals(CarvingData.CarvingType.CENTER) && c.isReplaceableInner(m)) {
|
||||||
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
||||||
b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), false);
|
b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), c.getUpdateBlocks().contains(m));
|
||||||
} else if(e.getValue().equals(CarvingData.CarvingType.WALL) && c.isReplaceableOuter(m)){
|
} else if(e.getValue().equals(CarvingData.CarvingType.WALL) && c.isReplaceableOuter(m)){
|
||||||
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
||||||
b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), false);
|
b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), c.getUpdateBlocks().contains(m));
|
||||||
} else if(e.getValue().equals(CarvingData.CarvingType.TOP) && c.isReplaceableTop(m)){
|
} else if(e.getValue().equals(CarvingData.CarvingType.TOP) && c.isReplaceableTop(m)){
|
||||||
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
||||||
b.setBlockData(c.getPaletteTop(v.getBlockY()).get(random), false);
|
b.setBlockData(c.getPaletteTop(v.getBlockY()).get(random), c.getUpdateBlocks().contains(m));
|
||||||
} else if(e.getValue().equals(CarvingData.CarvingType.BOTTOM) && c.isReplaceableBottom(m)){
|
} else if(e.getValue().equals(CarvingData.CarvingType.BOTTOM) && c.isReplaceableBottom(m)){
|
||||||
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType());
|
||||||
b.setBlockData(c.getPaletteBottom(v.getBlockY()).get(random), false);
|
b.setBlockData(c.getPaletteBottom(v.getBlockY()).get(random), c.getUpdateBlocks().contains(m));
|
||||||
}
|
}
|
||||||
if(c.getUpdateBlocks().contains(m)) {
|
if(c.getUpdateBlocks().contains(m)) {
|
||||||
updateNeeded.add(b);
|
updateNeeded.add(b);
|
||||||
@ -58,7 +59,7 @@ public class CavePopulator extends BlockPopulator {
|
|||||||
while(mut.getBlock().getType().equals(orig));
|
while(mut.getBlock().getType().equals(orig));
|
||||||
try {
|
try {
|
||||||
if(c.getShiftedBlocks().get(shiftCandidate.get(l)).contains(mut.getBlock().getType())) {
|
if(c.getShiftedBlocks().get(shiftCandidate.get(l)).contains(mut.getBlock().getType())) {
|
||||||
mut.getBlock().setType(shiftCandidate.get(l));
|
mut.getBlock().setBlockData(shiftStorage.computeIfAbsent(shiftCandidate.get(l), Material::createBlockData), false);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
} catch(NullPointerException ignored) {}
|
} catch(NullPointerException ignored) {}
|
||||||
|
@ -4,6 +4,7 @@ import com.dfsek.terra.TerraProfiler;
|
|||||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -13,11 +14,16 @@ import org.polydev.gaea.population.GaeaBlockPopulator;
|
|||||||
import org.polydev.gaea.profiler.ProfileFuture;
|
import org.polydev.gaea.profiler.ProfileFuture;
|
||||||
import org.polydev.gaea.world.Flora;
|
import org.polydev.gaea.world.Flora;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class FloraPopulator extends GaeaBlockPopulator {
|
public class FloraPopulator extends GaeaBlockPopulator {
|
||||||
|
Set<Chunk> pop = new HashSet<>();
|
||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
||||||
|
if(pop.contains(chunk)) Bukkit.getLogger().warning("Already populated flora in chunk: " + chunk);
|
||||||
|
pop.add(chunk);
|
||||||
ProfileFuture flora = TerraProfiler.fromWorld(world).measure("FloraTime");
|
ProfileFuture flora = TerraProfiler.fromWorld(world).measure("FloraTime");
|
||||||
for(int x = 0; x < 16; x++) {
|
for(int x = 0; x < 16; x++) {
|
||||||
for(int z = 0; z < 16; z++) {
|
for(int z = 0; z < 16; z++) {
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.dfsek.terra.population;
|
||||||
|
|
||||||
|
import com.dfsek.terra.Terra;
|
||||||
|
import com.dfsek.terra.structure.GaeaStructure;
|
||||||
|
import com.dfsek.terra.structure.StructureSpawn;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.polydev.gaea.population.GaeaBlockPopulator;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class StructurePopulator extends GaeaBlockPopulator {
|
||||||
|
StructureSpawn spawnTest = new StructureSpawn(100, 5);
|
||||||
|
Set<Chunk> pop = new HashSet<>();
|
||||||
|
@Override
|
||||||
|
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
||||||
|
if(pop.contains(chunk)) Bukkit.getLogger().warning("Already populated structures in chunk: " + chunk);
|
||||||
|
pop.add(chunk);
|
||||||
|
Location near = spawnTest.getNearestSpawn((chunk.getX() << 4) + 8, (chunk.getZ() << 4), world.getSeed()).toLocation(world);
|
||||||
|
if(near.getChunk().equals(chunk)) {
|
||||||
|
Terra.getInstance().getLogger().info("Spawning structure at " + near.toString() + " in chunk " + chunk);
|
||||||
|
try {
|
||||||
|
GaeaStructure struc = GaeaStructure.load(new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", "demo.tstructure"));
|
||||||
|
near.setY(world.getHighestBlockYAt(near));
|
||||||
|
struc.paste(near);
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ package com.dfsek.terra.population;
|
|||||||
import com.dfsek.terra.Terra;
|
import com.dfsek.terra.Terra;
|
||||||
import com.dfsek.terra.TerraProfiler;
|
import com.dfsek.terra.TerraProfiler;
|
||||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||||
import com.dfsek.terra.biome.UserDefinedDecorator;
|
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
@ -15,10 +15,13 @@ import java.io.ObjectInputStream;
|
|||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GaeaStructure implements Serializable {
|
public class GaeaStructure implements Serializable {
|
||||||
public static final long serialVersionUID = -6664585217063842034L;
|
public static final long serialVersionUID = -6664585217063842035L;
|
||||||
private final StructureContainedBlock[][][] structure;
|
private final StructureContainedBlock[][][] structure;
|
||||||
|
private final String id;
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
public static GaeaStructure load(File f) throws IOException {
|
public static GaeaStructure load(File f) throws IOException {
|
||||||
try {
|
try {
|
||||||
@ -28,7 +31,9 @@ public class GaeaStructure implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GaeaStructure(Location l1, Location l2) {
|
public GaeaStructure(Location l1, Location l2, String id) {
|
||||||
|
this.id = id;
|
||||||
|
this.uuid = UUID.randomUUID();
|
||||||
if(l1.getX() > l2.getX() || l1.getY() > l2.getY() || l1.getZ() > l2.getZ()) throw new IllegalArgumentException("Invalid locations provided!");
|
if(l1.getX() > l2.getX() || l1.getY() > l2.getY() || l1.getZ() > l2.getZ()) throw new IllegalArgumentException("Invalid locations provided!");
|
||||||
structure = new StructureContainedBlock[l2.getBlockX()-l1.getBlockX()+1][l2.getBlockY()-l1.getBlockY()+1][l2.getBlockZ()-l1.getBlockZ()+1];
|
structure = new StructureContainedBlock[l2.getBlockX()-l1.getBlockX()+1][l2.getBlockY()-l1.getBlockY()+1][l2.getBlockZ()-l1.getBlockZ()+1];
|
||||||
for(int x = 0; x <= l2.getBlockX()-l1.getBlockX(); x++) {
|
for(int x = 0; x <= l2.getBlockX()-l1.getBlockX(); x++) {
|
||||||
@ -87,4 +92,12 @@ public class GaeaStructure implements Serializable {
|
|||||||
oos.writeObject(o);
|
oos.writeObject(o);
|
||||||
oos.close();
|
oos.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.dfsek.terra.structure;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class StructureManager {
|
||||||
|
private static StructureManager singleton;
|
||||||
|
private Logger logger;
|
||||||
|
private final Map<UUID, GaeaStructure> structures = new HashMap<>();
|
||||||
|
public StructureManager(JavaPlugin main) {
|
||||||
|
if(singleton!= null) throw new IllegalStateException("Only one instance of StructureManager may exist at a given time.");
|
||||||
|
this.logger = main.getLogger();
|
||||||
|
logger.info("Initializing StructureManager...");
|
||||||
|
singleton = this;
|
||||||
|
}
|
||||||
|
public GaeaStructure get(UUID uuid) {
|
||||||
|
return structures.get(uuid);
|
||||||
|
}
|
||||||
|
public void load(File file) throws IOException {
|
||||||
|
GaeaStructure s = GaeaStructure.load(file);
|
||||||
|
structures.put(s.getUuid(), s);
|
||||||
|
}
|
||||||
|
}
|
@ -33,13 +33,11 @@ public class StructureSpawn {
|
|||||||
return shortest;
|
return shortest;
|
||||||
}
|
}
|
||||||
private Vector getStructureChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
|
private Vector getStructureChunkSpawn(int structureChunkX, int structureChunkZ, long seed) {
|
||||||
if(ConfigUtil.debug) Bukkit.getLogger().info("Structure chunk: " + structureChunkX + ":" + structureChunkZ);
|
|
||||||
Random r = new Random(MathUtil.getCarverChunkSeed(structureChunkX, structureChunkZ, seed));
|
Random r = new Random(MathUtil.getCarverChunkSeed(structureChunkX, structureChunkZ, seed));
|
||||||
int offsetX = r.nextInt(width);
|
int offsetX = r.nextInt(width);
|
||||||
int offsetZ = r.nextInt(width);
|
int offsetZ = r.nextInt(width);
|
||||||
int sx = structureChunkX * (width + 2*separation) + offsetX;
|
int sx = structureChunkX * (width + 2*separation) + offsetX;
|
||||||
int sz = structureChunkZ * (width + 2*separation) + offsetZ;
|
int sz = structureChunkZ * (width + 2*separation) + offsetZ;
|
||||||
if(ConfigUtil.debug) Bukkit.getLogger().info("Structure coords: " + sx + ":" + sz);
|
|
||||||
return new Vector(sx, 0, sz);
|
return new Vector(sx, 0, sz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,5 @@ terra {
|
|||||||
}
|
}
|
||||||
getspawn;
|
getspawn;
|
||||||
}
|
}
|
||||||
|
save-data;
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user