1 package com.irtimaled.bbor.common.chunkProcessors;
3 import com.irtimaled.bbor.common.BoundingBoxCache;
4 import com.irtimaled.bbor.common.BoundingBoxType;
5 import com.irtimaled.bbor.common.TypeHelper;
6 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
7 import com.irtimaled.bbor.common.models.BoundingBoxMobSpawner;
8 import com.irtimaled.bbor.common.models.BoundingBoxStructure;
9 import com.irtimaled.bbor.common.models.Coords;
10 import net.minecraft.tileentity.TileEntity;
11 import net.minecraft.tileentity.TileEntityMobSpawner;
12 import net.minecraft.util.math.ChunkPos;
13 import net.minecraft.world.chunk.Chunk;
14 import net.minecraft.world.chunk.IChunkProvider;
15 import net.minecraft.world.gen.ChunkProviderServer;
16 import net.minecraft.world.gen.IChunkGenerator;
17 import net.minecraft.world.gen.structure.MapGenStructure;
18 import net.minecraft.world.gen.structure.StructureBoundingBox;
19 import net.minecraft.world.gen.structure.StructureComponent;
20 import net.minecraft.world.gen.structure.StructureStart;
23 import java.util.function.Function;
25 public abstract class AbstractChunkProcessor {
26 Map<BoundingBoxType, Function<IChunkGenerator, Collection<StructureStart>>> supportedStructures = new HashMap<>();
28 AbstractChunkProcessor(BoundingBoxCache boundingBoxCache) {
29 this.boundingBoxCache = boundingBoxCache;
32 private final BoundingBoxCache boundingBoxCache;
34 static <T extends IChunkGenerator, R extends MapGenStructure> Collection<StructureStart> getStructures(T chunkGenerator, Class<R> generatorClass) {
35 Class<T> chunkGeneratorClass = (Class<T>) chunkGenerator.getClass();
36 R structureGenerator = ReflectionHelper.getPrivateValue(chunkGeneratorClass, chunkGenerator, generatorClass);
37 if (structureGenerator != null) {
38 Map<ChunkPos, StructureStart> structureMap = ReflectionHelper.getPrivateValue(MapGenStructure.class, structureGenerator, Map.class);
39 return structureMap.values();
41 return Collections.emptyList();
44 Collection<StructureStart> getStructuresWithComponent(Collection<StructureStart> structures, Class structureComponent) {
45 Collection<StructureStart> validStructures = new HashSet<>();
46 for (StructureStart structure : structures) {
47 if (structure.getComponents().get(0).getClass().equals(structureComponent)) {
48 validStructures.add(structure);
51 return validStructures;
55 private void addStructures(BoundingBoxType type, StructureStart structureStart) {
56 StructureBoundingBox bb = structureStart.getBoundingBox();
57 if (bb == null) return;
59 AbstractBoundingBox boundingBox = buildStructure(bb, type);
60 if (boundingBoxCache.isCached(boundingBox)) return;
62 Set<AbstractBoundingBox> structureBoundingBoxes = new HashSet<>();
63 for (StructureComponent structureComponent : structureStart.getComponents()) {
64 structureBoundingBoxes.add(buildStructure(structureComponent.getBoundingBox(), type));
66 boundingBoxCache.addBoundingBoxes(boundingBox, structureBoundingBoxes);
69 private AbstractBoundingBox buildStructure(StructureBoundingBox bb, BoundingBoxType type) {
70 Coords min = new Coords(bb.minX, bb.minY, bb.minZ);
71 Coords max = new Coords(bb.maxX, bb.maxY, bb.maxZ);
72 return BoundingBoxStructure.from(min, max, type);
75 private void addMobSpawners(Chunk chunk) {
76 Collection<TileEntity> tileEntities = chunk.getWorld().loadedTileEntityList;
77 for (TileEntity tileEntity : tileEntities) {
78 TileEntityMobSpawner spawner = TypeHelper.as(tileEntity, TileEntityMobSpawner.class);
79 if (spawner != null) {
80 Coords coords = new Coords(spawner.getPos());
81 boundingBoxCache.addBoundingBox(BoundingBoxMobSpawner.from(coords));
86 public void process(Chunk chunk) {
87 IChunkProvider chunkProvider = chunk.getWorld().getChunkProvider();
88 IChunkGenerator chunkGenerator = ReflectionHelper.getPrivateValue(ChunkProviderServer.class, (ChunkProviderServer) chunkProvider, IChunkGenerator.class);
89 supportedStructures.forEach((type, supplier) ->
91 Collection<StructureStart> structureStarts = supplier.apply(chunkGenerator);
92 structureStarts.forEach(structureStart -> addStructures(type, structureStart));
95 addMobSpawners(chunk);