]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
Add support for spawnable blocks rendering
authorIrtimaled <irtimaled@gmail.com>
Sun, 10 May 2020 09:28:19 +0000 (02:28 -0700)
committerIrtimaled <irtimaled@gmail.com>
Mon, 18 May 2020 00:31:27 +0000 (17:31 -0700)
12 files changed:
src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
src/main/java/com/irtimaled/bbor/client/config/BoundingBoxTypeHelper.java
src/main/java/com/irtimaled/bbor/client/config/ConfigManager.java
src/main/java/com/irtimaled/bbor/client/gui/SettingsScreen.java
src/main/java/com/irtimaled/bbor/client/interop/SpawnableBlocksHelper.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSpawnableBlocks.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSpawningSphere.java
src/main/java/com/irtimaled/bbor/client/providers/SpawnableBlocksProvider.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/providers/SpawningSphereProvider.java
src/main/java/com/irtimaled/bbor/client/renderers/SpawnableBlocksRenderer.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/common/BoundingBoxType.java
src/main/resources/assets/bbor/lang/en_us.json

index 6672c6955d15f1e29752441734df31c53e49bdd4..6dedcf31da5e2a0c4e44484e73d771bff2089ee1 100644 (file)
@@ -48,6 +48,7 @@ public class ClientRenderer {
         registerRenderer(BoundingBoxBeacon.class, new BeaconRenderer());
         registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
         registerRenderer(BoundingBoxConduit.class, new ConduitRenderer());
+        registerRenderer(BoundingBoxSpawnableBlocks.class, new SpawnableBlocksRenderer());
 
         registerProvider(new SlimeChunkProvider());
         registerProvider(new WorldSpawnProvider());
@@ -58,6 +59,7 @@ public class ClientRenderer {
         registerProvider(new BiomeBorderProvider());
         registerProvider(new MobSpawnerProvider());
         registerProvider(new ConduitProvider());
+        registerProvider(new SpawnableBlocksProvider());
     }
 
     public static <T extends AbstractBoundingBox> void registerProvider(IBoundingBoxProvider<T> provider) {
index 084652f8aae7453544e19cd72e9ca09f7bc5b9d5..212056ffaf50e875e27e6a3002b747e94b4f1c36 100644 (file)
@@ -22,6 +22,7 @@ public class BoundingBoxTypeHelper {
         registerType(BoundingBoxType.BiomeBorder, ConfigManager.drawBiomeBorders);
         registerType(BoundingBoxType.Beacon, ConfigManager.drawBeacons);
         registerType(BoundingBoxType.Conduit, ConfigManager.drawConduits);
+        registerType(BoundingBoxType.SpawnableBlocks, ConfigManager.drawSpawnableBlocks);
 
         registerType(BoundingBoxType.JungleTemple, ConfigManager.drawJungleTemples);
         registerType(BoundingBoxType.DesertTemple, ConfigManager.drawDesertTemples);
index d6c301c4e581025e44d3d4d8d04c2bf6b2161ee1..13773de56c93463209281b8268722ffe67257945 100644 (file)
@@ -53,6 +53,9 @@ public class ConfigManager {
     public static Setting<Boolean> drawRuinedPortals;
     public static Setting<Boolean> drawConduits;
     public static Setting<Boolean> renderConduitMobHarmArea;
+    public static Setting<Boolean> drawSpawnableBlocks;
+    public static Setting<Integer> spawnableBlocksRenderWidth;
+    public static Setting<Integer> spawnableBlocksRenderHeight;
 
     public static void loadConfig() {
         configDir = new File(".", "config");
@@ -114,6 +117,10 @@ public class ConfigManager {
         renderAFKSpawnableBlocks = setup(config, "afkSpot", "renderAFKSpawnableBlocks", true, "If set to true boxes to show spawnable blocks within the AFK sphere will be drawn.");
         afkSpawnableBlocksRenderDistance = setup(config, "afkSpot", "afkSpawnableBlocksRenderDistance", 3, "The distance from the player where spawnable blocks within the AFK sphere will be drawn.");
 
+        drawSpawnableBlocks = setup(config, "spawnableBlocks", "drawSpawnableBlocks", false, "If set to true boxes to show spawnable blocks will be drawn.");
+        spawnableBlocksRenderWidth = setup(config, "spawnableBlocks", "spawnableBlocksRenderWidth", 2, "The distance from the player where spawnable blocks will be drawn in X and Z axis.");
+        spawnableBlocksRenderHeight = setup(config, "spawnableBlocks", "spawnableBlocksRenderHeight", 1, "The distance from the player where spawnable blocks will be drawn in Y axis.");
+
         config.save();
     }
 
index 92da9ec6bc8d04ff81c20a5e4e81a33f5b717ca5..d336685c0ef11ea24b9b72d1eb70eed1edabf4b6 100644 (file)
@@ -69,6 +69,16 @@ public class SettingsScreen extends ListScreen {
                         (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.beacons"), BoundingBoxType.Beacon),
                         (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.conduits"), BoundingBoxType.Conduit),
                         (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.conduits.mobHarmArea"), ConfigManager.renderConduitMobHarmArea))
+                .section(I18n.format("bbor.features.spawnableBlocks"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.spawnableBlocks"), BoundingBoxType.SpawnableBlocks),
+                        (x, width) -> new IntSettingSlider(width, 1, 3, "bbor.options.distance.y", ConfigManager.spawnableBlocksRenderHeight)
+                                .addDisplayValue(1, "2")
+                                .addDisplayValue(2, "4")
+                                .addDisplayValue(3, "8"),
+                        (x, width) -> new IntSettingSlider(width, 1, 3, "bbor.options.distance.xz", ConfigManager.spawnableBlocksRenderWidth)
+                                .addDisplayValue(1, "8")
+                                .addDisplayValue(2, "16")
+                                .addDisplayValue(3, "32"))
                 .section(I18n.format("bbor.features.spawningSpheres"),
                         (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.spawningSpheres"), BoundingBoxType.AFKSphere),
                         (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.spawningSpheres.spawnableBlocks"), ConfigManager.renderAFKSpawnableBlocks),
diff --git a/src/main/java/com/irtimaled/bbor/client/interop/SpawnableBlocksHelper.java b/src/main/java/com/irtimaled/bbor/client/interop/SpawnableBlocksHelper.java
new file mode 100644 (file)
index 0000000..f781a6c
--- /dev/null
@@ -0,0 +1,67 @@
+package com.irtimaled.bbor.client.interop;
+
+import com.irtimaled.bbor.common.models.Coords;
+import net.minecraft.block.Block;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.EnumCreatureType;
+import net.minecraft.init.Blocks;
+import net.minecraft.tags.BlockTags;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.EnumLightType;
+import net.minecraft.world.World;
+import net.minecraft.world.biome.Biome;
+
+public class SpawnableBlocksHelper {
+    public static void findSpawnableBlocks(Coords coords, int width, int height, BlockProcessor blockProcessor) {
+        int blockX = coords.getX();
+        int minX = blockX - width;
+        int maxX = blockX + width + 1;
+
+        int blockZ = coords.getZ();
+        int minZ = blockZ - width;
+        int maxZ = blockZ + width + 1;
+
+        int blockY = coords.getY();
+        int minY = Math.max(1, blockY - height);
+        int maxY = Math.min(255, blockY + height);
+
+        World world = Minecraft.getInstance().world;
+        for (int x = minX; x < maxX; x++) {
+            for (int z = minZ; z < maxZ; z++) {
+                if (isBiomeHostileSpawnProof(world, new BlockPos(x, 1, z))) continue;
+
+                IBlockState upperBlockState = world.getBlockState(new BlockPos(x, minY - 1, z));
+                for (int y = Math.max(1, minY); y < maxY; y++) {
+                    IBlockState spawnBlockState = upperBlockState;
+                    BlockPos pos = new BlockPos(x, y, z);
+                    upperBlockState = world.getBlockState(pos);
+                    if (isSpawnable(world, pos, spawnBlockState, upperBlockState)) {
+                        blockProcessor.process(x, y, z);
+                    }
+                }
+            }
+        }
+    }
+
+    static boolean isBiomeHostileSpawnProof(World world, BlockPos pos) {
+        Biome biome = world.getBiome(pos);
+        return biome.getSpawningChance() == 0 ||
+                biome.getSpawns(EnumCreatureType.MONSTER).isEmpty();
+    }
+
+    static boolean isSpawnable(World world, BlockPos pos, IBlockState spawnBlockState, IBlockState upperBlockState) {
+        Block spawnBlock = spawnBlockState.getBlock();
+        return spawnBlock != Blocks.AIR &&
+                spawnBlock != Blocks.BEDROCK &&
+                spawnBlock != Blocks.BARRIER &&
+                spawnBlockState.isTopSolid() &&
+                !upperBlockState.isBlockNormalCube() &&
+                !upperBlockState.canProvidePower() &&
+                !upperBlockState.isIn(BlockTags.RAILS) &&
+                upperBlockState.getCollisionShape(world, pos).getEnd(EnumFacing.Axis.Y) <= 0 &&
+                upperBlockState.getFluidState().isEmpty() &&
+                (world.dimension.isNether() || world.getLightFor(EnumLightType.BLOCK, pos) <= 7);
+    }
+}
diff --git a/src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSpawnableBlocks.java b/src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSpawnableBlocks.java
new file mode 100644 (file)
index 0000000..8f3a4d5
--- /dev/null
@@ -0,0 +1,25 @@
+package com.irtimaled.bbor.client.models;
+
+import com.irtimaled.bbor.common.BoundingBoxType;
+import com.irtimaled.bbor.common.models.AbstractBoundingBox;
+import com.irtimaled.bbor.common.models.Coords;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class BoundingBoxSpawnableBlocks extends AbstractBoundingBox {
+    private final Set<Coords> blocks = new HashSet<>();
+
+    public BoundingBoxSpawnableBlocks() {
+        super(BoundingBoxType.SpawnableBlocks);
+    }
+
+    public Set<Coords> getBlocks() {
+        return blocks;
+    }
+
+    @Override
+    public Boolean intersectsBounds(int minX, int minZ, int maxX, int maxZ) {
+        return true;
+    }
+}
index 8229e97b10164d5ff5b4e27563b7178558be44c3..a7d5948cab3465405b964f5e65bb6098968dc966 100644 (file)
@@ -14,6 +14,10 @@ public class BoundingBoxSpawningSphere extends BoundingBoxSphere {
         super(point, SPAWN_RADIUS, BoundingBoxType.AFKSphere);
     }
 
+    public boolean isWithinSphere(Point point) {
+        return this.getPoint().getDistance(point) <= getRadius() + 0.5D;
+    }
+
     public void setSpawnableCount(int count) {
         this.spawnableCount = count;
     }
diff --git a/src/main/java/com/irtimaled/bbor/client/providers/SpawnableBlocksProvider.java b/src/main/java/com/irtimaled/bbor/client/providers/SpawnableBlocksProvider.java
new file mode 100644 (file)
index 0000000..4f3704e
--- /dev/null
@@ -0,0 +1,62 @@
+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.SpawnableBlocksHelper;
+import com.irtimaled.bbor.client.models.BoundingBoxSpawnableBlocks;
+import com.irtimaled.bbor.common.BoundingBoxType;
+import com.irtimaled.bbor.common.MathHelper;
+import com.irtimaled.bbor.common.models.Coords;
+import net.minecraft.client.Minecraft;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class SpawnableBlocksProvider implements IBoundingBoxProvider<BoundingBoxSpawnableBlocks> {
+    public static final Minecraft minecraft = Minecraft.getInstance();
+    private static Long lastGameTime = null;
+
+    private static Set<BoundingBoxSpawnableBlocks> lastBoundingBox = null;
+
+    public static void clear() {
+        lastBoundingBox = null;
+    }
+
+    private boolean isWithinActiveSpawningSphere() {
+        return BoundingBoxTypeHelper.shouldRender(BoundingBoxType.AFKSphere) &&
+                ConfigManager.renderAFKSpawnableBlocks.get() &&
+                SpawningSphereProvider.playerInsideSphere();
+    }
+
+    @Override
+    public boolean canProvide(int dimensionId) {
+        return BoundingBoxTypeHelper.shouldRender(BoundingBoxType.SpawnableBlocks) &&
+                !isWithinActiveSpawningSphere();
+    }
+
+    @Override
+    public Iterable<BoundingBoxSpawnableBlocks> get(int dimensionId) {
+        long gameTime = minecraft.world.getGameTime();
+        if (lastBoundingBox == null || (!((Long) gameTime).equals(lastGameTime) && gameTime % 2L == 0L)) {
+            lastGameTime = gameTime;
+            lastBoundingBox = getSpawnableBlocks();
+        }
+        return lastBoundingBox;
+    }
+
+    private Set<BoundingBoxSpawnableBlocks> getSpawnableBlocks() {
+        BoundingBoxSpawnableBlocks boundingBox = new BoundingBoxSpawnableBlocks();
+        Set<Coords> blocks = boundingBox.getBlocks();
+
+        int width = MathHelper.floor(Math.pow(2, 1 + ConfigManager.spawnableBlocksRenderWidth.get()));
+        int height = MathHelper.floor(Math.pow(2, ConfigManager.spawnableBlocksRenderHeight.get()));
+
+        SpawnableBlocksHelper.findSpawnableBlocks(Player.getCoords(), width, height,
+                (x, y, z) -> blocks.add(new Coords(x, y, z)));
+
+        Set<BoundingBoxSpawnableBlocks> boundingBoxes = new HashSet<>();
+        boundingBoxes.add(boundingBox);
+        return boundingBoxes;
+    }
+}
index 1efd41ebf023b0a09077f2aa5729c507b93d6a0c..00c24827ee5bd8cfea3dbb5a4d254ae5299a960d 100644 (file)
@@ -58,9 +58,17 @@ public class SpawningSphereProvider implements IBoundingBoxProvider<BoundingBoxS
         return SpawningSphereHelper.findSpawnableSpaces(center, center.getCoords(), size, size, (x, y, z) -> true);
     }
 
+    static boolean playerInsideSphere() {
+        return spawningSphereInDimension(Player.getDimensionId()) && spawningSphere.isWithinSphere(Player.getPoint());
+    }
+
+    private static boolean spawningSphereInDimension(int dimensionId) {
+        return spawningSphere != null && SpawningSphereProvider.dimensionId == dimensionId;
+    }
+
     @Override
     public boolean canProvide(int dimensionId) {
-        return spawningSphere != null && SpawningSphereProvider.dimensionId == dimensionId && BoundingBoxTypeHelper.shouldRender(BoundingBoxType.AFKSphere);
+        return spawningSphereInDimension(dimensionId) && BoundingBoxTypeHelper.shouldRender(BoundingBoxType.AFKSphere);
     }
 
     @Override
diff --git a/src/main/java/com/irtimaled/bbor/client/renderers/SpawnableBlocksRenderer.java b/src/main/java/com/irtimaled/bbor/client/renderers/SpawnableBlocksRenderer.java
new file mode 100644 (file)
index 0000000..504ce3f
--- /dev/null
@@ -0,0 +1,16 @@
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.client.models.BoundingBoxSpawnableBlocks;
+
+public class SpawnableBlocksRenderer extends AbstractRenderer<BoundingBoxSpawnableBlocks> {
+    @Override
+    public void render(BoundingBoxSpawnableBlocks boundingBox) {
+        boundingBox.getBlocks().forEach(c ->        {
+            int x = c.getX();
+            int y = c.getY();
+            int z = c.getZ();
+            OffsetBox offsetBox = new OffsetBox(x, y, z, x + 1, y, z + 1);
+            renderCuboid(offsetBox, boundingBox.getColor());
+        });
+    }
+}
index ecb128717388ecb4a3af7f53ae743da7e8709662..51fe9b67e80ccefccbf9f1371920f4d705a37269 100644 (file)
@@ -19,6 +19,7 @@ public class BoundingBoxType {
     public static final BoundingBoxType Custom = register(Color.WHITE, "Custom");
     public static final BoundingBoxType Beacon = register(Color.WHITE, "Beacon");
     public static final BoundingBoxType Conduit = register(Color.CYAN, "Conduit");
+    public static final BoundingBoxType SpawnableBlocks = register(Color.RED, "Spawnable Blocks");
 
     public static final BoundingBoxType JungleTemple = register(Colors.DARK_GREEN, "Jungle_Pyramid");
     public static final BoundingBoxType DesertTemple = register(Color.ORANGE, "Desert_Pyramid");
index dea0e6313802b77bc23222f23797e8415e81f507..56dcbda9f7a7496ef5e7243a1862723530500a31 100644 (file)
@@ -17,6 +17,8 @@
   "bbor.options.distance.nearest": "Nearest",
   "bbor.options.distance.nearer": "Nearer",
   "bbor.options.distance.normal": "Normal",
+  "bbor.options.distance.y": "Distance (Y): %s",
+  "bbor.options.distance.xz": "Distance (X/Z): %s",
 
   "bbor.features.spawnChunks": "Spawn Chunks",
   "bbor.features.lazyChunks": "Lazy Chunks",
@@ -26,6 +28,7 @@
   "bbor.features.mobSpawners.activationLines": "Activation Lines",
   "bbor.features.spawningSpheres": "Spawning Spheres",
   "bbor.features.spawningSpheres.spawnableBlocks": "Spawnable Blocks",
+  "bbor.features.spawnableBlocks": "Spawnable Blocks",
   "bbor.features.biomeBorders": "Biome Borders",
 
   "bbor.sections.beaconsAndConduits": "Beacons & Conduits",