]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/providers/BedrockCeilingProvider.java
Bedrock ceiling
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / providers / BedrockCeilingProvider.java
1 package com.irtimaled.bbor.client.providers;
2
3 import com.irtimaled.bbor.client.Player;
4 import com.irtimaled.bbor.client.config.BoundingBoxTypeHelper;
5 import com.irtimaled.bbor.client.interop.BedrockCeilingHelper;
6 import com.irtimaled.bbor.client.interop.ClientInterop;
7 import com.irtimaled.bbor.client.models.BoundingBoxBedrockCeiling;
8 import com.irtimaled.bbor.common.BoundingBoxType;
9 import com.irtimaled.bbor.common.MathHelper;
10 import com.irtimaled.bbor.common.models.Coords;
11 import com.irtimaled.bbor.common.models.DimensionId;
12 import it.unimi.dsi.fastutil.objects.ObjectArrayList;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 public class BedrockCeilingProvider implements IBoundingBoxProvider<BoundingBoxBedrockCeiling>, ICachingProvider {
21     private static final double CHUNK_SIZE = 16d;
22     private static Long lastGameTime = null;
23     private static final Map<String, BedrockChunk> chunks = new HashMap<>();
24
25     private static class BedrockChunk {
26         private final List<BoundingBoxBedrockCeiling> boxes = new ObjectArrayList<>();
27
28         public BedrockChunk(int chunkX, int chunkZ) {
29             int chunkStartX = chunkX << 4;
30             int chunkStartZ = chunkZ << 4;
31
32             if (BedrockCeilingHelper.chunkLoaded(chunkX, chunkZ)) findBoxesFromBlockState(chunkStartX, chunkStartZ);
33 //            else findBoxesFromRNG(chunkX, chunkZ, chunkStartX, chunkStartZ);
34         }
35
36         private void findBoxesFromBlockState(int chunkStartX, int chunkStartZ) {
37             for (int x = 0; x < 16; x++) {
38                 for (int z = 0; z < 16; z++) {
39                     Coords coords = getCoordsFromBlockState(chunkStartX + x, chunkStartZ + z);
40                     if (coords != null) {
41                         boxes.add(new BoundingBoxBedrockCeiling(coords));
42                     }
43                 }
44             }
45         }
46
47         private Coords getCoordsFromBlockState(int x, int z) {
48             Coords coords = null;
49             for (int y = 127; y >= 123; y--) {
50                 if (BedrockCeilingHelper.isBedrock(x, y, z)) {
51                     if (coords == null) {
52                         coords = new Coords(x, y, z);
53                     } else {
54                         return null;
55                     }
56                 }
57             }
58             return coords;
59         }
60
61 //        private void findBoxesFromRNG(int chunkX, int chunkZ, int chunkStartX, int chunkStartZ) {
62 //            Random random = BedrockCeilingHelper.getRandomForChunk(chunkX, chunkZ);
63 //
64 //            // preseed 16x16x3 calls to nextDouble
65 //            for (int dummy = 0; dummy < 768; dummy++) {
66 //                random.nextDouble();
67 //            }
68 //            for (int z = 0; z < 16; z++) {
69 //                for (int x = 0; x < 16; x++) {
70 //                    Coords coords = getBlocksFromRNG(random, chunkStartX + x, chunkStartZ + z);
71 //
72 //                    if (coords != null) {
73 //                        boxes.add(new BoundingBoxBedrockCeiling(coords));
74 //                    }
75 //                }
76 //            }
77 //        }
78 //
79 //        private Coords getBlocksFromRNG(Random random, int x, int z) {
80 //            int count = 0;
81 //            for (int y = 127; y >= 123; y--) {
82 //                if (y >= 127 - random.nextInt(5)) {
83 //                    count++;
84 //                }
85 //            }
86 //            for (int y = 4; y >= 0; y--) {
87 //                random.nextInt(5);
88 //            }
89 //            return count == 1 ? new Coords(x, 127, z) : null;
90 //        }
91
92         public Collection<? extends BoundingBoxBedrockCeiling> getBlocks() {
93             return boxes;
94         }
95
96         public void clear() {
97             boxes.clear();
98         }
99     }
100
101     public void clearCache() {
102         chunks.values().forEach(BedrockChunk::clear);
103         chunks.clear();
104     }
105
106     @Override
107     public Iterable<BoundingBoxBedrockCeiling> get(DimensionId dimensionId) {
108         boolean shouldRecalculate = shouldRecalculate();
109
110         int renderDistanceChunks = ClientInterop.getRenderDistanceChunks() / 2;
111         int playerChunkX = MathHelper.floor(Player.getX() / CHUNK_SIZE);
112         int playerChunkZ = MathHelper.floor(Player.getZ() / CHUNK_SIZE);
113
114         ArrayList<BoundingBoxBedrockCeiling> boxes = new ArrayList<>();
115
116         for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; chunkX++) {
117             for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; chunkZ++) {
118                 String key = String.format("%d,%d", chunkX, chunkZ);
119                 if (shouldRecalculate || !chunks.containsKey(key)) {
120                     chunks.put(key, new BedrockChunk(chunkX, chunkZ));
121                 }
122                 BedrockChunk chunk = chunks.get(key);
123                 boxes.addAll(chunk.getBlocks());
124             }
125         }
126         return boxes;
127     }
128
129     public boolean shouldRecalculate() {
130         long gameTime = ClientInterop.getGameTime();
131         if (!((Long) gameTime).equals(lastGameTime) && (gameTime & 0b1111) == 0) {
132             lastGameTime = gameTime;
133             return true;
134         }
135         return false;
136     }
137
138     @Override
139     public boolean canProvide(DimensionId dimensionId) {
140         return dimensionId == DimensionId.NETHER && BoundingBoxTypeHelper.shouldRender(BoundingBoxType.BedrockCeiling) && Player.getY() > 110;
141     }
142 }