]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
Add BiomeBorder support
authorIrtimaled <irtimaled@gmail.com>
Fri, 4 Oct 2019 05:34:21 +0000 (22:34 -0700)
committerIrtimaled <irtimaled@gmail.com>
Tue, 19 Nov 2019 04:26:15 +0000 (20:26 -0800)
12 files changed:
src/main/java/com/irtimaled/bbor/client/ClientProxy.java
src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
src/main/java/com/irtimaled/bbor/client/gui/SettingsScreen.java
src/main/java/com/irtimaled/bbor/client/interop/BiomeBorderHelper.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/providers/BiomeBorderProvider.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/BiomeBorderRenderer.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/renderers/VillageRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/WorldSpawnRenderer.java
src/main/java/com/irtimaled/bbor/common/BoundingBoxType.java
src/main/java/com/irtimaled/bbor/common/models/BoundingBoxBiomeBorder.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/config/ConfigManager.java

index 9fb1d6462f627c1b3d76e9c39533f22e2a867875..cf9afd050e6f7df9d6c0a455f3c75b9b7fe27cf2 100644 (file)
@@ -39,6 +39,7 @@ public class ClientProxy extends CommonProxy {
                 .registerProvider(new SpawningSphereProvider())
                 .registerProvider(new BeaconProvider())
                 .registerProvider(new CustomBoxProvider())
+                .registerProvider(new BiomeBorderProvider())
                 .registerProvider(new CacheProvider(this::getCache));
 
         KeyListener.init();
@@ -56,6 +57,7 @@ public class ClientProxy extends CommonProxy {
         SpawningSphereProvider.clear();
         BeaconProvider.clear();
         CustomBoxProvider.clear();
+        BiomeBorderProvider.clear();
         VillageColorCache.clear();
         clearCaches();
     }
index 6bd465276ed5238c2683edea78af2e03584767c2..34a8aa4d47a3004f3a1ffac4cbb73c73e9069c1d 100644 (file)
@@ -47,6 +47,7 @@ public class ClientRenderer {
         registerRenderer(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
         registerRenderer(BoundingBoxSpawningSphere.class, new SpawningSphereRenderer());
         registerRenderer(BoundingBoxBeacon.class, new CuboidRenderer());
+        registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
     }
 
     public <T extends AbstractBoundingBox> ClientRenderer registerProvider(IBoundingBoxProvider<T> provider) {
index a3f963d17eee59d14b890248ebe7b013a59ddf85..2626b0163e9abf67a4468f897a2bf4817c2be9eb 100644 (file)
@@ -145,6 +145,13 @@ public class SettingsScreen extends GuiScreen {
                 (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, "Spawn Sphere", BoundingBoxType.AFKSphere),
                 (id, x, y, width) -> new BoolSettingButton(id, x, y, width, "Spawnable Blocks", ConfigManager.renderAFKSpawnableBlocks),
                 (id, x, y, width) -> new IntSettingSlider(id, x, y, width, 1, 3, "Distance", ConfigManager.afkSpawnableBlocksRenderDistance)
+                        .addDisplayValue(1, "Nearest")
+                        .addDisplayValue(2, "Nearer")
+                        .addDisplayValue(3, "Normal"),
+
+                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, "Biome Borders", BoundingBoxType.BiomeBorder),
+                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, "Only This Biome", ConfigManager.renderOnlyCurrentBiome),
+                (id, x, y, width) -> new IntSettingSlider(id, x, y, width, 1, 3, "Distance", ConfigManager.biomeBordersRenderDistance)
                         .addDisplayValue(1, "Nearest")
                         .addDisplayValue(2, "Nearer")
                         .addDisplayValue(3, "Normal"));
diff --git a/src/main/java/com/irtimaled/bbor/client/interop/BiomeBorderHelper.java b/src/main/java/com/irtimaled/bbor/client/interop/BiomeBorderHelper.java
new file mode 100644 (file)
index 0000000..fbc2442
--- /dev/null
@@ -0,0 +1,18 @@
+package com.irtimaled.bbor.client.interop;
+
+import com.irtimaled.bbor.common.models.Coords;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.biome.Biome;
+
+public class BiomeBorderHelper {
+    public static int getBiomeId(Coords coords) {
+        return getBiomeId(coords.getX(), coords.getY(), coords.getZ());
+    }
+
+    public static int getBiomeId(int x, int y, int z) {
+        BlockPos pos = new BlockPos(x, y, z);
+        Biome biome = Minecraft.getInstance().world.getBiome(pos);
+        return Biome.getIdForBiome(biome);
+    }
+}
diff --git a/src/main/java/com/irtimaled/bbor/client/providers/BiomeBorderProvider.java b/src/main/java/com/irtimaled/bbor/client/providers/BiomeBorderProvider.java
new file mode 100644 (file)
index 0000000..1fb724f
--- /dev/null
@@ -0,0 +1,93 @@
+package com.irtimaled.bbor.client.providers;
+
+import com.irtimaled.bbor.client.PlayerCoords;
+import com.irtimaled.bbor.client.interop.BiomeBorderHelper;
+import com.irtimaled.bbor.common.BoundingBoxType;
+import com.irtimaled.bbor.common.MathHelper;
+import com.irtimaled.bbor.common.models.BoundingBoxBiomeBorder;
+import com.irtimaled.bbor.common.models.Coords;
+import com.irtimaled.bbor.config.ConfigManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class BiomeBorderProvider implements IBoundingBoxProvider<BoundingBoxBiomeBorder> {
+    private static Coords lastPlayerCoords = null;
+    private static Boolean lastRenderAllTransitions = null;
+    private static Integer lastRenderDistance = null;
+    private static Map<Coords, BoundingBoxBiomeBorder> lastBorders = new HashMap<>();
+
+    public Iterable<BoundingBoxBiomeBorder> get(int dimensionId) {
+        if (!BoundingBoxType.BiomeBorder.shouldRender())
+            return Iterators.empty();
+
+        Coords playerCoords = PlayerCoords.get();
+        Integer renderDistance = ConfigManager.biomeBordersRenderDistance.get();
+        Boolean renderAllTransitions = !ConfigManager.renderOnlyCurrentBiome.get();
+        if (!playerCoords.equals(lastPlayerCoords) || !renderDistance.equals(lastRenderDistance) || renderAllTransitions != lastRenderAllTransitions) {
+            lastPlayerCoords = playerCoords;
+            lastRenderDistance = renderDistance;
+            lastRenderAllTransitions = renderAllTransitions;
+            lastBorders = getBiomeBorders();
+        }
+        return lastBorders.values();
+    }
+
+    public static void clear() {
+        lastBorders = new HashMap<>();
+        lastPlayerCoords = null;
+    }
+
+    private Map<Coords, BoundingBoxBiomeBorder> getBiomeBorders() {
+        Integer renderDistance = lastRenderDistance;
+        Coords playerCoords = lastPlayerCoords;
+        boolean renderAllTransitions = lastRenderAllTransitions;
+
+        int width = MathHelper.floor(Math.pow(2, 3 + renderDistance));
+        int blockX = playerCoords.getX();
+        int minX = blockX - width;
+        int maxX = blockX + width;
+
+        int blockY = playerCoords.getY();
+
+        int blockZ = playerCoords.getZ();
+        int minZ = blockZ - width;
+        int maxZ = blockZ + width;
+
+        int size = (width * 2) + 1;
+        int[][] biomeIds = new int[size][size];
+        for (int x = minX; x <= maxX; x++) {
+            int matchX = (x - minX);
+            for (int z = minZ; z <= maxZ; z++) {
+                int matchZ = (z - minZ);
+                biomeIds[matchX][matchZ] = BiomeBorderHelper.getBiomeId(x, blockY, z);
+            }
+        }
+
+        int playerBiomeId = BiomeBorderHelper.getBiomeId(playerCoords);
+
+        Map<Coords, BoundingBoxBiomeBorder> borders = new HashMap<>();
+        for (int matchX = 1; matchX < size - 2; matchX++) {
+            for (int matchZ = 1; matchZ < size - 2; matchZ++) {
+                int x = matchX + minX;
+                int z = matchZ + minZ;
+                int biomeId = biomeIds[matchX][matchZ];
+                if (renderAllTransitions || biomeId == playerBiomeId) {
+                    Coords coords = new Coords(x, blockY, z);
+                    if (lastBorders.containsKey(coords)) {
+                        borders.put(coords, lastBorders.get(coords));
+                    } else {
+                        boolean north = biomeIds[matchX][matchZ - 1] != biomeId;
+                        boolean east = biomeIds[matchX + 1][matchZ] != biomeId;
+                        boolean south = biomeIds[matchX][matchZ + 1] != biomeId;
+                        boolean west = biomeIds[matchX - 1][matchZ] != biomeId;
+                        if (north || east || south || west) {
+                            borders.put(coords, BoundingBoxBiomeBorder.from(coords, north, east, south, west));
+                        }
+                    }
+                }
+            }
+        }
+        return borders;
+    }
+}
index e9c254f8e9636ab368fa2a074a81852d95b76748..349382b6cd12d81ab417eb84d66b48bd6db78df8 100644 (file)
@@ -18,30 +18,19 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
     public abstract void render(T boundingBox);
 
     void renderCuboid(OffsetBox bb, Color color) {
+        OffsetBox nudge = bb.nudge();
         if (ConfigManager.fill.get()) {
-            renderFilledCuboid(bb, color);
+            renderFilledFaces(nudge.getMin(), nudge.getMax(), color, 30);
         }
-        renderUnfilledCuboid(bb, color);
+        renderOutlinedCuboid(nudge, color);
     }
 
-    private void renderFilledCuboid(OffsetBox bb, Color color) {
-        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
-        GL11.glEnable(GL11.GL_BLEND);
-        renderCuboid(bb.nudge(), color, 30);
-        GL11.glDisable(GL11.GL_BLEND);
-        GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
-        GL11.glPolygonOffset(-1.f, -1.f);
-    }
-
-    void renderUnfilledCuboid(OffsetBox bb, Color color) {
+    void renderOutlinedCuboid(OffsetBox bb, Color color) {
         GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
-        renderCuboid(bb.nudge(), color, 255);
+        renderFaces(bb.getMin(), bb.getMax(), color, 255);
     }
 
-    private void renderCuboid(OffsetBox box, Color color, int alpha) {
-        OffsetPoint min = box.getMin();
-        OffsetPoint max = box.getMax();
-
+    private void renderFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) {
         double minX = min.getX();
         double minY = min.getY();
         double minZ = min.getZ();
@@ -52,37 +41,47 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
 
         Renderer renderer = Renderer.startQuads()
                 .setColor(color)
-                .setAlpha(alpha)
-                .addPoint(minX, minY, minZ)
-                .addPoint(maxX, minY, minZ)
-                .addPoint(maxX, minY, maxZ)
-                .addPoint(minX, minY, maxZ);
-
-        if (minY != maxY) {
-            renderer.addPoint(minX, maxY, minZ)
-                    .addPoint(maxX, maxY, minZ)
-                    .addPoint(maxX, maxY, maxZ)
-                    .addPoint(minX, maxY, maxZ)
+                .setAlpha(alpha);
 
-                    .addPoint(minX, minY, maxZ)
-                    .addPoint(minX, maxY, maxZ)
-                    .addPoint(maxX, maxY, maxZ)
+        if(minX != maxX && minZ != maxZ) {
+            renderer.addPoint(minX, minY, minZ)
+                    .addPoint(maxX, minY, minZ)
                     .addPoint(maxX, minY, maxZ)
+                    .addPoint(minX, minY, maxZ);
 
-                    .addPoint(minX, minY, minZ)
-                    .addPoint(minX, maxY, minZ)
-                    .addPoint(maxX, maxY, minZ)
-                    .addPoint(maxX, minY, minZ)
+            if (minY != maxY) {
+                renderer.addPoint(minX, maxY, minZ)
+                        .addPoint(maxX, maxY, minZ)
+                        .addPoint(maxX, maxY, maxZ)
+                        .addPoint(minX, maxY, maxZ);
+            }
+        }
 
-                    .addPoint(minX, minY, minZ)
+        if(minX != maxX && minY != maxY) {
+            renderer.addPoint(minX, minY, maxZ)
+                    .addPoint(minX, maxY, maxZ)
+                    .addPoint(maxX, maxY, maxZ)
+                    .addPoint(maxX, minY, maxZ);
+
+            if(minZ != maxZ) {
+                renderer.addPoint(minX, minY, minZ)
+                        .addPoint(minX, maxY, minZ)
+                        .addPoint(maxX, maxY, minZ)
+                        .addPoint(maxX, minY, minZ);
+            }
+        }
+        if(minY != maxY && minZ != maxZ) {
+            renderer.addPoint(minX, minY, minZ)
                     .addPoint(minX, minY, maxZ)
                     .addPoint(minX, maxY, maxZ)
-                    .addPoint(minX, maxY, minZ)
+                    .addPoint(minX, maxY, minZ);
 
-                    .addPoint(maxX, minY, minZ)
-                    .addPoint(maxX, minY, maxZ)
-                    .addPoint(maxX, maxY, maxZ)
-                    .addPoint(maxX, maxY, minZ);
+            if(minX != maxX) {
+                renderer.addPoint(maxX, minY, minZ)
+                        .addPoint(maxX, minY, maxZ)
+                        .addPoint(maxX, maxY, maxZ)
+                        .addPoint(maxX, maxY, minZ);
+            }
         }
         renderer.render();
     }
@@ -96,6 +95,15 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
                 .render();
     }
 
+    void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) {
+        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+        GL11.glEnable(GL11.GL_BLEND);
+        renderFaces(min, max, color, alpha);
+        GL11.glDisable(GL11.GL_BLEND);
+        GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
+        GL11.glPolygonOffset(-1.f, -1.f);
+    }
+
     void renderText(OffsetPoint offsetPoint, String... texts) {
         FontRenderer fontRenderer = Minecraft.getInstance().fontRenderer;
 
diff --git a/src/main/java/com/irtimaled/bbor/client/renderers/BiomeBorderRenderer.java b/src/main/java/com/irtimaled/bbor/client/renderers/BiomeBorderRenderer.java
new file mode 100644 (file)
index 0000000..7828981
--- /dev/null
@@ -0,0 +1,60 @@
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.common.models.BoundingBoxBiomeBorder;
+import com.irtimaled.bbor.common.models.Coords;
+import com.irtimaled.bbor.config.ConfigManager;
+
+import java.awt.*;
+
+public class BiomeBorderRenderer extends AbstractRenderer<BoundingBoxBiomeBorder> {
+    @Override
+    public void render(BoundingBoxBiomeBorder boundingBox) {
+        Coords coords = boundingBox.getCoords();
+        OffsetPoint northWest = new OffsetPoint(coords).offset(0, 0.001F, 0);
+        OffsetPoint northEast = northWest.offset(1, 0, 0);
+        OffsetPoint southWest = northWest.offset(0, 0, 1);
+
+        Color color = Color.GREEN;
+        if (boundingBox.renderNorth()) {
+            render(northWest, northEast, color);
+        }
+        if (boundingBox.renderWest()) {
+            render(northWest, southWest, color);
+        }
+        if(ConfigManager.renderOnlyCurrentBiome.get()) {
+            OffsetPoint southEast = southWest.offset(1, 0, 0);
+            if (boundingBox.renderSouth()) {
+                render(southWest, southEast, color);
+            }
+            if (boundingBox.renderEast()) {
+                render(northEast, southEast, color);
+            }
+        }
+    }
+
+    private void render(OffsetPoint topCorner1, OffsetPoint topCorner2, Color color) {
+        double xOffset = 0d;
+        double zOffset = 0d;
+        if(topCorner1.getX() == topCorner2.getX())
+        {
+            xOffset = getOffset(topCorner1.getX());
+        }
+        else
+        {
+            zOffset = getOffset(topCorner1.getZ());
+        }
+
+        topCorner1 = topCorner1.offset(xOffset, 0, zOffset);
+        topCorner2 = topCorner2.offset(xOffset, 0, zOffset);
+
+        renderLine(topCorner1, topCorner2, color);
+        OffsetPoint bottomCorner2 = topCorner2.offset(0, 1, 0);
+        renderFilledFaces(topCorner1, bottomCorner2, color, 30);
+        OffsetPoint bottomCorner1 = topCorner1.offset(0, 1, 0);
+        renderLine(bottomCorner1, bottomCorner2, color);
+    }
+
+    private double getOffset(double value) {
+        return value > 0 ? -0.001F : 0.001F;
+    }
+}
index 0ae5df613ae3acfc5c7b89942998d9423cfd7306..b064594b9026df797fd2e346437a0d1a529ad706 100644 (file)
@@ -26,7 +26,7 @@ public class VillageRenderer extends AbstractRenderer<BoundingBoxVillage> {
         OffsetBox bb = new OffsetBox(offsetCenter, offsetCenter)
                 .grow(8, 3, 8);
 
-        renderUnfilledCuboid(bb, boundingBox.getColor());
+        renderOutlinedCuboid(bb.nudge(), boundingBox.getColor());
     }
 
     private void renderVillageDoors(BoundingBoxVillage boundingBox) {
index bea75ed5436fe95ef99248614739326f0fc6a516..7d26db5ffcdd7a401049e2dafad12f31158e1049 100644 (file)
@@ -17,6 +17,6 @@ public class WorldSpawnRenderer extends AbstractRenderer<BoundingBoxWorldSpawn>
         double y = PlayerCoords.getMaxY(ConfigManager.worldSpawnMaxY.get());
 
         OffsetBox offsetBox = new OffsetBox(minCoords.getX(), y, minCoords.getZ(), maxCoords.getX(), y, maxCoords.getZ());
-        renderUnfilledCuboid(offsetBox, color);
+        renderOutlinedCuboid(offsetBox.nudge(), color);
     }
 }
index a15738b9088e69327029821a10125054300023e5..5d7edc5b13530db33c485fbf5b158b1b848be9b7 100644 (file)
@@ -33,6 +33,7 @@ public class BoundingBoxType {
     public final static BoundingBoxType Village = register(Colors.PURPLE, "Village", ConfigManager.drawVillages);
     public final static BoundingBoxType VillageSpheres = register(null, "Village Sphere", ConfigManager.drawVillageSpheres);
     public final static BoundingBoxType AFKSphere = register(Color.RED, "AFK Sphere", ConfigManager.drawAFKSpheres);
+    public final static BoundingBoxType BiomeBorder = register(Color.GREEN, "Biome Border", ConfigManager.drawBiomeBorders);
     public final static BoundingBoxType Beacon = register(Color.WHITE, "Beacon", ConfigManager.drawBeacons);
     public final static BoundingBoxType Custom = register(Color.WHITE, "Custom", ConfigManager.drawCustomBoxes);
 
diff --git a/src/main/java/com/irtimaled/bbor/common/models/BoundingBoxBiomeBorder.java b/src/main/java/com/irtimaled/bbor/common/models/BoundingBoxBiomeBorder.java
new file mode 100644 (file)
index 0000000..3c7d817
--- /dev/null
@@ -0,0 +1,53 @@
+package com.irtimaled.bbor.common.models;
+
+import com.irtimaled.bbor.common.BoundingBoxType;
+
+public class BoundingBoxBiomeBorder extends AbstractBoundingBox {
+    private final Coords coords;
+    private final boolean north;
+    private final boolean east;
+    private final boolean south;
+    private final boolean west;
+
+    private BoundingBoxBiomeBorder(Coords coords, boolean north, boolean east, boolean south, boolean west) {
+        super(BoundingBoxType.Custom);
+        this.coords = coords;
+        this.north = north;
+        this.east = east;
+        this.south = south;
+        this.west = west;
+    }
+
+    public static BoundingBoxBiomeBorder from(Coords coords, boolean north, boolean east, boolean south, boolean west) {
+        return new BoundingBoxBiomeBorder(coords, north, east, south, west);
+    }
+
+    @Override
+    public Boolean intersectsBounds(int minX, int minZ, int maxX, int maxZ) {
+        return coords.getX() >= minX &&
+                coords.getZ() >= minZ &&
+                coords.getX() <= maxX &&
+                coords.getZ() <= maxZ;
+    }
+
+    public Coords getCoords() {
+        return coords;
+    }
+
+    public boolean renderNorth() {
+        return north;
+    }
+
+    public boolean renderEast() {
+        return east;
+    }
+
+    public boolean renderSouth() {
+        return south;
+    }
+
+    public boolean renderWest() {
+        return west;
+    }
+
+}
index ec57aa11e5672c7d9bf079c511e1b4d65186e022..c79a126397bc5303703a37f16718bef1b8bd1eb7 100644 (file)
@@ -45,6 +45,9 @@ public class ConfigManager {
     public static Setting<Integer> afkSpawnableBlocksRenderDistance;
     public static Setting<Boolean> drawBeacons;
     public static Setting<Boolean> drawCustomBoxes;
+    public static Setting<Boolean> drawBiomeBorders;
+    public static Setting<Boolean> renderOnlyCurrentBiome;
+    public static Setting<Integer> biomeBordersRenderDistance;
 
     public static void loadConfig(File mcConfigDir) {
         configDir = new File(mcConfigDir, "config");
@@ -57,6 +60,9 @@ public class ConfigManager {
         keepCacheBetweenSessions = setup(config, "general", "keepCacheBetweenSessions", false, "If set to true bounding box caches will be kept between sessions.");
         drawBeacons = setup(config, "general", "drawBeacons", true, "If set to true beacon bounding boxes will be drawn.");
         drawCustomBoxes = setup(config, "general", "drawCustomBoxes", true, "If set to true custom bounding boxes will be drawn.");
+        drawBiomeBorders = setup(config, "biomeBorders", "drawBiomeBorders", true, "If set to true biome borders will be drawn.");
+        renderOnlyCurrentBiome = setup(config, "biomeBorders", "renderOnlyCurrentBiome", true, "If set to true only the biome border for the current biome will be drawn.");
+        biomeBordersRenderDistance = setup(config, "biomeBorders", "biomeBordersRenderDistance", 3, "The distance from the player where biome borders will be drawn.");
 
         drawVillageSpheres = setup(config, "villages", "drawVillageSpheres", true, "If set to true village bounding spheres are drawn.");
         drawIronGolemSpawnArea = setup(config, "villages", "drawIronGolemSpawnArea", true, "If set to true the iron golem spawn area of the village will be drawn. (default:true)");