]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blobdiff - src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
Cleanup code
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / ClientRenderer.java
index dc56e753fc1b4da7b425f9cd344b2d7d8415619e..a828369d57826b0efab76a66181add6610c9300e 100644 (file)
@@ -2,24 +2,24 @@ package com.irtimaled.bbor.client;
 
 import com.irtimaled.bbor.client.renderers.*;
 import com.irtimaled.bbor.common.BoundingBoxCache;
+import com.irtimaled.bbor.common.BoundingBoxType;
+import com.irtimaled.bbor.common.Dimensions;
+import com.irtimaled.bbor.common.MathHelper;
 import com.irtimaled.bbor.common.models.*;
 import com.irtimaled.bbor.config.ConfigManager;
 import net.minecraft.client.Minecraft;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.world.dimension.DimensionType;
 import org.lwjgl.opengl.GL11;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import static com.irtimaled.bbor.client.Constants.CHUNK_SIZE;
+import java.util.*;
 
 public class ClientRenderer {
-    private final GetCache getCache;
+    private static final int CHUNK_SIZE = 16;
     private static final Map<Class<? extends BoundingBox>, Renderer> boundingBoxRendererMap = new HashMap<>();
 
+    private final GetCache getCache;
+    private long seed;
+    private Set<BoundingBox> spawnChunkBoundingBoxes = new HashSet<>();
+
     ClientRenderer(GetCache getCache) {
         this.getCache = getCache;
         boundingBoxRendererMap.put(BoundingBoxVillage.class, new VillageRenderer());
@@ -29,42 +29,43 @@ public class ClientRenderer {
         boundingBoxRendererMap.put(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
     }
 
-    private boolean isWithinRenderDistance(BlockPos minBlockPos, BlockPos maxBlockPos) {
-        int renderDistanceBlocks = Minecraft.getInstance().gameSettings.renderDistanceChunks * CHUNK_SIZE;
-        int minX = MathHelper.floor(PlayerData.getX() - renderDistanceBlocks);
-        int maxX = MathHelper.floor(PlayerData.getX() + renderDistanceBlocks);
-        int minZ = MathHelper.floor(PlayerData.getZ() - renderDistanceBlocks);
-        int maxZ = MathHelper.floor(PlayerData.getZ() + renderDistanceBlocks);
-
-        return maxBlockPos.getX() >= minX &&
-                maxBlockPos.getZ() >= minZ &&
-                minBlockPos.getX() <= maxX &&
-                minBlockPos.getZ() <= maxZ;
+    private boolean isWithinRenderDistance(BoundingBox boundingBox) {
+        Coords minCoords = boundingBox.getMinCoords();
+        Coords maxCoords = boundingBox.getMaxCoords();
+        int renderDistanceBlocks = getRenderDistanceChunks() * CHUNK_SIZE;
+        int minX = MathHelper.floor(PlayerCoords.getX() - renderDistanceBlocks);
+        int maxX = MathHelper.floor(PlayerCoords.getX() + renderDistanceBlocks);
+        int minZ = MathHelper.floor(PlayerCoords.getZ() - renderDistanceBlocks);
+        int maxZ = MathHelper.floor(PlayerCoords.getZ() + renderDistanceBlocks);
+
+        return maxCoords.getX() >= minX &&
+                maxCoords.getZ() >= minZ &&
+                minCoords.getX() <= maxX &&
+                minCoords.getZ() <= maxZ;
     }
 
-    public void render(DimensionType dimensionType, Boolean outerBoxesOnly) {
-        BoundingBoxCache cache = getCache.apply(dimensionType);
-        if (cache == null) return;
+    public void render(int dimensionId, Boolean outerBoxesOnly) {
+        Map<BoundingBox, Set<BoundingBox>> boundingBoxes = getBoundingBoxes(dimensionId);
 
         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
         GL11.glLineWidth(2.0f);
         GL11.glDisable(GL11.GL_TEXTURE_2D);
         GL11.glDisable(GL11.GL_CULL_FACE);
 
-        if (ConfigManager.alwaysVisible.getBoolean()) {
+        if (ConfigManager.alwaysVisible.get()) {
             GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
         }
-        for (Map.Entry<BoundingBox, Set<BoundingBox>> entry : cache.getBoundingBoxes().entrySet()) {
+        for (Map.Entry<BoundingBox, Set<BoundingBox>> entry : boundingBoxes.entrySet()) {
             BoundingBox key = entry.getKey();
-            if (!key.shouldRender() || !isWithinRenderDistance(key.getMinBlockPos(), key.getMaxBlockPos())) continue;
+            if (!key.shouldRender()) continue;
 
             Renderer renderer = boundingBoxRendererMap.get(key.getClass());
             if (renderer == null) continue;
 
             if (!outerBoxesOnly) {
-                Set<BoundingBox> boundingBoxes = entry.getValue();
-                if (boundingBoxes != null) {
-                    boundingBoxes.forEach(renderer::render);
+                Set<BoundingBox> children = entry.getValue();
+                if (children != null) {
+                    children.forEach(renderer::render);
                     continue;
                 }
             }
@@ -75,4 +76,93 @@ public class ClientRenderer {
         GL11.glEnable(GL11.GL_CULL_FACE);
         GL11.glEnable(GL11.GL_TEXTURE_2D);
     }
+
+    private Map<BoundingBox, Set<BoundingBox>> getBoundingBoxes(int dimensionId) {
+        Map<BoundingBox, Set<BoundingBox>> boundingBoxes = new HashMap<>();
+        if (dimensionId == Dimensions.OVERWORLD) {
+            if (BoundingBoxType.SlimeChunks.shouldRender()) {
+                addSlimeChunks(boundingBoxes);
+            }
+
+            for (BoundingBox boundingBox : spawnChunkBoundingBoxes) {
+                if (boundingBox.shouldRender() && isWithinRenderDistance(boundingBox)) {
+                    boundingBoxes.put(boundingBox, null);
+                }
+            }
+        }
+
+        BoundingBoxCache cache = getCache.apply(dimensionId);
+        if (cache != null) {
+            for (Map.Entry<BoundingBox, Set<BoundingBox>> entry : cache.getBoundingBoxes().entrySet()) {
+                BoundingBox key = entry.getKey();
+                if (key.shouldRender() && isWithinRenderDistance(key)) {
+                    boundingBoxes.put(key, entry.getValue());
+                }
+            }
+        }
+        return boundingBoxes;
+    }
+
+    private void addSlimeChunks(Map<BoundingBox, Set<BoundingBox>> boundingBoxes) {
+        int renderDistanceChunks = getRenderDistanceChunks();
+        int playerChunkX = MathHelper.floor(PlayerCoords.getX() / 16.0D);
+        int playerChunkZ = MathHelper.floor(PlayerCoords.getZ() / 16.0D);
+        for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; ++chunkX) {
+            for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; ++chunkZ) {
+                if (isSlimeChunk(chunkX, chunkZ)) {
+                    int chunkXStart = chunkX << 4;
+                    int chunkZStart = chunkZ << 4;
+                    Coords minCoords = new Coords(chunkXStart, 1, chunkZStart);
+                    Coords maxCoords = new Coords(chunkXStart + 15, 38, chunkZStart + 15);
+                    boundingBoxes.put(BoundingBoxSlimeChunk.from(minCoords, maxCoords), null);
+                }
+            }
+        }
+    }
+
+    private int getRenderDistanceChunks() {
+        return Minecraft.getInstance().gameSettings.renderDistanceChunks;
+    }
+
+    private boolean isSlimeChunk(int chunkX, int chunkZ) {
+        Random r = new Random(seed +
+                (long) (chunkX * chunkX * 4987142) +
+                (long) (chunkX * 5947611) +
+                (long) (chunkZ * chunkZ) * 4392871L +
+                (long) (chunkZ * 389711) ^ 987234911L);
+        return r.nextInt(10) == 0;
+    }
+
+    void setWorldData(long seed, int spawnX, int spawnZ) {
+        this.seed = seed;
+        spawnChunkBoundingBoxes = getSpawnChunkBoundingBoxes(spawnX, spawnZ);
+    }
+
+    private Set<BoundingBox> getSpawnChunkBoundingBoxes(int spawnX, int spawnZ) {
+        Set<BoundingBox> boundingBoxes = new HashSet<>();
+        boundingBoxes.add(getWorldSpawnBoundingBox(spawnX, spawnZ));
+        boundingBoxes.add(buildSpawnChunksBoundingBox(spawnX, spawnZ, 12, BoundingBoxType.SpawnChunks));
+        boundingBoxes.add(buildSpawnChunksBoundingBox(spawnX, spawnZ, 16, BoundingBoxType.LazySpawnChunks));
+        return boundingBoxes;
+    }
+
+    private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
+        Coords minCoords = new Coords(spawnX - 10, 0, spawnZ - 10);
+        Coords maxCoords = new Coords(spawnX + 10, 0, spawnZ + 10);
+
+        return BoundingBoxWorldSpawn.from(minCoords, maxCoords, BoundingBoxType.WorldSpawn);
+    }
+
+    private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ, int size, BoundingBoxType type) {
+        double midOffset = CHUNK_SIZE * (size / 2.0);
+        double midX = Math.round((float) (spawnX / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
+        double midZ = Math.round((float) (spawnZ / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
+        Coords minCoords = new Coords(midX - midOffset, 0, midZ - midOffset);
+        if (spawnX / (double) CHUNK_SIZE % 0.5D == 0.0D && spawnZ / (double) CHUNK_SIZE % 0.5D == 0.0D) {
+            midX += (double) CHUNK_SIZE;
+            midZ += (double) CHUNK_SIZE;
+        }
+        Coords maxCoords = new Coords(midX + midOffset, 0, midZ + midOffset);
+        return BoundingBoxWorldSpawn.from(minCoords, maxCoords, type);
+    }
 }