mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
Add EntityFeature to StructureConfig.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.terra.async.AsyncStructureFinder;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.util.StructureTypeEnum;
|
||||
import org.bukkit.entity.EnderSignal;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.dfsek.terra.command.biome;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeSnowConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.dfsek.terra.command.structure;
|
||||
import com.dfsek.terra.Terra;
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.async.AsyncStructureFinder;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.config.lang.LangUtil;
|
||||
import com.dfsek.terra.generation.TerraChunkGenerator;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -12,7 +12,6 @@ import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.command.WorldCommand;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.dfsek.terra.config.genconfig.CarverConfig;
|
||||
import com.dfsek.terra.config.genconfig.FloraConfig;
|
||||
import com.dfsek.terra.config.genconfig.OreConfig;
|
||||
import com.dfsek.terra.config.genconfig.PaletteConfig;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.TreeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.AbstractBiomeConfig;
|
||||
import com.dfsek.terra.config.genconfig.biome.BiomeConfig;
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.dfsek.terra.config.TerraConfig;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||
import com.dfsek.terra.generation.UserDefinedGenerator;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.dfsek.terra.config.genconfig.structure;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.base.ConfigUtil;
|
||||
import com.dfsek.terra.config.exception.ConfigException;
|
||||
import com.dfsek.terra.structure.features.EntityFeature;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class EntityFeatureConfig implements FeatureConfig {
|
||||
private final EntityFeature feature;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityFeatureConfig(Map<String, Object> items) throws InvalidConfigurationException {
|
||||
if(! items.containsKey("entity")) throw new ConfigException("No EntityType specified!", "EntityFeature");
|
||||
if(! items.containsKey("amount")) throw new ConfigException("No amount specified!", "EntityFeature");
|
||||
if(! items.containsKey("attempts")) throw new ConfigException("Attempts not specified!", "EntityFeature");
|
||||
if(! items.containsKey("in-height")) throw new ConfigException("Spawn Checking Height not specified!", "EntityFeature");
|
||||
if(! items.containsKey("spawnable-on")) throw new ConfigException("No Spawnable-on materials specified!", "EntityFeature");
|
||||
if(! items.containsKey("spawnable-in")) throw new ConfigException("No Spawnable-in materials specified!", "EntityFeature");
|
||||
|
||||
EntityType type;
|
||||
try {
|
||||
type = EntityType.valueOf((String) items.get("entity"));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new InvalidConfigurationException("No such EntityType: " + items.get("entity"));
|
||||
} catch(ClassCastException e) {
|
||||
throw new InvalidConfigurationException("Error in Entity Configuration!");
|
||||
}
|
||||
|
||||
int attempts = (Integer) items.get("attempts");
|
||||
int height = (Integer) items.get("in-height");
|
||||
|
||||
Range amount;
|
||||
try {
|
||||
Map<String, Integer> amountMap = (Map<String, Integer>) items.get("amount");
|
||||
amount = new Range(amountMap.get("min"), amountMap.get("max"));
|
||||
} catch(ClassCastException e) {
|
||||
throw new InvalidConfigurationException("Error in Amount Configuration!");
|
||||
}
|
||||
|
||||
Set<Material> on = ConfigUtil.toBlockData((List<String>) items.get("spawnable-on"), "SpawnableOn", "");
|
||||
Set<Material> in = ConfigUtil.toBlockData((List<String>) items.get("spawnable-in"), "SpawnableIn", "");
|
||||
|
||||
this.feature = new EntityFeature(type, amount, attempts, on, in, height);
|
||||
Debug.info("Loaded EntityFeature with type: " + type);
|
||||
}
|
||||
@Override
|
||||
public Feature getFeature() {
|
||||
return feature;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.config.genconfig.structure;
|
||||
|
||||
import com.dfsek.terra.config.TerraConfigSection;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
|
||||
public interface FeatureConfig {
|
||||
Feature getFeature();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
package com.dfsek.terra.config.genconfig.structure;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.config.TerraConfig;
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.config.exception.NotFoundException;
|
||||
import com.dfsek.terra.population.StructurePopulator;
|
||||
import com.dfsek.terra.procgen.GridSpawn;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.json.simple.parser.ParseException;
|
||||
@@ -19,7 +20,9 @@ import org.polydev.gaea.structures.loot.LootTable;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
@@ -31,8 +34,11 @@ public class StructureConfig extends TerraConfig {
|
||||
private final Range searchStart;
|
||||
private final Range bound;
|
||||
private final Map<Integer, LootTable> loot = new HashMap<>();
|
||||
private final List<Feature> features;
|
||||
|
||||
StructurePopulator.SearchType type;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public StructureConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||
super(file, config);
|
||||
if(! contains("id")) throw new ConfigException("No ID specified!", "null");
|
||||
@@ -76,6 +82,16 @@ public class StructureConfig extends TerraConfig {
|
||||
}
|
||||
}
|
||||
|
||||
features = new ArrayList<>();
|
||||
if(contains("features")) {
|
||||
for(Map<?, ?> map : getMapList("features")) {
|
||||
for(Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if(entry.getKey().equals("ENTITY_FEATURE"))
|
||||
features.add(new EntityFeatureConfig((Map<String, Object>) entry.getValue()).getFeature());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spawn = new GridSpawn(getInt("spawn.width", 500), getInt("spawn.padding", 100));
|
||||
searchStart = new Range(getInt("spawn.start.min", 72), getInt("spawn.start.max", 72));
|
||||
bound = new Range(getInt("spawn.bound.min", 48), getInt("spawn.bound.max", 72));
|
||||
@@ -86,6 +102,10 @@ public class StructureConfig extends TerraConfig {
|
||||
}
|
||||
}
|
||||
|
||||
public List<Feature> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
@@ -132,11 +132,9 @@ public class TerraChunkGenerator extends GaeaChunkGenerator {
|
||||
private void load(World w) {
|
||||
try {
|
||||
popMan.loadBlocks(w);
|
||||
} catch(IOException e) {
|
||||
if(e instanceof FileNotFoundException) {
|
||||
LangUtil.log("warning.no-population", Level.WARNING);
|
||||
} else e.printStackTrace();
|
||||
} catch(ClassNotFoundException e) {
|
||||
} catch(FileNotFoundException e) {
|
||||
LangUtil.log("warning.no-population", Level.WARNING);
|
||||
} catch(IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
popMap.put(w, popMan);
|
||||
|
||||
@@ -6,10 +6,11 @@ import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.base.ConfigPack;
|
||||
import com.dfsek.terra.config.genconfig.StructureConfig;
|
||||
import com.dfsek.terra.config.genconfig.structure.StructureConfig;
|
||||
import com.dfsek.terra.procgen.math.Vector2;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import com.dfsek.terra.structure.StructureContainedInventory;
|
||||
import com.dfsek.terra.structure.features.Feature;
|
||||
import com.dfsek.terra.util.structure.RotationUtil;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@@ -67,6 +68,7 @@ public class StructurePopulator extends BlockPopulator {
|
||||
Debug.stack(e);
|
||||
}
|
||||
}
|
||||
for(Feature f : conf.getFeatures()) f.apply(struc, spawn, chunk); // Apply features.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.dfsek.terra.structure.features;
|
||||
|
||||
import com.dfsek.terra.Debug;
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import com.dfsek.terra.structure.StructureInfo;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.polydev.gaea.math.MathUtil;
|
||||
import org.polydev.gaea.math.Range;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class EntityFeature implements Feature {
|
||||
private final EntityType type;
|
||||
private final Range amount;
|
||||
private final int attempts;
|
||||
private final Set<Material> in;
|
||||
private final Set<Material> stand;
|
||||
private final int inSize;
|
||||
public EntityFeature(EntityType type, Range amount, int attempts, Set<Material> stand, Set<Material> in, int inSize) {
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
this.attempts = attempts;
|
||||
this.in = in;
|
||||
this.stand = stand;
|
||||
this.inSize = inSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Structure structure, Location l, Chunk chunk) {
|
||||
Random random = new Random(MathUtil.getCarverChunkSeed(chunk.getX(), chunk.getZ(), chunk.getWorld().getSeed()));
|
||||
|
||||
int amountSpawn = amount.get(random);
|
||||
|
||||
StructureInfo info = structure.getStructureInfo();
|
||||
Range x = new Range(0, info.getSizeZ());
|
||||
Range y = new Range(0, info.getSizeY());
|
||||
Range z = new Range(0, info.getSizeZ());
|
||||
|
||||
int cx = info.getCenterX();
|
||||
int cz = info.getCenterZ();
|
||||
|
||||
for(int i = 0; i < amountSpawn && i < attempts; i++) {
|
||||
int yv = y.get(random);
|
||||
Location attempt = l.clone().add(x.get(random)-cx, yv, z.get(random)-cz);
|
||||
if(!isInChunk(chunk, attempt)) continue; // Don't attempt spawn if not in current chunk.
|
||||
|
||||
boolean canSpawn = false;
|
||||
while(yv >= 0 && attempt.getBlockY() >= l.getBlockY()) { // Go down, see if valid spawns exist.
|
||||
canSpawn = true;
|
||||
Block on = attempt.getBlock();
|
||||
attempt.subtract(0, 1, 0);
|
||||
yv--;
|
||||
|
||||
if(!stand.contains(on.getType())) continue;
|
||||
|
||||
for(int j = 1; j < inSize + 1; j++) if(! in.contains(on.getRelative(BlockFace.UP, j).getType())) canSpawn = false;
|
||||
|
||||
if(canSpawn) break;
|
||||
}
|
||||
if(canSpawn) {
|
||||
Debug.info("Spawning entity at " + attempt);
|
||||
chunk.getWorld().spawnEntity(attempt.add(0.5, 1, 0.5), type); // Add 0.5 to X & Z so entity spawns in center of block.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInChunk(Chunk c, Location l) {
|
||||
return Math.floorDiv(l.getBlockX(), 16) == c.getX() && Math.floorDiv(l.getBlockZ(), 16) == c.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Structure structure, Location l, Random random) {
|
||||
int amountSpawn = amount.get(random);
|
||||
|
||||
StructureInfo info = structure.getStructureInfo();
|
||||
Range x = new Range(0, info.getSizeZ());
|
||||
Range y = new Range(0, info.getSizeY());
|
||||
Range z = new Range(0, info.getSizeZ());
|
||||
|
||||
int cx = info.getCenterX();
|
||||
int cz = info.getCenterZ();
|
||||
|
||||
for(int i = 0; i < amountSpawn && i < attempts; i++) {
|
||||
int yv = y.get(random);
|
||||
Location attempt = l.clone().add(x.get(random)-cx, yv, z.get(random)-cz);
|
||||
|
||||
boolean canSpawn = false;
|
||||
while(yv >= 0 && attempt.getBlockY() >= l.getBlockY()) { // Go down, see if valid spawns exist.
|
||||
canSpawn = true;
|
||||
Block on = attempt.getBlock();
|
||||
attempt.subtract(0, 1, 0);
|
||||
yv--;
|
||||
|
||||
if(!stand.contains(on.getType())) continue;
|
||||
|
||||
for(int j = 1; j < inSize + 1; j++) if(! in.contains(on.getRelative(BlockFace.UP, j).getType())) canSpawn = false;
|
||||
|
||||
if(canSpawn) break;
|
||||
}
|
||||
if(canSpawn) {
|
||||
Debug.info("Spawning entity at " + attempt);
|
||||
l.getWorld().spawnEntity(attempt.add(0.5, 1, 0.5), type); // Add 0.5 to X & Z so entity spawns in center of block.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpawnRule {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.structure.features;
|
||||
|
||||
import com.dfsek.terra.structure.Structure;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public interface Feature {
|
||||
void apply(Structure structure, Location l, Chunk chunk);
|
||||
void apply(Structure structure, Location l, Random random);
|
||||
}
|
||||
Reference in New Issue
Block a user