From 8924242cee0cd983d50889afed21c7c8ff216e28 Mon Sep 17 00:00:00 2001 From: Irtimaled Date: Sun, 13 Sep 2020 23:47:42 -0700 Subject: [PATCH] Add BedrockCeiling boxes --- .../irtimaled/bbor/client/ClientRenderer.java | 2 + .../client/config/BoundingBoxTypeHelper.java | 1 + .../bbor/client/config/ConfigManager.java | 6 +- .../client/interop/BedrockCeilingHelper.java | 27 ++++ .../bbor/client/interop/ClientInterop.java | 4 + .../models/BoundingBoxBedrockCeiling.java | 11 ++ .../providers/BedrockCeilingProvider.java | 138 ++++++++++++++++++ .../bbor/common/BoundingBoxType.java | 1 + .../bbor/common/models/DimensionId.java | 1 + 9 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/irtimaled/bbor/client/interop/BedrockCeilingHelper.java create mode 100644 src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBedrockCeiling.java create mode 100644 src/main/java/com/irtimaled/bbor/client/providers/BedrockCeilingProvider.java diff --git a/src/main/java/com/irtimaled/bbor/client/ClientRenderer.java b/src/main/java/com/irtimaled/bbor/client/ClientRenderer.java index e4bf5b5..68788d1 100644 --- a/src/main/java/com/irtimaled/bbor/client/ClientRenderer.java +++ b/src/main/java/com/irtimaled/bbor/client/ClientRenderer.java @@ -48,6 +48,7 @@ public class ClientRenderer { registerRenderer(BoundingBoxLine.class, new LineRenderer()); registerRenderer(BoundingBoxSphere.class, new SphereRenderer()); registerRenderer(BoundingBoxFlowerForest.class, new FlowerForestRenderer()); + registerRenderer(BoundingBoxBedrockCeiling.class, new CuboidRenderer()); registerProvider(new SlimeChunkProvider()); registerProvider(new WorldSpawnProvider()); @@ -62,6 +63,7 @@ public class ClientRenderer { registerProvider(new CustomLineProvider()); registerProvider(new CustomSphereProvider()); registerProvider(new FlowerForestProvider()); + registerProvider(new BedrockCeilingProvider()); } public static void registerProvider(IBoundingBoxProvider provider) { diff --git a/src/main/java/com/irtimaled/bbor/client/config/BoundingBoxTypeHelper.java b/src/main/java/com/irtimaled/bbor/client/config/BoundingBoxTypeHelper.java index 3688627..d22d71b 100644 --- a/src/main/java/com/irtimaled/bbor/client/config/BoundingBoxTypeHelper.java +++ b/src/main/java/com/irtimaled/bbor/client/config/BoundingBoxTypeHelper.java @@ -26,6 +26,7 @@ public class BoundingBoxTypeHelper { registerType(BoundingBoxType.Conduit, ConfigManager.drawConduits, ConfigManager.colorConduits); registerType(BoundingBoxType.SpawnableBlocks, ConfigManager.drawSpawnableBlocks, ConfigManager.colorSpawnableBlocks); registerType(BoundingBoxType.FlowerForest, ConfigManager.drawFlowerForests, null); + registerType(BoundingBoxType.BedrockCeiling, ConfigManager.drawBedrockCeilingBlocks, ConfigManager.colorBedrockCeilingBlocks); registerType(BoundingBoxType.JungleTemple, ConfigManager.drawJungleTemples, ConfigManager.colorJungleTemples); registerType(BoundingBoxType.DesertTemple, ConfigManager.drawDesertTemples, ConfigManager.colorDesertTemples); diff --git a/src/main/java/com/irtimaled/bbor/client/config/ConfigManager.java b/src/main/java/com/irtimaled/bbor/client/config/ConfigManager.java index a659e62..ceeda12 100644 --- a/src/main/java/com/irtimaled/bbor/client/config/ConfigManager.java +++ b/src/main/java/com/irtimaled/bbor/client/config/ConfigManager.java @@ -55,6 +55,7 @@ public class ConfigManager { public static Setting renderSphereAsDots; public static Setting drawFlowerForests; public static Setting flowerForestsRenderDistance; + public static Setting drawBedrockCeilingBlocks; public static Setting colorWorldSpawn; public static Setting colorLazySpawnChunks; @@ -100,6 +101,7 @@ public class ConfigManager { public static Setting colorFlowerForestOxeyeDaisy; public static Setting colorFlowerForestCornflower; public static Setting colorFlowerForestLilyOfTheValley; + public static Setting colorBedrockCeilingBlocks; public static Setting buttonOnOverlay; @@ -129,6 +131,8 @@ public class ConfigManager { drawFlowerForests = setup(config, "flowerForests", "drawFlowerForests", true, "If set to true flower forest flower overlays will be drawn."); flowerForestsRenderDistance = setup(config, "flowerForests", "flowerForestsRenderDistance", 3, "The distance from the player where flower forests will be drawn."); + drawBedrockCeilingBlocks = setup(config, "bedrockCeiling", "drawBedrockCeilingBlocks", true, "If set to true position with only one layer of bedrock will be drawn."); + drawVillages = setup(config, "structures", "drawVillages", false, "If set to true village bounding boxes will be drawn."); drawDesertTemples = setup(config, "structures", "drawDesertTemples", true, "If set to true desert temple bounding boxes are drawn."); drawJungleTemples = setup(config, "structures", "drawJungleTemples", true, "If set to true jungle temple bounding boxes are drawn."); @@ -211,7 +215,7 @@ public class ConfigManager { colorFlowerForestOxeyeDaisy = setup(config, "colors", "colorFlowerForestOxeyeDaisy", HexColor.from("#d3d3d3"), "Color of Flower Forest Oxeye Daisy"); colorFlowerForestCornflower = setup(config, "colors", "colorFlowerForestCornflower", HexColor.from("#0000ff"), "Color of Flower Forest Cornflower"); colorFlowerForestLilyOfTheValley = setup(config, "colors", "colorFlowerForestLilyOfTheValley", HexColor.from("#ffffff"), "Color of Flower Forest Lily Of The Valley"); - + colorBedrockCeilingBlocks = setup(config, "colors", "colorBedrockCeilingBlocks", HexColor.from("#00ff00"), "Color of Bedrock Ceiling Blocks"); config.save(); } diff --git a/src/main/java/com/irtimaled/bbor/client/interop/BedrockCeilingHelper.java b/src/main/java/com/irtimaled/bbor/client/interop/BedrockCeilingHelper.java new file mode 100644 index 0000000..5d7e262 --- /dev/null +++ b/src/main/java/com/irtimaled/bbor/client/interop/BedrockCeilingHelper.java @@ -0,0 +1,27 @@ +package com.irtimaled.bbor.client.interop; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.Minecraft; +import net.minecraft.util.SharedSeedRandom; +import net.minecraft.util.math.BlockPos; + +import java.util.Random; + +public class BedrockCeilingHelper { + public static boolean isBedrock(int x, int y, int z){ + BlockPos pos = new BlockPos(x, y, z); + BlockState blockState = Minecraft.getInstance().world.getBlockState(pos); + return blockState == Blocks.BEDROCK.getDefaultState(); + } + + public static boolean chunkLoaded(int chunkX, int chunkZ) { + return Minecraft.getInstance().world.getChunkProvider().chunkExists(chunkX, chunkZ); + } + + public static Random getRandomForChunk(int chunkX, int chunkZ) { + SharedSeedRandom random = new SharedSeedRandom(); + random.setBaseChunkSeed(chunkX, chunkZ); + return random; + } +} diff --git a/src/main/java/com/irtimaled/bbor/client/interop/ClientInterop.java b/src/main/java/com/irtimaled/bbor/client/interop/ClientInterop.java index 7ab06b9..581215f 100644 --- a/src/main/java/com/irtimaled/bbor/client/interop/ClientInterop.java +++ b/src/main/java/com/irtimaled/bbor/client/interop/ClientInterop.java @@ -119,4 +119,8 @@ public class ClientInterop { public static void displayScreen(Screen screen) { Minecraft.getInstance().displayGuiScreen(screen); } + + public static long getGameTime() { + return Minecraft.getInstance().world.getGameTime(); + } } diff --git a/src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBedrockCeiling.java b/src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBedrockCeiling.java new file mode 100644 index 0000000..d661c52 --- /dev/null +++ b/src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBedrockCeiling.java @@ -0,0 +1,11 @@ +package com.irtimaled.bbor.client.models; + +import com.irtimaled.bbor.common.BoundingBoxType; +import com.irtimaled.bbor.common.models.BoundingBoxCuboid; +import com.irtimaled.bbor.common.models.Coords; + +public class BoundingBoxBedrockCeiling extends BoundingBoxCuboid { + public BoundingBoxBedrockCeiling(Coords coords) { + super(coords, coords, BoundingBoxType.BedrockCeiling); + } +} diff --git a/src/main/java/com/irtimaled/bbor/client/providers/BedrockCeilingProvider.java b/src/main/java/com/irtimaled/bbor/client/providers/BedrockCeilingProvider.java new file mode 100644 index 0000000..3278be4 --- /dev/null +++ b/src/main/java/com/irtimaled/bbor/client/providers/BedrockCeilingProvider.java @@ -0,0 +1,138 @@ +package com.irtimaled.bbor.client.providers; + +import com.irtimaled.bbor.client.Player; +import com.irtimaled.bbor.client.config.BoundingBoxTypeHelper; +import com.irtimaled.bbor.client.config.ConfigManager; +import com.irtimaled.bbor.client.interop.BedrockCeilingHelper; +import com.irtimaled.bbor.client.interop.ClientInterop; +import com.irtimaled.bbor.client.models.BoundingBoxBedrockCeiling; +import com.irtimaled.bbor.common.BoundingBoxType; +import com.irtimaled.bbor.common.MathHelper; +import com.irtimaled.bbor.common.models.Coords; +import com.irtimaled.bbor.common.models.DimensionId; + +import java.util.*; + +public class BedrockCeilingProvider implements IBoundingBoxProvider, ICachingProvider { + private static final double CHUNK_SIZE = 16d; + private static Long lastGameTime = null; + private static final Map chunks = new HashMap<>(); + + private static class BedrockChunk { + private final Set boxes = new HashSet<>(); + + public BedrockChunk(int chunkX, int chunkZ) { + int chunkStartX = chunkX << 4; + int chunkStartZ = chunkZ << 4; + + if (BedrockCeilingHelper.chunkLoaded(chunkX, chunkZ)) findBoxesFromBlockState(chunkStartX, chunkStartZ); + else findBoxesFromRNG(chunkX, chunkZ, chunkStartX, chunkStartZ); + } + + private void findBoxesFromBlockState(int chunkStartX, int chunkStartZ) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + Coords coords = getCoordsFromBlockState(chunkStartX + x, chunkStartZ + z); + if (coords != null) { + boxes.add(new BoundingBoxBedrockCeiling(coords)); + } + } + } + } + + private Coords getCoordsFromBlockState(int x, int z) { + Coords coords = null; + for (int y = 127; y >= 123; y--) { + if (BedrockCeilingHelper.isBedrock(x, y, z)) { + if (coords == null) { + coords = new Coords(x, y, z); + } else { + return null; + } + } + } + return coords; + } + + private void findBoxesFromRNG(int chunkX, int chunkZ, int chunkStartX, int chunkStartZ) { + Random random = BedrockCeilingHelper.getRandomForChunk(chunkX, chunkZ); + + // preseed 16x16x3 calls to nextDouble + for (int dummy = 0; dummy < 768; dummy++) { + random.nextDouble(); + } + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + Coords coords = getBlocksFromRNG(random, chunkStartX + x, chunkStartZ + z); + + if (coords != null) { + boxes.add(new BoundingBoxBedrockCeiling(coords)); + } + } + } + } + + private Coords getBlocksFromRNG(Random random, int x, int z) { + int count = 0; + for (int y = 127; y >= 123; y--) { + if (y >= 127 - random.nextInt(5)) { + count++; + } + } + for (int y = 4; y >= 0; y--) { + random.nextInt(5); + } + return count == 1 ? new Coords(x, 127, z) : null; + } + + public Collection getBlocks() { + return boxes; + } + + public void clear() { + boxes.clear(); + } + } + + public void clearCache() { + chunks.values().forEach(BedrockChunk::clear); + chunks.clear(); + } + + @Override + public Iterable get(DimensionId dimensionId) { + boolean shouldRecalculate = shouldRecalculate(); + + int renderDistanceChunks = ClientInterop.getRenderDistanceChunks() / 2; + int playerChunkX = MathHelper.floor(Player.getX() / CHUNK_SIZE); + int playerChunkZ = MathHelper.floor(Player.getZ() / CHUNK_SIZE); + + Set boxes = new HashSet<>(); + + for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; chunkX++) { + for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; chunkZ++) { + String key = String.format("%d,%d", chunkX, chunkZ); + if (shouldRecalculate || !chunks.containsKey(key)) { + chunks.put(key, new BedrockChunk(chunkX, chunkZ)); + } + BedrockChunk chunk = chunks.get(key); + boxes.addAll(chunk.getBlocks()); + } + } + return boxes; + } + + public boolean shouldRecalculate() { + long gameTime = ClientInterop.getGameTime(); + if (!((Long) gameTime).equals(lastGameTime) && gameTime % 2L == 0L) { + lastGameTime = gameTime; + return true; + } + return false; + } + + @Override + public boolean canProvide(DimensionId dimensionId) { + return dimensionId == DimensionId.NETHER && BoundingBoxTypeHelper.shouldRender(BoundingBoxType.BedrockCeiling) && Player.getY() > 110; + } +} diff --git a/src/main/java/com/irtimaled/bbor/common/BoundingBoxType.java b/src/main/java/com/irtimaled/bbor/common/BoundingBoxType.java index 65728f6..05cca0a 100644 --- a/src/main/java/com/irtimaled/bbor/common/BoundingBoxType.java +++ b/src/main/java/com/irtimaled/bbor/common/BoundingBoxType.java @@ -18,6 +18,7 @@ public class BoundingBoxType { public static final BoundingBoxType Conduit = register("Conduit"); public static final BoundingBoxType SpawnableBlocks = register("Spawnable Blocks"); public static final BoundingBoxType FlowerForest = register("Flower Forest"); + public static final BoundingBoxType BedrockCeiling = register("Bedrock Ceiling"); public static final BoundingBoxType JungleTemple = register("Jungle_Pyramid"); public static final BoundingBoxType DesertTemple = register("Desert_Pyramid"); diff --git a/src/main/java/com/irtimaled/bbor/common/models/DimensionId.java b/src/main/java/com/irtimaled/bbor/common/models/DimensionId.java index 83924e3..b40cdcc 100644 --- a/src/main/java/com/irtimaled/bbor/common/models/DimensionId.java +++ b/src/main/java/com/irtimaled/bbor/common/models/DimensionId.java @@ -18,6 +18,7 @@ public class DimensionId { } public static DimensionId OVERWORLD = DimensionId.from(DimensionType.OVERWORLD); + public static DimensionId NETHER = DimensionId.from(DimensionType.NETHER); private final ResourceLocation value; -- 2.44.0