package rtg.world.gen.structure; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import net.minecraft.init.Biomes; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.structure.MapGenVillage; import net.minecraft.world.gen.structure.StructureComponent; import net.minecraft.world.gen.structure.StructureStart; import net.minecraft.world.gen.structure.StructureVillagePieces; import rtg.api.RTGAPI; import rtg.util.Logger; import rtg.world.WorldTypeRTG; import rtg.world.biome.BiomeProviderRTG; import rtg.world.biome.realistic.RealisticBiomeBase; public class MapGenVillageRTG extends MapGenVillage { public static List<Biome> VILLAGE_SPAWN_BIOMES = Arrays.<Biome>asList(new Biome[] {Biomes.PLAINS, Biomes.DESERT, Biomes.SAVANNA, Biomes.TAIGA}); private int size; private int distance; private final int minTownSeparation; public MapGenVillageRTG() { this.size = RTGAPI.config().VILLAGE_SIZE.get(); // Vanilla = 0 this.distance = RTGAPI.config().MAX_DISTANCE_VILLAGES.get(); // Vanille = 32 this.minTownSeparation = RTGAPI.config().MIN_DISTANCE_VILLAGES.get(); // Vanilla = 8 } public MapGenVillageRTG(Map<String, String> map) { this(); for (Entry<String, String> entry : map.entrySet()) { if (((String)entry.getKey()).equals("size")) { this.size = MathHelper.getInt((String)entry.getValue(), this.size, 0); } else if (((String)entry.getKey()).equals("distance")) { this.distance = MathHelper.getInt((String)entry.getValue(), this.distance, 9); } } } @Override public String getStructureName() { return "Village"; } @Override protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { boolean canSpawnVillage = false; int i = chunkX; int j = chunkZ; if (chunkX < 0) { chunkX -= this.distance - 1; } if (chunkZ < 0) { chunkZ -= this.distance - 1; } int k = chunkX / this.distance; int l = chunkZ / this.distance; Random random = this.world.setRandomSeed(k, l, 10387312); k = k * this.distance; l = l * this.distance; k = k + random.nextInt(this.distance - 8); l = l + random.nextInt(this.distance - 8); if (i == k && j == l) { boolean booRTGWorld = world.getWorldType() instanceof WorldTypeRTG; boolean booRTGChunkManager = world.getBiomeProvider() instanceof BiomeProviderRTG; int worldX = i * 16 + 8; int worldZ = j * 16 + 8; if (booRTGWorld && booRTGChunkManager) { BiomeProviderRTG cmr = (BiomeProviderRTG) world.getBiomeProvider(); //Why are we flipping XZ here? No idea, but it works. - Pink RealisticBiomeBase realisticBiome = cmr.getBiomeDataAt(worldX, worldZ); if (realisticBiome.getConfig().ALLOW_VILLAGES.get()) { canSpawnVillage = true; Logger.debug("Potential village in %s at %d %d", realisticBiome.baseBiome.getBiomeName(), worldX, worldZ); } } else canSpawnVillage = this.world.getBiomeProvider().areBiomesViable(worldX, worldZ, 0, VILLAGE_SPAWN_BIOMES); } return canSpawnVillage; } @Override public BlockPos getClosestStrongholdPos(World worldIn, BlockPos pos, boolean findUnexplored) { this.world = worldIn; return findNearestStructurePosBySpacing(worldIn, this, pos, this.distance, 8, 10387312, false, 100, findUnexplored); } @Override protected StructureStart getStructureStart(int chunkX, int chunkZ) { return new MapGenVillage.Start(this.world, this.rand, chunkX, chunkZ, this.size); } public static class Start extends StructureStart { private boolean hasMoreThanTwoComponents; public Start() {} public Start(World worldIn, Random rand, int x, int z, int size) { super(x, z); List<StructureVillagePieces.PieceWeight> list = StructureVillagePieces.getStructureVillageWeightedPieceList(rand, size); StructureVillagePieces.Start structurevillagepieces$start = new StructureVillagePieces.Start(worldIn.getBiomeProvider(), 0, rand, (x << 4) + 2, (z << 4) + 2, list, size); this.components.add(structurevillagepieces$start); structurevillagepieces$start.buildComponent(structurevillagepieces$start, this.components, rand); List<StructureComponent> list1 = structurevillagepieces$start.pendingRoads; List<StructureComponent> list2 = structurevillagepieces$start.pendingHouses; while (!list1.isEmpty() || !list2.isEmpty()) { if (list1.isEmpty()) { int i = rand.nextInt(list2.size()); StructureComponent structurecomponent = (StructureComponent)list2.remove(i); structurecomponent.buildComponent(structurevillagepieces$start, this.components, rand); } else { int j = rand.nextInt(list1.size()); StructureComponent structurecomponent2 = (StructureComponent)list1.remove(j); structurecomponent2.buildComponent(structurevillagepieces$start, this.components, rand); } } this.updateBoundingBox(); int k = 0; for (StructureComponent structurecomponent1 : this.components) { if (!(structurecomponent1 instanceof StructureVillagePieces.Road)) { ++k; } } this.hasMoreThanTwoComponents = k > 2; } @Override public boolean isSizeableStructure() { return this.hasMoreThanTwoComponents; } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setBoolean("Valid", this.hasMoreThanTwoComponents); } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.hasMoreThanTwoComponents = tagCompound.getBoolean("Valid"); } } }