mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
all new NBTStructureLib features up to structure block (coming next)
This commit is contained in:
parent
a4a08aa9cd
commit
a32b04ed14
@ -13,6 +13,7 @@ import net.minecraft.command.ICommandSender;
|
|||||||
import net.minecraft.command.PlayerNotFoundException;
|
import net.minecraft.command.PlayerNotFoundException;
|
||||||
import net.minecraft.command.WrongUsageException;
|
import net.minecraft.command.WrongUsageException;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.util.ChatComponentText;
|
||||||
import net.minecraft.util.ChatComponentTranslation;
|
import net.minecraft.util.ChatComponentTranslation;
|
||||||
import net.minecraft.util.EnumChatFormatting;
|
import net.minecraft.util.EnumChatFormatting;
|
||||||
import net.minecraft.util.MathHelper;
|
import net.minecraft.util.MathHelper;
|
||||||
@ -71,6 +72,8 @@ public class CommandLocate extends CommandBase {
|
|||||||
ChatComponentTranslation message = new ChatComponentTranslation("commands.locate.success.coordinates", structure.name, pos.chunkXPos * 16, pos.chunkZPos * 16);
|
ChatComponentTranslation message = new ChatComponentTranslation("commands.locate.success.coordinates", structure.name, pos.chunkXPos * 16, pos.chunkZPos * 16);
|
||||||
message.getChatStyle().setColor(EnumChatFormatting.GREEN);
|
message.getChatStyle().setColor(EnumChatFormatting.GREEN);
|
||||||
sender.addChatMessage(message);
|
sender.addChatMessage(message);
|
||||||
|
} else if (args[0].equals("list")) {
|
||||||
|
sender.addChatMessage(new ChatComponentText(String.join(", ", NBTStructure.listStructures())));
|
||||||
} else {
|
} else {
|
||||||
throw new WrongUsageException(getCommandUsage(sender), new Object[0]);
|
throw new WrongUsageException(getCommandUsage(sender), new Object[0]);
|
||||||
}
|
}
|
||||||
@ -105,9 +108,9 @@ public class CommandLocate extends CommandBase {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
||||||
if(args.length == 1)
|
if(args.length == 1)
|
||||||
return getListOfStringsMatchingLastWord(args, "structure");
|
return getListOfStringsMatchingLastWord(args, "structure", "list");
|
||||||
|
|
||||||
if(args.length == 2) {
|
if(args.length == 2 && args[0].equals("structure")) {
|
||||||
List<String> structures = NBTStructure.listStructures();
|
List<String> structures = NBTStructure.listStructures();
|
||||||
return getListOfStringsMatchingLastWord(args, structures.toArray(new String[structures.size()]));
|
return getListOfStringsMatchingLastWord(args, structures.toArray(new String[structures.size()]));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,17 +9,47 @@ import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
|||||||
// Assigned to a Component to build
|
// Assigned to a Component to build
|
||||||
public class JigsawPiece {
|
public class JigsawPiece {
|
||||||
|
|
||||||
// Translates a given name into a jigsaw piece, for serialization
|
// Translates a given name into a jigsaw piece, for serialization
|
||||||
protected static Map<String, JigsawPiece> jigsawMap = new HashMap<>();
|
protected static Map<String, JigsawPiece> jigsawMap = new HashMap<>();
|
||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public final NBTStructure structure;
|
public final NBTStructure structure;
|
||||||
|
|
||||||
// Block modifiers, for randomization and terrain matching
|
// Block modifiers, for randomization and terrain matching
|
||||||
|
/**
|
||||||
|
* Replaces matching blocks using the result of a BlockSelector
|
||||||
|
*/
|
||||||
public Map<Block, BlockSelector> blockTable;
|
public Map<Block, BlockSelector> blockTable;
|
||||||
public boolean conformToTerrain = false; // moves every single column to the terrain (digging out trenches, natural formations)
|
|
||||||
public boolean alignToTerrain = false; // aligns this component y-level individually, without moving individual columns (village houses)
|
/**
|
||||||
public int heightOffset = 0; // individual offset for the structure
|
* Moves every single column to the terrain (for digging out trenches, natural formations, etc)
|
||||||
|
*/
|
||||||
|
public boolean conformToTerrain = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns this component y-level individually, without moving individual columns (like village houses)
|
||||||
|
*/
|
||||||
|
public boolean alignToTerrain = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Height offset for this structure piece, -1 will sink the floor flush into the ground
|
||||||
|
*/
|
||||||
|
public int heightOffset = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will fill any air gap beneath the jigsaw piece using the given selector
|
||||||
|
*/
|
||||||
|
public BlockSelector platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If greater than 0, will limit the number of times this piece can spawn in a structure
|
||||||
|
*/
|
||||||
|
public int instanceLimit = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, will continue generation beyond the defined limits until this piece exists at least once
|
||||||
|
*/
|
||||||
|
public boolean required = false;
|
||||||
|
|
||||||
public JigsawPiece(String name, NBTStructure structure) {
|
public JigsawPiece(String name, NBTStructure structure) {
|
||||||
this(name, structure, 0);
|
this(name, structure, 0);
|
||||||
|
|||||||
@ -23,6 +23,11 @@ public class JigsawPool {
|
|||||||
totalWeight += weight;
|
totalWeight += weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getAverageWeight() {
|
||||||
|
if(pieces.size() == 0) return 1;
|
||||||
|
return totalWeight / pieces.size();
|
||||||
|
}
|
||||||
|
|
||||||
protected JigsawPool clone() {
|
protected JigsawPool clone() {
|
||||||
JigsawPool clone = new JigsawPool();
|
JigsawPool clone = new JigsawPool();
|
||||||
clone.pieces = new ArrayList<>(this.pieces);
|
clone.pieces = new ArrayList<>(this.pieces);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import com.hbm.util.Tuple.Pair;
|
|||||||
import com.hbm.util.Tuple.Quartet;
|
import com.hbm.util.Tuple.Quartet;
|
||||||
import com.hbm.util.fauxpointtwelve.BlockPos;
|
import com.hbm.util.fauxpointtwelve.BlockPos;
|
||||||
import com.hbm.world.gen.nbt.SpawnCondition.WorldCoordinate;
|
import com.hbm.world.gen.nbt.SpawnCondition.WorldCoordinate;
|
||||||
|
import com.hbm.world.gen.nbt.selector.BiomeBlockSelector;
|
||||||
|
|
||||||
import cpw.mods.fml.common.registry.GameRegistry;
|
import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
@ -57,9 +58,11 @@ public class NBTStructure {
|
|||||||
|
|
||||||
private static Map<String, SpawnCondition> namedMap = new HashMap<>();
|
private static Map<String, SpawnCondition> namedMap = new HashMap<>();
|
||||||
|
|
||||||
protected static Map<Integer, List<SpawnCondition>> weightedMap = new HashMap<>();
|
protected static Map<Integer, List<SpawnCondition>> spawnMap = new HashMap<>();
|
||||||
protected static Map<Integer, List<SpawnCondition>> customSpawnMap = new HashMap<>();
|
protected static Map<Integer, List<SpawnCondition>> customSpawnMap = new HashMap<>();
|
||||||
|
|
||||||
|
private static Map<Integer, Map<Integer, WeightedSpawnList>> validBiomeCache = new HashMap<>();
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private boolean isLoaded;
|
private boolean isLoaded;
|
||||||
@ -84,6 +87,15 @@ public class NBTStructure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NBTStructure(String name, InputStream stream) {
|
||||||
|
this.name = name;
|
||||||
|
loadStructure(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name.substring(0, name.length() - 4); // trim .nbt
|
||||||
|
}
|
||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
MapGenStructureIO.registerStructure(Start.class, "NBTStructures");
|
MapGenStructureIO.registerStructure(Start.class, "NBTStructures");
|
||||||
MapGenStructureIO.func_143031_a(Component.class, "NBTComponents");
|
MapGenStructureIO.func_143031_a(Component.class, "NBTComponents");
|
||||||
@ -102,10 +114,8 @@ public class NBTStructure {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SpawnCondition> weightedList = weightedMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
List<SpawnCondition> spawnList = spawnMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
||||||
for(int i = 0; i < spawn.spawnWeight; i++) {
|
spawnList.add(spawn);
|
||||||
weightedList.add(spawn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerStructure(SpawnCondition spawn, int[] dimensionIds) {
|
public static void registerStructure(SpawnCondition spawn, int[] dimensionIds) {
|
||||||
@ -122,10 +132,8 @@ public class NBTStructure {
|
|||||||
public static void registerNullWeight(int dimensionId, int weight, Predicate<BiomeGenBase> predicate) {
|
public static void registerNullWeight(int dimensionId, int weight, Predicate<BiomeGenBase> predicate) {
|
||||||
SpawnCondition spawn = new SpawnCondition(weight, predicate);
|
SpawnCondition spawn = new SpawnCondition(weight, predicate);
|
||||||
|
|
||||||
List<SpawnCondition> weightedList = weightedMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
List<SpawnCondition> spawnList = spawnMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
||||||
for(int i = 0; i < spawn.spawnWeight; i++) {
|
spawnList.add(spawn);
|
||||||
weightedList.add(spawn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Presents a list of all structures registered (so far)
|
// Presents a list of all structures registered (so far)
|
||||||
@ -473,9 +481,7 @@ public class NBTStructure {
|
|||||||
Block block = transformBlock(state.definition, null, world.rand);
|
Block block = transformBlock(state.definition, null, world.rand);
|
||||||
int meta = transformMeta(state.definition, null, coordBaseMode);
|
int meta = transformMeta(state.definition, null, coordBaseMode);
|
||||||
|
|
||||||
if(ry < 0 || ry >= world.getHeight()) continue;
|
if(ry < 1) continue;
|
||||||
Block existing = world.getBlock(rx, ry, rz);
|
|
||||||
if(existing == Blocks.bedrock) continue;
|
|
||||||
|
|
||||||
world.setBlock(rx, ry, rz, block, meta, 2);
|
world.setBlock(rx, ry, rz, block, meta, 2);
|
||||||
|
|
||||||
@ -535,12 +541,30 @@ public class NBTStructure {
|
|||||||
int minZ = Math.min(rotMinZ, rotMaxZ);
|
int minZ = Math.min(rotMinZ, rotMaxZ);
|
||||||
int maxZ = Math.max(rotMinZ, rotMaxZ);
|
int maxZ = Math.max(rotMinZ, rotMaxZ);
|
||||||
|
|
||||||
|
if(piece.blockTable != null || piece.platform != null) {
|
||||||
|
BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(generatingBounds.getCenterX(), generatingBounds.getCenterZ());
|
||||||
|
|
||||||
|
if(piece.blockTable != null) {
|
||||||
|
for(BlockSelector selector : piece.blockTable.values()) {
|
||||||
|
if(selector instanceof BiomeBlockSelector) {
|
||||||
|
((BiomeBlockSelector) selector).nextBiome = biome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(piece.platform instanceof BiomeBlockSelector) {
|
||||||
|
((BiomeBlockSelector) piece.platform).nextBiome = biome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(int bx = minX; bx <= maxX; bx++) {
|
for(int bx = minX; bx <= maxX; bx++) {
|
||||||
for(int bz = minZ; bz <= maxZ; bz++) {
|
for(int bz = minZ; bz <= maxZ; bz++) {
|
||||||
int rx = rotateX(bx, bz, coordBaseMode) + totalBounds.minX;
|
int rx = rotateX(bx, bz, coordBaseMode) + totalBounds.minX;
|
||||||
int rz = rotateZ(bx, bz, coordBaseMode) + totalBounds.minZ;
|
int rz = rotateZ(bx, bz, coordBaseMode) + totalBounds.minZ;
|
||||||
int oy = piece.conformToTerrain ? world.getTopSolidOrLiquidBlock(rx, rz) + piece.heightOffset : totalBounds.minY;
|
int oy = piece.conformToTerrain ? world.getTopSolidOrLiquidBlock(rx, rz) + piece.heightOffset : totalBounds.minY;
|
||||||
|
|
||||||
|
boolean hasBase = false;
|
||||||
|
|
||||||
for(int by = 0; by < size.y; by++) {
|
for(int by = 0; by < size.y; by++) {
|
||||||
BlockState state = blockArray[bx][by][bz];
|
BlockState state = blockArray[bx][by][bz];
|
||||||
if(state == null) continue;
|
if(state == null) continue;
|
||||||
@ -550,9 +574,7 @@ public class NBTStructure {
|
|||||||
Block block = transformBlock(state.definition, piece.blockTable, world.rand);
|
Block block = transformBlock(state.definition, piece.blockTable, world.rand);
|
||||||
int meta = transformMeta(state.definition, piece.blockTable, coordBaseMode);
|
int meta = transformMeta(state.definition, piece.blockTable, coordBaseMode);
|
||||||
|
|
||||||
if(ry < 0 || ry >= world.getHeight()) continue;
|
if(ry < 1) continue;
|
||||||
Block existing = world.getBlock(rx, ry, rz);
|
|
||||||
if(existing == Blocks.bedrock) continue;
|
|
||||||
|
|
||||||
world.setBlock(rx, ry, rz, block, meta, 2);
|
world.setBlock(rx, ry, rz, block, meta, 2);
|
||||||
|
|
||||||
@ -560,6 +582,16 @@ public class NBTStructure {
|
|||||||
TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode, structureName);
|
TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode, structureName);
|
||||||
world.setTileEntity(rx, ry, rz, te);
|
world.setTileEntity(rx, ry, rz, te);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(by == 0 && piece.platform != null && !block.getMaterial().isReplaceable()) hasBase = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasBase && !piece.conformToTerrain) {
|
||||||
|
for(int y = oy - 1; y > 0; y--) {
|
||||||
|
if(!world.getBlock(rx, y, rz).isReplaceable(world, rx, y, rz)) break;
|
||||||
|
piece.platform.selectBlocks(world.rand, 0, 0, 0, false);
|
||||||
|
world.setBlock(rx, y, rz, piece.platform.func_151561_a(), piece.platform.getSelectedBlockMetaData(), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -940,6 +972,8 @@ public class NBTStructure {
|
|||||||
List<Component> queuedComponents = new ArrayList<>();
|
List<Component> queuedComponents = new ArrayList<>();
|
||||||
if(spawn.structure == null) queuedComponents.add(startComponent);
|
if(spawn.structure == null) queuedComponents.add(startComponent);
|
||||||
|
|
||||||
|
Set<JigsawPiece> requiredPieces = findRequiredPieces(spawn);
|
||||||
|
|
||||||
// Iterate through and build out all the components we intend to spawn
|
// Iterate through and build out all the components we intend to spawn
|
||||||
while(!queuedComponents.isEmpty()) {
|
while(!queuedComponents.isEmpty()) {
|
||||||
queuedComponents.sort((a, b) -> b.priority - a.priority); // sort by placement priority descending
|
queuedComponents.sort((a, b) -> b.priority - a.priority); // sort by placement priority descending
|
||||||
@ -956,7 +990,10 @@ public class NBTStructure {
|
|||||||
if(fromComponent.piece.structure.fromConnections == null) continue;
|
if(fromComponent.piece.structure.fromConnections == null) continue;
|
||||||
|
|
||||||
int distance = getDistanceTo(fromComponent.getBoundingBox());
|
int distance = getDistanceTo(fromComponent.getBoundingBox());
|
||||||
boolean fallbacksOnly = this.components.size() >= spawn.sizeLimit || distance >= spawn.rangeLimit;
|
|
||||||
|
// Only generate fallback pieces once we hit our size limit, unless we have a required component
|
||||||
|
// Note that there is a HARD limit of 1024 pieces to prevent infinite generation
|
||||||
|
boolean fallbacksOnly = requiredPieces.size() == 0 && (components.size() >= spawn.sizeLimit || distance >= spawn.rangeLimit) || components.size() > 1024;
|
||||||
|
|
||||||
for(List<JigsawConnection> unshuffledList : fromComponent.piece.structure.fromConnections) {
|
for(List<JigsawConnection> unshuffledList : fromComponent.piece.structure.fromConnections) {
|
||||||
List<JigsawConnection> connectionList = new ArrayList<>(unshuffledList);
|
List<JigsawConnection> connectionList = new ArrayList<>(unshuffledList);
|
||||||
@ -994,6 +1031,8 @@ public class NBTStructure {
|
|||||||
if(nextComponent != null) {
|
if(nextComponent != null) {
|
||||||
addComponent(nextComponent, fromConnection.placementPriority);
|
addComponent(nextComponent, fromConnection.placementPriority);
|
||||||
queuedComponents.add(nextComponent);
|
queuedComponents.add(nextComponent);
|
||||||
|
|
||||||
|
requiredPieces.remove(nextComponent.piece);
|
||||||
} else {
|
} else {
|
||||||
// If we failed to fit anything in, grab something from the fallback pool, ignoring bounds check
|
// If we failed to fit anything in, grab something from the fallback pool, ignoring bounds check
|
||||||
// unless we are perfectly abutting another piece, so grid layouts can work!
|
// unless we are perfectly abutting another piece, so grid layouts can work!
|
||||||
@ -1043,6 +1082,22 @@ public class NBTStructure {
|
|||||||
return new BlockPos(x, y, z);
|
return new BlockPos(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<JigsawPiece> findRequiredPieces(SpawnCondition spawn) {
|
||||||
|
Set<JigsawPiece> requiredPieces = new HashSet<>();
|
||||||
|
|
||||||
|
if(spawn.pools == null) return requiredPieces;
|
||||||
|
|
||||||
|
for(JigsawPool pool : spawn.pools.values()) {
|
||||||
|
for(Pair<JigsawPiece, Integer> weight : pool.pieces) {
|
||||||
|
if(weight.getKey().required) {
|
||||||
|
requiredPieces.add(weight.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requiredPieces;
|
||||||
|
}
|
||||||
|
|
||||||
private Component buildNextComponent(Random rand, SpawnCondition spawn, JigsawPool pool, Component fromComponent, JigsawConnection fromConnection) {
|
private Component buildNextComponent(Random rand, SpawnCondition spawn, JigsawPool pool, Component fromComponent, JigsawConnection fromConnection) {
|
||||||
JigsawPiece nextPiece = pool.get(rand);
|
JigsawPiece nextPiece = pool.get(rand);
|
||||||
if(nextPiece == null) {
|
if(nextPiece == null) {
|
||||||
@ -1050,6 +1105,17 @@ public class NBTStructure {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(nextPiece.instanceLimit > 0) {
|
||||||
|
int instances = 0;
|
||||||
|
for(Object component : components) {
|
||||||
|
if(component instanceof Component && ((Component) component).piece == nextPiece) {
|
||||||
|
instances++;
|
||||||
|
|
||||||
|
if(instances >= nextPiece.instanceLimit) return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<JigsawConnection> connectionPool = nextPiece.structure.getConnectionPool(fromConnection.dir, fromConnection.targetName);
|
List<JigsawConnection> connectionPool = nextPiece.structure.getConnectionPool(fromConnection.dir, fromConnection.targetName);
|
||||||
if(connectionPool == null || connectionPool.isEmpty()) {
|
if(connectionPool == null || connectionPool.isEmpty()) {
|
||||||
MainRegistry.logger.warn("[Jigsaw] No valid connections for: " + fromConnection.targetName + " - in piece: " + nextPiece.name);
|
MainRegistry.logger.warn("[Jigsaw] No valid connections for: " + fromConnection.targetName + " - in piece: " + nextPiece.name);
|
||||||
@ -1153,7 +1219,7 @@ public class NBTStructure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!weightedMap.containsKey(worldObj.provider.dimensionId))
|
if (!spawnMap.containsKey(worldObj.provider.dimensionId))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
int x = chunkX;
|
int x = chunkX;
|
||||||
@ -1189,11 +1255,35 @@ public class NBTStructure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SpawnCondition findSpawn(BiomeGenBase biome) {
|
private SpawnCondition findSpawn(BiomeGenBase biome) {
|
||||||
List<SpawnCondition> spawnList = weightedMap.get(worldObj.provider.dimensionId);
|
Map<Integer, WeightedSpawnList> dimensionCache = validBiomeCache.computeIfAbsent(worldObj.provider.dimensionId, integer -> new HashMap<>());
|
||||||
|
|
||||||
for(int i = 0; i < 64; i++) {
|
WeightedSpawnList filteredList;
|
||||||
SpawnCondition spawn = spawnList.get(rand.nextInt(spawnList.size()));
|
if(!dimensionCache.containsKey(biome.biomeID)) {
|
||||||
if(spawn.isValid(biome)) return spawn;
|
List<SpawnCondition> spawnList = spawnMap.get(worldObj.provider.dimensionId);
|
||||||
|
|
||||||
|
filteredList = new WeightedSpawnList();
|
||||||
|
for(SpawnCondition spawn : spawnList) {
|
||||||
|
if(spawn.isValid(biome)) {
|
||||||
|
filteredList.add(spawn);
|
||||||
|
filteredList.totalWeight += spawn.spawnWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dimensionCache.put(biome.biomeID, filteredList);
|
||||||
|
} else {
|
||||||
|
filteredList = dimensionCache.get(biome.biomeID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filteredList.totalWeight == 0) return null;
|
||||||
|
|
||||||
|
int weight = rand.nextInt(filteredList.totalWeight);
|
||||||
|
|
||||||
|
for(SpawnCondition spawn : filteredList) {
|
||||||
|
weight -= spawn.spawnWeight;
|
||||||
|
|
||||||
|
if(weight < 0) {
|
||||||
|
return spawn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -1201,4 +1291,10 @@ public class NBTStructure {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class WeightedSpawnList extends ArrayList<SpawnCondition> {
|
||||||
|
|
||||||
|
public int totalWeight = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,34 +18,70 @@ public class SpawnCondition {
|
|||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
// If defined, will spawn a single jigsaw piece, for single nbt structures
|
/**
|
||||||
|
* If defined, will spawn a single jigsaw piece, for single nbt structures
|
||||||
|
*/
|
||||||
public JigsawPiece structure;
|
public JigsawPiece structure;
|
||||||
|
|
||||||
// If defined, will spawn in a non-nbt structure component
|
/**
|
||||||
|
* If defined, will spawn in a non-nbt structure component
|
||||||
|
*/
|
||||||
public Function<Quartet<World, Random, Integer, Integer>, StructureStart> start;
|
public Function<Quartet<World, Random, Integer, Integer>, StructureStart> start;
|
||||||
|
|
||||||
// If defined, will override regular spawn location checking, for placing at specific coordinates or with special rules
|
/**
|
||||||
|
* If defined, will override regular spawn location checking, for placing at specific coordinates or with special rules
|
||||||
|
*/
|
||||||
public Predicate<WorldCoordinate> checkCoordinates;
|
public Predicate<WorldCoordinate> checkCoordinates;
|
||||||
|
|
||||||
// Our regular spawning mechanics, based on biome, you should generally use these
|
/**
|
||||||
|
* Defines whether the current biome is valid for spawning this structure
|
||||||
|
*/
|
||||||
public Predicate<BiomeGenBase> canSpawn;
|
public Predicate<BiomeGenBase> canSpawn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The chance of this structure spawning relative to others,
|
||||||
|
* higher weights will spawn more often.
|
||||||
|
*/
|
||||||
public int spawnWeight = 1;
|
public int spawnWeight = 1;
|
||||||
|
|
||||||
// Named jigsaw pools that are referenced within the structure
|
/**
|
||||||
|
* Named jigsaw pools that are referenced by jigsaw blocks within the structure
|
||||||
|
*/
|
||||||
public Map<String, JigsawPool> pools;
|
public Map<String, JigsawPool> pools;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the "core" pool, which the structure starts generation from,
|
||||||
|
* must be a name of a pool defined within `pool`
|
||||||
|
*/
|
||||||
public String startPool;
|
public String startPool;
|
||||||
|
|
||||||
// Maximum amount of components in this structure
|
/**
|
||||||
|
* Maximum amount of components in this structure.
|
||||||
|
* Once the structure reaches this many components,
|
||||||
|
* it will only generate fallback pieces and stop
|
||||||
|
*
|
||||||
|
* Note: there is a hard limit of 1024 pieces to prevent infinite generation,
|
||||||
|
* even if some pieces are marked as required!
|
||||||
|
*/
|
||||||
public int sizeLimit = 8;
|
public int sizeLimit = 8;
|
||||||
|
|
||||||
// How far the structure can extend horizontally from the center, maximum of 128
|
// This could be increased by changing GenStructure:range from 8, but this is
|
||||||
// This could be increased by changing GenStructure:range from 8, but this is already quite reasonably large
|
// already quite reasonably large
|
||||||
|
/**
|
||||||
|
* How far the structure can extend horizontally from the center, maximum of 128
|
||||||
|
*/
|
||||||
public int rangeLimit = 128;
|
public int rangeLimit = 128;
|
||||||
|
|
||||||
// Height modifiers, will clamp height that the start generates at, allowing for:
|
/**
|
||||||
// * Submarines that must spawn under the ocean surface
|
* Height modifiers, will clamp height that the start generates at, allowing for:
|
||||||
// * Bunkers that sit underneath the ground
|
* * Submarines that must spawn under the ocean surface
|
||||||
|
* * Bunkers that sit underneath the ground
|
||||||
|
*/
|
||||||
public int minHeight = 1;
|
public int minHeight = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see minHeight
|
||||||
|
*/
|
||||||
public int maxHeight = 128;
|
public int maxHeight = 128;
|
||||||
|
|
||||||
protected SpawnCondition(int weight, Predicate<BiomeGenBase> predicate) {
|
protected SpawnCondition(int weight, Predicate<BiomeGenBase> predicate) {
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.hbm.world.gen.nbt.selector;
|
||||||
|
|
||||||
|
import net.minecraft.world.biome.BiomeGenBase;
|
||||||
|
import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||||
|
|
||||||
|
public abstract class BiomeBlockSelector extends BlockSelector {
|
||||||
|
|
||||||
|
public BiomeGenBase nextBiome;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package com.hbm.world.gen.nbt.selector;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class BiomeFillerSelector extends BiomeBlockSelector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||||
|
field_151562_a = nextBiome.fillerBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package com.hbm.world.gen.nbt.selector;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class BiomeTopSelector extends BiomeBlockSelector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||||
|
field_151562_a = nextBiome.topBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.hbm.world.gen.nbt.selector;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||||
|
|
||||||
|
public class BrickSelector extends BlockSelector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||||
|
field_151562_a = Blocks.brick_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.hbm.world.gen.nbt.selector;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||||
|
|
||||||
|
public class StoneBrickSelector extends BlockSelector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||||
|
field_151562_a = Blocks.stonebrick;
|
||||||
|
float f = rand.nextFloat();
|
||||||
|
|
||||||
|
if (f < 0.2F) {
|
||||||
|
this.selectedBlockMetaData = 2;
|
||||||
|
} else if (f < 0.5F) {
|
||||||
|
this.selectedBlockMetaData = 1;
|
||||||
|
} else {
|
||||||
|
this.selectedBlockMetaData = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user