1 package com.irtimaled.bbor;
3 import net.minecraft.util.BlockPos;
4 import net.minecraft.village.Village;
5 import net.minecraft.world.ChunkCoordIntPair;
6 import net.minecraft.world.World;
7 import net.minecraft.world.chunk.IChunkProvider;
8 import net.minecraft.world.gen.ChunkProviderGenerate;
9 import net.minecraft.world.gen.ChunkProviderHell;
10 import net.minecraft.world.gen.structure.ComponentScatteredFeaturePieces;
11 import net.minecraft.world.gen.structure.MapGenStructure;
12 import net.minecraft.world.gen.structure.StructureComponent;
13 import net.minecraft.world.gen.structure.StructureStart;
14 import net.minecraftforge.fml.common.FMLLog;
15 import net.minecraftforge.fml.relauncher.ReflectionHelper;
19 import java.util.List;
21 public class DimensionProcessor extends BoundingBoxCache {
23 private ConfigManager configManager;
26 public DimensionProcessor(ConfigManager configManager, World world, int dimensionId, IChunkProvider chunkProvider) {
27 this.configManager = configManager;
29 this.dimensionId = dimensionId;
30 this.chunkProvider = chunkProvider;
31 villageCache = new HashSet<BoundingBox>();
32 slimeChunkCache = new HashSet<BoundingBox>();
33 worldSpawnCache = new HashSet<BoundingBox>();
36 private int dimensionId;
37 private IChunkProvider chunkProvider;
38 private Set<BoundingBox> villageCache;
39 private Set<BoundingBox> slimeChunkCache;
40 private Set<BoundingBox> worldSpawnCache;
42 private boolean closed = false;
49 slimeChunkCache.clear();
50 worldSpawnCache.clear();
54 private static <T extends IChunkProvider> Collection<StructureStart> getStructures(T chunkProvider, int method) {
55 Class<T> cpClass = (Class<T>) chunkProvider.getClass();
56 Object structureGenerator = ReflectionHelper.getPrivateValue(cpClass, chunkProvider, method);
57 if (structureGenerator instanceof MapGenStructure) {
58 Map<ChunkCoordIntPair, StructureStart> structureMap = ReflectionHelper.getPrivateValue(MapGenStructure.class, (MapGenStructure) structureGenerator, 1);
59 return structureMap.values();
61 return Collections.emptyList();
64 private Map<StructureType, Collection<StructureStart>> getStructures() {
66 Map<StructureType, Collection<StructureStart>> structureMap = new HashMap<StructureType, Collection<StructureStart>>();
67 if (chunkProvider instanceof ChunkProviderGenerate) {
68 if (configManager.drawDesertTemples.getBoolean()) {
69 structureMap.put(StructureType.DesertTemple, getStructuresWithComponent(getStructures(chunkProvider, 20), ComponentScatteredFeaturePieces.DesertPyramid.class));
72 if (configManager.drawJungleTemples.getBoolean()) {
73 structureMap.put(StructureType.JungleTemple, getStructuresWithComponent(getStructures(chunkProvider, 20), ComponentScatteredFeaturePieces.JunglePyramid.class));
76 if (configManager.drawWitchHuts.getBoolean()) {
77 structureMap.put(StructureType.WitchHut, getStructuresWithComponent(getStructures(chunkProvider, 20), ComponentScatteredFeaturePieces.SwampHut.class));
80 if (configManager.drawOceanMonuments.getBoolean()) {
81 structureMap.put(StructureType.OceanMonument, getStructures(chunkProvider, 22));
84 if (configManager.drawStrongholds.getBoolean()) {
85 structureMap.put(StructureType.Stronghold, getStructures(chunkProvider, 17));
88 if (configManager.drawMineShafts.getBoolean()) {
89 structureMap.put(StructureType.MineShaft, getStructures(chunkProvider, 19));
91 } else if (chunkProvider instanceof ChunkProviderHell) {
93 if (configManager.drawNetherFortresses.getBoolean()) {
94 structureMap.put(StructureType.NetherFortress, getStructures(chunkProvider, 22));
101 private Collection<StructureStart> getStructuresWithComponent(Collection<StructureStart> structures, Class structureComponent) {
102 Collection<StructureStart> validStructures = new HashSet<StructureStart>();
103 for (StructureStart structure : structures) {
104 if (structure.getComponents().getFirst().getClass().equals(structureComponent)) {
105 validStructures.add(structure);
108 return validStructures;
112 public synchronized void refresh() {
115 Map<StructureType, Collection<StructureStart>> structureMap = getStructures();
116 for (StructureType structureType : structureMap.keySet()) {
117 Color color = structureType.getColor();
118 for (StructureStart structureStart : structureMap.get(structureType)) {
119 BoundingBox boundingBox = BoundingBoxStructure.from(structureStart.getBoundingBox(), color);
120 if (!cache.containsKey(boundingBox)) {
121 Set<BoundingBox> structureBoundingBoxes = new HashSet<BoundingBox>();
122 Iterator structureComponents = structureStart.getComponents().iterator();
123 while (structureComponents.hasNext()) {
124 StructureComponent structureComponent = (StructureComponent) structureComponents.next();
125 structureBoundingBoxes.add(BoundingBoxStructure.from(structureComponent.getBoundingBox(), color));
127 cache.put(boundingBox, structureBoundingBoxes);
128 FMLLog.info("[%d] new boundingBoxCacheMap entries: %d", dimensionId, structureBoundingBoxes.size());
133 if (configManager.drawVillages.getBoolean() &&
134 (world.villageCollectionObj != null)) {
136 Set<BoundingBox> villageBoundingBoxes = new HashSet<BoundingBox>();
137 List<Village> villages = world.villageCollectionObj.getVillageList();
139 for (Village village : villages) {
140 BlockPos center = ReflectionHelper.getPrivateValue(Village.class, village, 3);
141 Integer radius = ReflectionHelper.getPrivateValue(Village.class, village, 4);
142 villageBoundingBoxes.add(BoundingBoxVillage.from(center, radius, village.getNumVillagers(), village.getNumVillageDoors()));
144 processDelta(villageCache, villageBoundingBoxes);
146 villageCache = villageBoundingBoxes;
150 private void processDelta(Set<BoundingBox> oldBoundingBoxes, Set<BoundingBox> newBoundingBoxes) {
151 for (BoundingBox bb : oldBoundingBoxes) {
152 if (!newBoundingBoxes.contains(bb)) {
154 BoundingBoxOutlineReloaded.proxy.boundingBoxRemoved(bb);
156 if (!cache.containsKey(bb)) {
157 Set<BoundingBox> boundingBoxes = new HashSet<BoundingBox>();
158 boundingBoxes.add(bb);
159 cache.put(bb, boundingBoxes);