+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.util.math.AxisAlignedBB;
-import net.minecraft.util.math.BlockPos;
-
-import java.awt.*;
-
-public abstract class BoundingBox {
- private final Color color;
- private final BlockPos minBlockPos;
- private final BlockPos maxBlockPos;
-
- protected BoundingBox(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- this.minBlockPos = minBlockPos;
- this.maxBlockPos = maxBlockPos;
- this.color = color;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + minBlockPos.hashCode();
- result = prime * result + maxBlockPos.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- BoundingBox other = (BoundingBox) obj;
- if (!minBlockPos.equals(other.minBlockPos))
- return false;
- if (!maxBlockPos.equals(other.maxBlockPos))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "(" + minBlockPos.toString() + "; " + maxBlockPos.toString() + ")";
- }
-
- public AxisAlignedBB toAxisAlignedBB() {
- return toAxisAlignedBB(true);
- }
-
- public AxisAlignedBB toAxisAlignedBB(boolean extendMaxByOne) {
- AxisAlignedBB axisAlignedBB = new AxisAlignedBB(minBlockPos, maxBlockPos);
- if (extendMaxByOne)
- return axisAlignedBB.expand(1, 1, 1);
- return axisAlignedBB;
- }
-
- public BlockPos getMinBlockPos() {
- return minBlockPos;
- }
-
- public BlockPos getMaxBlockPos() {
- return maxBlockPos;
- }
-
- public Color getColor() {
- return color;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class BoundingBoxCache {
- private Map<BoundingBox, Set<BoundingBox>> cache = new ConcurrentHashMap<>();
-
- public Map<BoundingBox, Set<BoundingBox>> getBoundingBoxes() {
- return cache;
- }
-
- public synchronized void refresh() {
- }
-
- public void close() {
- cache.clear();
- }
-
- public boolean isCached(BoundingBox key) {
- return cache.containsKey(key);
- }
-
- public void addBoundingBoxes(BoundingBox key, Set<BoundingBox> boundingBoxes) {
- cache.put(key, boundingBoxes);
- }
-
- public void addBoundingBox(BoundingBox key) {
- Set<BoundingBox> boundingBoxes = new HashSet<>();
- boundingBoxes.add(key);
- addBoundingBoxes(key, boundingBoxes);
- }
-
- public void removeBoundingBox(BoundingBox key) {
- if (cache.containsKey(key)) {
- cache.remove(key);
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.network.NetworkManager;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-
-import java.io.File;
-
-public class BoundingBoxOutlineReloaded {
- public static ClientProxy proxy;
-
- public static void init() {
- proxy = new ClientProxy();
- proxy.init(new ConfigManager(new File(Minecraft.getMinecraft().mcDataDir, "config")));
- }
-
- public static void chunkLoaded(Chunk chunk) {
- proxy.chunkLoaded(chunk);
- }
-
- public static void worldLoaded(World world) {
- proxy.worldLoaded(world);
- }
-
- public static void keyPressed() {
- proxy.keyPressed();
- }
-
- public static void render(float partialTicks) {
- proxy.render(partialTicks);
- }
-
- public static void playerConnectedToServer(NetworkManager networkManager) {
- proxy.playerConnectedToServer(networkManager);
- }
-
- public static void playerDisconnectedFromServer() {
- proxy.playerDisconnectedFromServer();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.ChunkPos;
-
-import java.awt.*;
-
-public class BoundingBoxSlimeChunk extends BoundingBox {
- private BoundingBoxSlimeChunk(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- super(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxSlimeChunk from(ChunkPos chunkCoordIntPair, Color color) {
- BlockPos minBlockPos = new BlockPos(chunkCoordIntPair.getXStart(), 1, chunkCoordIntPair.getZStart());
- BlockPos maxBlockPos = new BlockPos(chunkCoordIntPair.getXEnd(), 38, chunkCoordIntPair.getZEnd());
- return new BoundingBoxSlimeChunk(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxSlimeChunk from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- return new BoundingBoxSlimeChunk(minBlockPos, maxBlockPos, color);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.gen.structure.StructureBoundingBox;
-
-import java.awt.*;
-
-public class BoundingBoxStructure extends BoundingBox {
- private BoundingBoxStructure(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- super(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxStructure from(StructureBoundingBox bb, Color color) {
- BlockPos minBlockPos = new BlockPos(bb.minX, bb.minY, bb.minZ);
- BlockPos maxBlockPos = new BlockPos(bb.maxX, bb.maxY, bb.maxZ);
- return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxStructure from(int[] bb, Color color) {
- BlockPos minBlockPos = new BlockPos(bb[0], bb[1], bb[2]);
- BlockPos maxBlockPos = new BlockPos(bb[3], bb[4], bb[5]);
- return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxStructure from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.util.math.BlockPos;
-
-import java.awt.*;
-import java.util.Set;
-
-public class BoundingBoxVillage extends BoundingBox {
- private final BlockPos center;
- private final Integer radius;
- private final boolean spawnsIronGolems;
- private Set<BlockPos> doors;
- private Double centerOffsetX;
- private Double centerOffsetZ;
-
- protected BoundingBoxVillage(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors, BlockPos minBlockPos, BlockPos maxBlockPos) {
- super(minBlockPos, maxBlockPos, color);
- this.center = center;
- this.radius = radius;
- this.spawnsIronGolems = spawnsIronGolems;
- this.doors = doors;
- calculateCenterOffsets(doors);
- }
-
- public static BoundingBoxVillage from(BlockPos center, Integer radius, int population, Set<BlockPos> doors) {
- return from(center, radius, null, population, doors);
- }
-
- public static BoundingBoxVillage from(BlockPos center, Integer radius, Color color, int population, Set<BlockPos> doors) {
- Boolean spawnsIronGolems = population >= 10 && doors.size() >= 21;
- return from(center, radius, color, spawnsIronGolems, doors);
- }
-
- public static BoundingBoxVillage from(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors) {
- BlockPos minBlockPos = new BlockPos(center.getX() - radius,
- center.getY() - 4,
- center.getZ() - radius);
- BlockPos maxBlockPos = new BlockPos(center.getX() + radius,
- center.getY() + 4,
- center.getZ() + radius);
- if (color == null)
- color = getNextColor();
- return new BoundingBoxVillage(center, radius, color, spawnsIronGolems, doors, minBlockPos, maxBlockPos);
- }
-
- private void calculateCenterOffsets(Set<BlockPos> doors) {
- boolean processedFirstDoor = false;
- int minX = 0;
- int maxX = 0;
- int minZ = 0;
- int maxZ = 0;
- for (BlockPos door : doors) {
- if (!processedFirstDoor ||
- (minX > door.getX()))
- minX = door.getX();
- if (!processedFirstDoor ||
- maxX < door.getX())
- maxX = door.getX();
- if (!processedFirstDoor ||
- minZ > door.getZ())
- minZ = door.getZ();
- if (!processedFirstDoor ||
- maxZ < door.getZ())
- maxZ = door.getZ();
-
- processedFirstDoor = true;
- }
- centerOffsetX = Math.abs(maxX - minX) % 2 == 0 ? 0.5 : (minX < 0 ? 0 : 1);
- centerOffsetZ = Math.abs(maxZ - minZ) % 2 == 0 ? 0.5 : (minZ < 0 ? 0 : 1);
- }
-
- @Override
- public String toString() {
- return "(" + center.toString() + "; " + radius.toString() + ")";
- }
-
- public Integer getRadius() {
- return radius;
- }
-
- public BlockPos getCenter() {
- return center;
- }
-
- public Double getCenterOffsetX() {
- return centerOffsetX;
- }
-
- public Double getCenterOffsetZ() {
- return centerOffsetZ;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- for (BlockPos door : doors) {
- result = prime * result + door.hashCode();
- }
- return result;
- }
-
- public boolean getSpawnsIronGolems() {
- return spawnsIronGolems;
- }
-
- private static int colorIndex = -1;
-
- public static Color getNextColor() {
- ++colorIndex;
- switch (colorIndex % 6) {
- case 0:
- return Color.RED;
- case 1:
- return Color.GREEN;
- case 2:
- return Color.BLUE;
- case 3:
- return Color.MAGENTA;
- case 4:
- return Color.YELLOW;
- case 5:
- return Color.CYAN;
- }
- return Color.WHITE;
- }
-
- public Set<BlockPos> getDoors() {
- return doors;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.util.math.BlockPos;
-
-import java.awt.*;
-
-public class BoundingBoxWorldSpawn extends BoundingBox {
- protected BoundingBoxWorldSpawn(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- super(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxWorldSpawn from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, color);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.WorldClient;
-import net.minecraft.client.renderer.BufferBuilder;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.client.settings.KeyBinding;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.nbt.CompressedStreamTools;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.network.NetworkManager;
-import net.minecraft.util.math.AxisAlignedBB;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.ChunkPos;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.world.DimensionType;
-import org.apache.commons.lang3.ArrayUtils;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-
-import java.awt.*;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-
-public class ClientProxy extends CommonProxy {
- private double activeY;
- private boolean active;
- private boolean outerBoxOnly;
- private KeyBinding activeHotKey;
- private KeyBinding outerBoxOnlyHotKey;
- private double playerX;
- private double playerY;
- private double playerZ;
- private BoundingBox worldSpawnBoundingBox;
- private BoundingBox spawnChunksBoundingBox;
- private BoundingBox lazySpawnChunksBoundingBox;
-
- public void keyPressed() {
- if (activeHotKey.isPressed()) {
- active = !active;
- if (active)
- activeY = playerY;
- } else if (outerBoxOnlyHotKey.isPressed()) {
- outerBoxOnly = !outerBoxOnly;
- }
- }
-
- @Override
- public void init(ConfigManager configManager) {
- super.init(configManager);
- String category = "Bounding Box Outline Reloaded";
- activeHotKey = new KeyBinding("Toggle On/Off", Keyboard.KEY_B, category);
- outerBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", Keyboard.KEY_O, category);
- Minecraft.getMinecraft().gameSettings.keyBindings = ArrayUtils.addAll(Minecraft.getMinecraft().gameSettings.keyBindings, activeHotKey, outerBoxOnlyHotKey);
- }
-
- @Override
- public void setWorldData(WorldData worldData) {
- worldSpawnBoundingBox = null;
- spawnChunksBoundingBox = null;
- lazySpawnChunksBoundingBox = null;
- super.setWorldData(worldData);
- }
-
- public void render(float partialTicks) {
- EntityPlayer entityPlayer = Minecraft.getMinecraft().player;
- playerX = entityPlayer.lastTickPosX + (entityPlayer.posX - entityPlayer.lastTickPosX) * (double) partialTicks;
- playerY = entityPlayer.lastTickPosY + (entityPlayer.posY - entityPlayer.lastTickPosY) * (double) partialTicks;
- playerZ = entityPlayer.lastTickPosZ + (entityPlayer.posZ - entityPlayer.lastTickPosZ) * (double) partialTicks;
-
- if (this.active) {
- DimensionType dimensionType = DimensionType.getById(entityPlayer.dimension);
- Map<BoundingBox, Set<BoundingBox>> boundingBoxes = null;
- if (boundingBoxCacheMap.containsKey(dimensionType)) {
- boundingBoxes = boundingBoxCacheMap.get(dimensionType).getBoundingBoxes();
- }
- renderBoundingBoxes(boundingBoxes, getClientBoundingBoxes(dimensionType));
- }
- }
-
- public void playerConnectedToServer(NetworkManager networkManager) {
- SocketAddress remoteAddress = networkManager.getRemoteAddress();
- if (remoteAddress instanceof InetSocketAddress) {
- InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress;
- loadLocalStructures(socketAddress.getHostName(), socketAddress.getPort());
- }
- }
-
- private void loadLocalStructures(String host, int port) {
- Logger.info("Looking for local structures (host:port=%s:%d)", host, port);
- String path = String.format("BBOutlineReloaded%s%s%s%d", File.separator, host, File.separator, port);
- File localStructuresFolder = new File(configManager.configDir, path);
- Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
- if (!localStructuresFolder.exists()) {
- path = String.format("BBOutlineReloaded%s%s", File.separator, host);
- localStructuresFolder = new File(configManager.configDir, path);
- Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
- }
- if (!localStructuresFolder.exists()) {
- path = String.format("BBOutlineReloaded%s%s,%d", File.separator, host, port);
- localStructuresFolder = new File(configManager.configDir, path);
- Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
- }
- if (!localStructuresFolder.exists()) {
- Logger.info("No local structures folders found");
- return;
- }
- loadLevelDat(localStructuresFolder);
- loadNetherStructures(localStructuresFolder);
- loadOverworldStructures(localStructuresFolder);
- loadEndStructures(localStructuresFolder);
- }
-
- private void loadOverworldStructures(File localStructuresFolder) {
- BoundingBoxCache cache = new BoundingBoxCache();
- if (configManager.drawDesertTemples.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Temple.dat", StructureType.DesertTemple.getColor(), "TeDP");
- }
- if (configManager.drawJungleTemples.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Temple.dat", StructureType.JungleTemple.getColor(), "TeJP");
- }
- if (configManager.drawWitchHuts.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Temple.dat", StructureType.WitchHut.getColor(), "TeSH");
- }
- if (configManager.drawOceanMonuments.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Monument.dat", StructureType.OceanMonument.getColor(), "*");
- }
- if (configManager.drawStrongholds.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Stronghold.dat", StructureType.Stronghold.getColor(), "*");
- }
- if (configManager.drawMansions.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Mansion.dat", StructureType.Mansion.getColor(), "*");
- }
- if (configManager.drawMineShafts.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "Mineshaft.dat", StructureType.MineShaft.getColor(), "*");
- }
- if (configManager.drawVillages.getBoolean()) {
- loadVillageNbtFile(localStructuresFolder, cache, "Villages.dat");
- }
-
- boundingBoxCacheMap.put(DimensionType.OVERWORLD, cache);
- }
-
- private void loadNetherStructures(File localStructuresFolder) {
- BoundingBoxCache cache = new BoundingBoxCache();
- if (configManager.drawNetherFortresses.getBoolean())
- loadStructureNbtFile(localStructuresFolder, cache, "Fortress.dat", StructureType.NetherFortress.getColor(), "*");
- if (configManager.drawVillages.getBoolean()) {
- loadVillageNbtFile(localStructuresFolder, cache, "villages_nether.dat");
- }
- boundingBoxCacheMap.put(DimensionType.NETHER, cache);
- }
-
- private void loadEndStructures(File localStructuresFolder) {
- BoundingBoxCache cache = new BoundingBoxCache();
- if (configManager.drawVillages.getBoolean()) {
- loadVillageNbtFile(localStructuresFolder, cache, "Villages_end.dat");
- }
- if (configManager.drawEndCities.getBoolean()) {
- loadStructureNbtFile(localStructuresFolder, cache, "EndCity.dat", StructureType.EndCity.getColor(), "*");
- }
- boundingBoxCacheMap.put(DimensionType.THE_END, cache);
- }
-
- private void loadVillageNbtFile(File localStructuresFolder, BoundingBoxCache cache, String fileName) {
- File file = new File(localStructuresFolder, fileName);
- NBTTagCompound nbt = loadNbtFile(file);
- if (nbt == null)
- return;
-
- NBTTagCompound[] villages = getChildCompoundTags(nbt.getCompoundTag("data"), "Villages");
- for (NBTTagCompound village : villages) {
- BlockPos center = new BlockPos(village.getInteger("CX"), village.getInteger("CY"), village.getInteger("CZ"));
- int radius = village.getInteger("Radius");
- int population = village.getInteger("PopSize");
- Set<BlockPos> doors = getDoors(village);
- BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, population, doors);
- cache.addBoundingBox(boundingBox);
- }
-
- Logger.info("Loaded %s (%d villages)", fileName, villages.length);
- }
-
- private Set<BlockPos> getDoors(NBTTagCompound village) {
- Set<BlockPos> doors = new HashSet<>();
- for (NBTTagCompound door : getChildCompoundTags(village, "Doors")) {
- doors.add(new BlockPos(door.getInteger("X"), door.getInteger("Y"), door.getInteger("Z")));
- }
- return doors;
- }
-
- private void loadStructureNbtFile(File localStructuresFolder, BoundingBoxCache cache, String fileName, Color color, String id) {
- File file = new File(localStructuresFolder, fileName);
- NBTTagCompound nbt = loadNbtFile(file);
- if (nbt == null)
- return;
-
- NBTTagCompound features = nbt.getCompoundTag("data")
- .getCompoundTag("Features");
- int loadedStructureCount = 0;
- for (Object key : features.getKeySet()) {
- NBTTagCompound feature = features.getCompoundTag((String) key);
- BoundingBox structure = BoundingBoxStructure.from(feature.getIntArray("BB"), color);
- Set<BoundingBox> boundingBoxes = new HashSet<>();
- NBTTagCompound[] children = getChildCompoundTags(feature, "Children");
- for (NBTTagCompound child : children) {
- if (id.equals(child.getString("id")) || id.equals("*"))
- boundingBoxes.add(BoundingBoxStructure.from(child.getIntArray("BB"), color));
- }
- if (boundingBoxes.size() > 0)
- ++loadedStructureCount;
- cache.addBoundingBoxes(structure, boundingBoxes);
- }
-
- Logger.info("Loaded %s (%d structures with type %s)", fileName, loadedStructureCount, id);
- }
-
- private NBTTagCompound[] getChildCompoundTags(NBTTagCompound parent, String key) {
- NBTTagList tagList = parent.getTagList(key, 10);
- NBTTagCompound[] result = new NBTTagCompound[tagList.tagCount()];
- for (int index = 0; index < tagList.tagCount(); index++) {
- result[index] = tagList.getCompoundTagAt(index);
- }
- return result;
- }
-
- private void loadLevelDat(File localStructuresFolder) {
- File file = new File(localStructuresFolder, "level.dat");
- NBTTagCompound nbt = loadNbtFile(file);
- if (nbt == null)
- return;
-
- NBTTagCompound data = nbt.getCompoundTag("Data");
- long seed = data.getLong("RandomSeed");
- int spawnX = data.getInteger("SpawnX");
- int spawnZ = data.getInteger("SpawnZ");
- setWorldData(new WorldData(seed, spawnX, spawnZ));
- Logger.info("Loaded level.dat (seed: %d, spawn: %d,%d)", worldData.getSeed(), worldData.getSpawnX(), worldData.getSpawnZ());
- }
-
- private NBTTagCompound loadNbtFile(File file) {
- if (!file.exists())
- return null;
- try {
- return CompressedStreamTools.readCompressed(new FileInputStream(file));
- } catch (IOException e) {
- }
- return null;
- }
-
- public void playerDisconnectedFromServer() {
- active = false;
- if (configManager.keepCacheBetweenSessions.getBoolean()) return;
- worldData = null;
- worldSpawnBoundingBox = null;
- spawnChunksBoundingBox = null;
- for (BoundingBoxCache cache : boundingBoxCacheMap.values()) {
- cache.close();
- }
- boundingBoxCacheMap.clear();
- }
-
- private void renderBoundingBoxes(Map<BoundingBox, Set<BoundingBox>> map, Set<BoundingBox> clientBoundingBoxes) {
- if (map == null && clientBoundingBoxes == null)
- return;
-
- 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()) {
- GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
- }
-
- if (map != null)
- for (BoundingBox bb : map.keySet()) {
- if (outerBoxOnly) {
- renderBoundingBoxSet(map.get(bb));
- } else {
- renderBoundingBoxByType(bb);
- }
- }
-
- if (clientBoundingBoxes != null)
- renderBoundingBoxSet(clientBoundingBoxes);
-
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
- GL11.glEnable(GL11.GL_CULL_FACE);
- GL11.glEnable(GL11.GL_TEXTURE_2D);
- }
-
- private void renderBoundingBoxSet(Set<BoundingBox> bbList) {
- if (bbList != null)
- for (BoundingBox bb : bbList) {
- renderBoundingBoxByType(bb);
- }
- }
-
- private void renderBoundingBoxByType(BoundingBox bb) {
- WorldClient world = Minecraft.getMinecraft().world;
- if (!world.isAreaLoaded(bb.getMinBlockPos(), bb.getMaxBlockPos())) {
- return;
- }
-
- if (bb instanceof BoundingBoxVillage) {
- BoundingBoxVillage villageBB = (BoundingBoxVillage) bb;
- if (configManager.renderVillageAsSphere.getBoolean()) {
- renderBoundingBoxVillageAsSphere(villageBB);
- } else {
- renderBoundingBox(villageBB);
- }
- if (configManager.drawIronGolemSpawnArea.getBoolean() &&
- villageBB.getSpawnsIronGolems()) {
- renderIronGolemSpawnArea(villageBB);
- }
- if (configManager.drawVillageDoors.getBoolean())
- renderVillageDoors(villageBB);
- } else if (bb instanceof BoundingBoxSlimeChunk) {
- renderSlimeChunk((BoundingBoxSlimeChunk) bb);
- } else if (bb instanceof BoundingBoxWorldSpawn) {
- renderWorldSpawn((BoundingBoxWorldSpawn) bb);
- } else {
- renderBoundingBox(bb);
- }
- }
-
- private void renderBoundingBox(BoundingBox bb) {
- AxisAlignedBB aaBB = bb.toAxisAlignedBB();
- Color color = bb.getColor();
- renderCuboid(aaBB, color, fill());
- }
-
- private void renderWorldSpawn(BoundingBoxWorldSpawn bb) {
- AxisAlignedBB aaBB = bb.toAxisAlignedBB(false);
- Color color = bb.getColor();
- double y = getMaxY(configManager.worldSpawnMaxY.getInt()) + 0.001F;
- renderRectangle(aaBB, y, y, color, false);
- }
-
- private void renderSlimeChunk(BoundingBoxSlimeChunk bb) {
- AxisAlignedBB aaBB = bb.toAxisAlignedBB();
- Color color = bb.getColor();
- renderCuboid(aaBB, color, fill());
-
- double maxY = getMaxY(configManager.slimeChunkMaxY.getInt());
- if (maxY > 39) {
- renderRectangle(aaBB, 39, maxY, color, fill());
- }
- }
-
- private double getMaxY(double configMaxY) {
- if (configMaxY == -1) {
- return activeY;
- } else if ((configMaxY == 0) || (playerY < configMaxY)) {
- return playerY;
- }
- return configMaxY;
- }
-
- private void renderRectangle(AxisAlignedBB aaBB, double minY, double maxY, Color color, Boolean fill) {
- aaBB = new AxisAlignedBB(aaBB.minX, minY, aaBB.minZ, aaBB.maxX, maxY, aaBB.maxZ);
- renderCuboid(aaBB, color, fill);
- }
-
- private boolean fill() {
- return configManager.fill.getBoolean();
- }
-
- private void renderIronGolemSpawnArea(BoundingBoxVillage villageBB) {
- BlockPos center = villageBB.getCenter();
- AxisAlignedBB abb = new AxisAlignedBB(new BlockPos(center.getX() - 8,
- center.getY() - 3,
- center.getZ() - 8),
- new BlockPos(center.getX() + 8,
- center.getY() + 3,
- center.getZ() + 8))
- .offset(villageBB.getCenterOffsetX(), 0.0, villageBB.getCenterOffsetZ());
-
- renderCuboid(abb, villageBB.getColor(), false);
- }
-
- private void renderVillageDoors(BoundingBoxVillage villageBB) {
- OffsetPoint center = new OffsetPoint(villageBB.getCenter())
- .add(villageBB.getCenterOffsetX(), 0.0, villageBB.getCenterOffsetZ());
- Color color = villageBB.getColor();
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- int colorR = color.getRed();
- int colorG = color.getGreen();
- int colorB = color.getBlue();
-
- worldRenderer.begin(GL11.GL_LINES, worldRenderer.getVertexFormat());
- for (BlockPos door : villageBB.getDoors()) {
- OffsetPoint point = new OffsetPoint(door).add(0.5, 0, 0.5);
-
- worldRenderer.pos(point.getX(), point.getY(), point.getZ()).color(colorR, colorG, colorB, 255).endVertex();
- worldRenderer.pos(center.getX(), center.getY(), center.getZ()).color(colorR, colorG, colorB, 255).endVertex();
- }
- tessellator.draw();
- }
-
- private void renderCuboid(AxisAlignedBB aaBB, Color color, boolean fill) {
- aaBB = offsetAxisAlignedBB(aaBB);
- if (fill) {
- renderFilledCuboid(aaBB, color);
- }
- renderUnfilledCuboid(aaBB, color);
- }
-
- private void renderFilledCuboid(AxisAlignedBB aaBB, Color color) {
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
- GL11.glEnable(GL11.GL_BLEND);
- renderCuboid(aaBB, 30, color);
- GL11.glDisable(GL11.GL_BLEND);
- GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
- GL11.glPolygonOffset(-1.f, -1.f);
- }
-
- private void renderUnfilledCuboid(AxisAlignedBB aaBB, Color color) {
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
- renderCuboid(aaBB, 255, color);
- }
-
- private void renderCuboid(AxisAlignedBB bb, int alphaChannel, Color color) {
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- int colorR = color.getRed();
- int colorG = color.getGreen();
- int colorB = color.getBlue();
-
- worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- if (bb.minY != bb.maxY) {
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- }
- tessellator.draw();
- }
-
- private AxisAlignedBB offsetAxisAlignedBB(AxisAlignedBB axisAlignedBB) {
- double growXZ = 0.001F;
- double growY = 0;
- if (axisAlignedBB.minY != axisAlignedBB.maxY) {
- growY = growXZ;
- }
- return axisAlignedBB
- .grow(growXZ, growY, growXZ)
- .offset(-playerX, -playerY, -playerZ);
- }
-
- private void renderBoundingBoxVillageAsSphere(BoundingBoxVillage bb) {
- OffsetPoint center = new OffsetPoint(bb.getCenter())
- .add(bb.getCenterOffsetX(), 0.0, bb.getCenterOffsetZ());
- ;
- int radius = bb.getRadius();
- Color color = bb.getColor();
- renderSphere(center, radius, color);
- }
-
- private void renderSphere(OffsetPoint center, double radius, Color color) {
- GL11.glEnable(GL11.GL_POINT_SMOOTH);
- GL11.glPointSize(2f);
-
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
- worldRenderer.begin(GL11.GL_POINTS, DefaultVertexFormats.POSITION_COLOR);
- for (OffsetPoint point : buildPoints(center, radius)) {
- worldRenderer.pos(point.getX(), point.getY(), point.getZ())
- .color(color.getRed(), color.getGreen(), color.getBlue(), 255)
- .endVertex();
- }
- tessellator.draw();
- }
-
- private class OffsetPoint {
- private final double x;
- private final double y;
- private final double z;
-
- public OffsetPoint(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- public OffsetPoint(BlockPos blockPos) {
- x = blockPos.getX();
- y = blockPos.getY();
- z = blockPos.getZ();
- }
-
- public double getX() {
- return x - playerX;
- }
-
- public double getY() {
- return y - playerY;
- }
-
- public double getZ() {
- return z - playerZ;
- }
-
- public OffsetPoint add(double x, double y, double z) {
- return new OffsetPoint(this.x + x, this.y + y, this.z + z);
- }
- }
-
- private Set<OffsetPoint> buildPoints(OffsetPoint center, double radius) {
- Set<OffsetPoint> points = new HashSet<>(1200);
-
- double tau = 6.283185307179586D;
- double pi = tau / 2D;
- double segment = tau / 48D;
-
- for (double t = 0.0D; t < tau; t += segment)
- for (double theta = 0.0D; theta < pi; theta += segment) {
- double dx = radius * Math.sin(t) * Math.cos(theta);
- double dz = radius * Math.sin(t) * Math.sin(theta);
- double dy = radius * Math.cos(t);
-
- points.add(center.add(dx, dy, dz));
- }
- return points;
- }
-
- private Set<BoundingBox> getClientBoundingBoxes(DimensionType dimensionType) {
- if (worldData == null || dimensionType != DimensionType.OVERWORLD) {
- return null;
- }
-
- Set<BoundingBox> boundingBoxes = new HashSet<>();
- if (configManager.drawWorldSpawn.getBoolean()) {
- boundingBoxes.add(getWorldSpawnBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
- boundingBoxes.add(getSpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
- }
- if (configManager.drawLazySpawnChunks.getBoolean()) {
- boundingBoxes.add(getLazySpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
- }
- if (configManager.drawSlimeChunks.getBoolean()) {
- boundingBoxes.addAll(this.getSlimeChunks());
- }
- return boundingBoxes;
- }
-
- private Set<BoundingBoxSlimeChunk> getSlimeChunks() {
- Minecraft minecraft = Minecraft.getMinecraft();
- int renderDistanceChunks = minecraft.gameSettings.renderDistanceChunks;
- int playerChunkX = MathHelper.floor(minecraft.player.posX / 16.0D);
- int playerChunkZ = MathHelper.floor(minecraft.player.posZ / 16.0D);
- Set<BoundingBoxSlimeChunk> slimeChunks = new HashSet<>();
- for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; ++chunkX) {
- for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; ++chunkZ) {
- if (isSlimeChunk(chunkX, chunkZ)) {
- ChunkPos chunk = new ChunkPos(chunkX, chunkZ);
- BlockPos minBlockPos = new BlockPos(chunk.getXStart(), 1, chunk.getZStart());
- BlockPos maxBlockPos = new BlockPos(chunk.getXEnd(), 38, chunk.getZEnd());
- if (minecraft.world.isAreaLoaded(minBlockPos, maxBlockPos)) {
- slimeChunks.add(BoundingBoxSlimeChunk.from(minBlockPos, maxBlockPos, Color.GREEN));
- }
- }
- }
- }
- return slimeChunks;
- }
-
- private boolean isSlimeChunk(int chunkX, int chunkZ) {
- Random r = new Random(worldData.getSeed() +
- (long) (chunkX * chunkX * 4987142) +
- (long) (chunkX * 5947611) +
- (long) (chunkZ * chunkZ) * 4392871L +
- (long) (chunkZ * 389711) ^ 987234911L);
- return r.nextInt(10) == 0;
- }
-
- private BoundingBox getSpawnChunksBoundingBox(int spawnX, int spawnZ) {
- if (spawnChunksBoundingBox != null) {
- return spawnChunksBoundingBox;
- }
- BoundingBox boundingBox = getSpawnChunksBoundingBox(spawnX, spawnZ, 12, Color.RED);
- spawnChunksBoundingBox = boundingBox;
- return boundingBox;
- }
-
- private BoundingBox getLazySpawnChunksBoundingBox(int spawnX, int spawnZ) {
- if (lazySpawnChunksBoundingBox != null)
- return lazySpawnChunksBoundingBox;
-
- BoundingBox boundingBox = getSpawnChunksBoundingBox(spawnX, spawnZ, 16, Color.RED);
- lazySpawnChunksBoundingBox = boundingBox;
- return boundingBox;
- }
-
- private BoundingBox getSpawnChunksBoundingBox(int spawnX, int spawnZ, int size, Color color) {
- double chunkSize = 16;
- double midOffset = chunkSize * (size / 2);
- double midX = Math.round((float) (spawnX / chunkSize)) * chunkSize;
- double midZ = Math.round((float) (spawnZ / chunkSize)) * chunkSize;
- BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
- if (spawnX / chunkSize % 0.5D == 0.0D && spawnZ / chunkSize % 0.5D == 0.0D) {
- midX += chunkSize;
- midZ += chunkSize;
- }
- BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
- return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, color);
- }
-
- private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
- if (worldSpawnBoundingBox != null)
- return worldSpawnBoundingBox;
-
- BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
- BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
-
- BoundingBox boundingBox = BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, Color.RED);
- worldSpawnBoundingBox = boundingBox;
- return boundingBox;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.world.DimensionType;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-import net.minecraft.world.chunk.IChunkProvider;
-import net.minecraft.world.gen.ChunkProviderServer;
-import net.minecraft.world.gen.IChunkGenerator;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class CommonProxy {
- public Map<DimensionType, BoundingBoxCache> boundingBoxCacheMap = new ConcurrentHashMap<>();
-
- public ConfigManager configManager;
- protected WorldData worldData;
- private IEventHandler eventHandler = null;
-
- public void init(ConfigManager configManager) {
- this.configManager = configManager;
- }
-
- public void worldLoaded(World world) {
- IChunkProvider chunkProvider = world.getChunkProvider();
- if (chunkProvider instanceof ChunkProviderServer) {
- IChunkGenerator chunkGenerator = ReflectionHelper.getPrivateValue(ChunkProviderServer.class, (ChunkProviderServer) chunkProvider, IChunkGenerator.class);
- setWorldData(new WorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ()));
- DimensionType dimensionType = world.provider.getDimensionType();
- Logger.info("create world dimension: %s, %s (chunkprovider: %s) (seed: %d)", dimensionType, world.getClass().toString(), chunkGenerator.getClass().toString(), worldData.getSeed());
- boundingBoxCacheMap.put(dimensionType, new DimensionProcessor(eventHandler, configManager, world, dimensionType, chunkGenerator));
- }
- }
-
- public void chunkLoaded(Chunk chunk) {
- DimensionType dimensionType = chunk.getWorld().provider.getDimensionType();
- if (boundingBoxCacheMap.containsKey(dimensionType)) {
- boundingBoxCacheMap.get(dimensionType).refresh();
- }
- }
-
- public WorldData getWorldData() {
- return worldData;
- }
-
- public void setWorldData(WorldData worldData) {
- this.worldData = worldData;
- }
-
- public void setEventHandler(IEventHandler eventHandler) {
- this.eventHandler = eventHandler;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import com.irtimaled.bbor.config.Configuration;
-import com.irtimaled.bbor.config.Setting;
-
-import java.io.File;
-
-public class ConfigManager {
- public final File configDir;
-
- public Setting fill;
- public Setting drawVillages;
- public Setting drawDesertTemples;
- public Setting drawJungleTemples;
- public Setting drawWitchHuts;
- public Setting drawStrongholds;
- public Setting drawMineShafts;
- public Setting drawNetherFortresses;
- public Setting drawOceanMonuments;
- public Setting alwaysVisible;
- public Setting renderVillageAsSphere;
- public Setting drawIronGolemSpawnArea;
- public Setting drawVillageDoors;
- public Setting drawSlimeChunks;
- public Setting slimeChunkMaxY;
- public Setting keepCacheBetweenSessions;
- public Setting drawWorldSpawn;
- public Setting worldSpawnMaxY;
- public Setting drawLazySpawnChunks;
- public Setting drawEndCities;
- public Setting drawMansions;
-
- private Configuration config;
-
- public ConfigManager(File configDir) {
- this.configDir = configDir;
- config = new Configuration(new File(configDir, "BBOutlineReloaded.cfg"));
- config.load();
-
- fill = SetupBooleanProperty(config, "general", "fill", true, "If set to true the bounding boxes are filled. (default: true)");
- alwaysVisible = SetupBooleanProperty(config, "general", "alwaysVisible", false, "If set to true boxes will be visible even through other blocks. (default: false)");
- keepCacheBetweenSessions = SetupBooleanProperty(config, "general", "keepCacheBetweenSessions", false, "If set to true bounding box caches will be kept between sessions. (default: false)");
- drawVillages = SetupBooleanProperty(config, "features", "drawVillages", true, "If set to true village bounding boxes are drawn. (default: true)");
- renderVillageAsSphere = SetupBooleanProperty(config, "features", "renderVillageAsSphere", true, "If set to true villages will be drawn as a sphere. (default:true)");
- drawIronGolemSpawnArea = SetupBooleanProperty(config, "features", "drawIronGolemSpawnArea", true, "If set to true the iron golem spawn area of the village will be drawn. (default:true)");
- drawVillageDoors = SetupBooleanProperty(config, "features", "drawVillageDoors", false, "If set to true lines between the village centre and doors will be drawn. (default:false)");
- drawDesertTemples = SetupBooleanProperty(config, "features", "drawDesertTemples", true, "If set to true desert temple bounding boxes are drawn. (default: true)");
- drawJungleTemples = SetupBooleanProperty(config, "features", "drawJungleTemples", true, "If set to true jungle temple bounding boxes are drawn. (default: true)");
- drawWitchHuts = SetupBooleanProperty(config, "features", "drawWitchHuts", true, "If set to true witch hut bounding boxes are drawn. (default: true)");
- drawStrongholds = SetupBooleanProperty(config, "features", "drawStrongholds", false, "If set to true stronghold bounding boxes are drawn. (default: false)");
- drawMineShafts = SetupBooleanProperty(config, "features", "drawMineShafts", false, "If set to true mineshaft bounding boxes are drawn. (default: false)");
- drawNetherFortresses = SetupBooleanProperty(config, "features", "drawNetherFortresses", true, "If set to true nether fortress bounding boxes are drawn. (default: true)");
- drawOceanMonuments = SetupBooleanProperty(config, "features", "drawOceanMonuments", true, "If set to true ocean monument bounding boxes are drawn. (default: true)");
- drawSlimeChunks = SetupBooleanProperty(config, "features", "drawSlimeChunks", true, "If set to true slime chunks bounding boxes are drawn. (default: true)");
- slimeChunkMaxY = SetupIntegerProperty(config, "features", "slimeChunkMaxY", -1, "The maximum top of the slime chunk bounding box. If set to -1 it will use the value when activated, if set to 0 it will always track the player's feet. (default: -1)");
- drawWorldSpawn = SetupBooleanProperty(config, "features", "drawWorldSpawn", true, "If set to true world spawn and spawn chunks bounding boxes are drawn. (default: true)");
- worldSpawnMaxY = SetupIntegerProperty(config, "features", "worldSpawnMaxY", -1, "The maximum top of the world spawn bounding boxes. If set to -1 it will use the value when activated, if set to 0 it will always track the players feet. (default: -1)");
- drawLazySpawnChunks = SetupBooleanProperty(config, "features", "drawLazySpawnChunks", false, "If set to true the lazy spawn chunks bounding boxes will be drawn. (default: false)");
- drawEndCities = SetupBooleanProperty(config, "features", "drawEndCities", true, "If set to true end city bounding boxes will be drawn. (default: true)");
- drawMansions = SetupBooleanProperty(config, "features", "drawMansions", true, "If set to true woodland mansions will be drawn. (default: true)");
- config.save();
- }
-
- private Setting SetupBooleanProperty(Configuration config, String category, String settingName, Boolean defaultValue, String comment) {
- Setting property = config.get(category, settingName, defaultValue);
- property.comment = comment;
- property.set(property.getBoolean(defaultValue));
- return property;
- }
-
- private Setting SetupIntegerProperty(Configuration config, String category, String settingName, int defaultValue, String comment) {
- Setting property = config.get(category, settingName, defaultValue);
- property.comment = comment;
- property.set(property.getInt(defaultValue));
- return property;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.ChunkPos;
-import net.minecraft.village.Village;
-import net.minecraft.village.VillageDoorInfo;
-import net.minecraft.world.DimensionType;
-import net.minecraft.world.World;
-import net.minecraft.world.gen.ChunkGeneratorEnd;
-import net.minecraft.world.gen.ChunkGeneratorHell;
-import net.minecraft.world.gen.ChunkGeneratorOverworld;
-import net.minecraft.world.gen.IChunkGenerator;
-import net.minecraft.world.gen.structure.*;
-
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-
-public class DimensionProcessor extends BoundingBoxCache {
- private ConfigManager configManager;
- private World world;
- private IEventHandler eventHandler;
-
- public DimensionProcessor(IEventHandler eventHandler, ConfigManager configManager, World world, DimensionType dimensionType, IChunkGenerator chunkGenerator) {
- this.eventHandler = eventHandler;
- this.configManager = configManager;
- this.world = world;
- this.dimensionType = dimensionType;
- this.chunkGenerator = chunkGenerator;
- villageCache = new HashMap<>();
- slimeChunkCache = new HashSet<>();
- worldSpawnCache = new HashSet<>();
- }
-
- private DimensionType dimensionType;
- private IChunkGenerator chunkGenerator;
- private Map<Integer, BoundingBoxVillage> villageCache;
- private Set<BoundingBox> slimeChunkCache;
- private Set<BoundingBox> worldSpawnCache;
-
- private boolean closed = false;
-
- @Override
- public void close() {
- closed = true;
- chunkGenerator = null;
- villageCache.clear();
- slimeChunkCache.clear();
- worldSpawnCache.clear();
- super.close();
- }
-
- private static <T extends IChunkGenerator, R extends MapGenStructure> Collection<StructureStart> getStructures(T chunkGenerator, Class<R> generatorClass) {
- Class<T> chunkGeneratorClass = (Class<T>) chunkGenerator.getClass();
- R structureGenerator = ReflectionHelper.getPrivateValue(chunkGeneratorClass, chunkGenerator, generatorClass);
- if (structureGenerator != null) {
- Map<ChunkPos, StructureStart> structureMap = ReflectionHelper.getPrivateValue(MapGenStructure.class, structureGenerator, Map.class);
- return structureMap.values();
- }
- return Collections.emptyList();
- }
-
- private Map<StructureType, Collection<StructureStart>> getStructures() {
- Map<StructureType, Collection<StructureStart>> structureMap = new HashMap<>();
- if (chunkGenerator instanceof ChunkGeneratorOverworld) {
- if (configManager.drawDesertTemples.getBoolean()) {
- structureMap.put(StructureType.DesertTemple, getStructuresWithComponent(getStructures(chunkGenerator, MapGenScatteredFeature.class), ComponentScatteredFeaturePieces.DesertPyramid.class));
- }
-
- if (configManager.drawJungleTemples.getBoolean()) {
- structureMap.put(StructureType.JungleTemple, getStructuresWithComponent(getStructures(chunkGenerator, MapGenScatteredFeature.class), ComponentScatteredFeaturePieces.JunglePyramid.class));
- }
-
- if (configManager.drawWitchHuts.getBoolean()) {
- structureMap.put(StructureType.WitchHut, getStructuresWithComponent(getStructures(chunkGenerator, MapGenScatteredFeature.class), ComponentScatteredFeaturePieces.SwampHut.class));
- }
-
- if (configManager.drawOceanMonuments.getBoolean()) {
- structureMap.put(StructureType.OceanMonument, getStructures(chunkGenerator, StructureOceanMonument.class));
- }
-
- if (configManager.drawStrongholds.getBoolean()) {
- structureMap.put(StructureType.Stronghold, getStructures(chunkGenerator, MapGenStronghold.class));
- }
-
- if (configManager.drawMansions.getBoolean()) {
- structureMap.put(StructureType.Mansion, getStructures(chunkGenerator, WoodlandMansion.class));
- }
-
- if (configManager.drawMineShafts.getBoolean()) {
- structureMap.put(StructureType.MineShaft, getStructures(chunkGenerator, MapGenMineshaft.class));
- }
- } else if (chunkGenerator instanceof ChunkGeneratorHell) {
- if (configManager.drawNetherFortresses.getBoolean()) {
- structureMap.put(StructureType.NetherFortress, getStructures(chunkGenerator, MapGenNetherBridge.class));
- }
- } else if (chunkGenerator instanceof ChunkGeneratorEnd) {
- if (configManager.drawEndCities.getBoolean()) {
- structureMap.put(StructureType.EndCity, getStructures(chunkGenerator, MapGenEndCity.class));
- }
- }
-
- return structureMap;
- }
-
- private Collection<StructureStart> getStructuresWithComponent(Collection<StructureStart> structures, Class structureComponent) {
- Collection<StructureStart> validStructures = new HashSet<>();
- for (StructureStart structure : structures) {
- if (structure.getComponents().get(0).getClass().equals(structureComponent)) {
- validStructures.add(structure);
- }
- }
- return validStructures;
- }
-
- @Override
- public synchronized void refresh() {
- if (closed) return;
-
- Map<StructureType, Collection<StructureStart>> structureMap = getStructures();
- for (StructureType structureType : structureMap.keySet()) {
- Color color = structureType.getColor();
- for (StructureStart structureStart : structureMap.get(structureType)) {
- if (structureStart.getBoundingBox() != null) {
- BoundingBox boundingBox = BoundingBoxStructure.from(structureStart.getBoundingBox(), color);
- if (!isCached(boundingBox)) {
- Set<BoundingBox> structureBoundingBoxes = new HashSet<>();
- for (StructureComponent structureComponent : structureStart.getComponents()) {
- structureBoundingBoxes.add(BoundingBoxStructure.from(structureComponent.getBoundingBox(), color));
- }
- addBoundingBoxes(boundingBox, structureBoundingBoxes);
- Logger.info("[%s] new boundingBoxCacheMap entries: %d", dimensionType, structureBoundingBoxes.size());
- }
- }
- }
- }
-
- if (configManager.drawVillages.getBoolean() &&
- world.getVillageCollection() != null) {
- Map<Integer, BoundingBoxVillage> villageBoundingBoxes = new HashMap<>();
- List<Village> villages = world.getVillageCollection().getVillageList();
- for (Village village : villages) {
- int villageId = village.hashCode();
- BlockPos center = village.getCenter();
- Color color = null;
- if (villageCache.containsKey(villageId)) {
- BoundingBoxVillage boundingBoxVillage = villageCache.get(villageId);
- if (boundingBoxVillage.getCenter() == center) {
- villageBoundingBoxes.put(villageId, boundingBoxVillage);
- villageCache.remove(villageId);
- continue;
- }
- color = boundingBoxVillage.getColor();
- }
-
- Integer radius = village.getVillageRadius();
- int population = village.getNumVillagers();
- Set<BlockPos> doors = getDoorsFromVillage(village);
- villageBoundingBoxes.put(villageId, BoundingBoxVillage.from(center, radius, color, population, doors));
- }
- processDelta(villageCache, villageBoundingBoxes);
- villageCache = villageBoundingBoxes;
- }
- }
-
- private Set<BlockPos> getDoorsFromVillage(Village village) {
- Set<BlockPos> doors = new HashSet<>();
- for (Object doorInfo : village.getVillageDoorInfoList()) {
- VillageDoorInfo villageDoorInfo = (VillageDoorInfo) doorInfo;
- doors.add(villageDoorInfo.getDoorBlockPos());
- }
- return doors;
- }
-
- private void processDelta(Map<Integer, BoundingBoxVillage> oldVillages, Map<Integer, BoundingBoxVillage> newVillages) {
- for (BoundingBox village : oldVillages.values()) {
- removeBoundingBox(village);
- if (eventHandler != null) {
- eventHandler.boundingBoxRemoved(this.dimensionType, village);
- }
- }
- for (BoundingBox village : newVillages.values()) {
- if (!isCached(village))
- addBoundingBox(village);
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import net.minecraft.world.DimensionType;
-
-public interface IEventHandler {
- void boundingBoxRemoved(DimensionType dimensionType, BoundingBox bb);
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import java.awt.*;
-
-public class StructureType {
- private static final int JUNGLE_TEMPLE = 1;
- private static final int DESERT_TEMPLE = 2;
- private static final int WITCH_HUT = 3;
- private static final int OCEAN_MONUMENT = 4;
- private static final int STRONGHOLD = 5;
- private static final int MINE_SHAFT = 6;
- private static final int NETHER_FORTRESS = 7;
- private static final int END_CITY = 8;
- private static final int MANSION = 9;
-
- public final static StructureType JungleTemple = new StructureType(JUNGLE_TEMPLE);
- public final static StructureType DesertTemple = new StructureType(DESERT_TEMPLE);
- public final static StructureType WitchHut = new StructureType(WITCH_HUT);
- public final static StructureType OceanMonument = new StructureType(OCEAN_MONUMENT);
- public final static StructureType Stronghold = new StructureType(STRONGHOLD);
- public final static StructureType MineShaft = new StructureType(MINE_SHAFT);
- public final static StructureType NetherFortress = new StructureType(NETHER_FORTRESS);
- public final static StructureType EndCity = new StructureType(END_CITY);
- public final static StructureType Mansion = new StructureType(MANSION);
-
- private final int type;
-
- private StructureType(int type) {
- this.type = type;
- }
-
- public Color getColor() {
- switch (type) {
- case DESERT_TEMPLE:
- return Color.ORANGE;
- case JUNGLE_TEMPLE:
- return Color.GREEN;
- case WITCH_HUT:
- return Color.BLUE;
- case MINE_SHAFT:
- return Color.LIGHT_GRAY;
- case NETHER_FORTRESS:
- return Color.RED;
- case OCEAN_MONUMENT:
- return Color.CYAN;
- case STRONGHOLD:
- return Color.YELLOW;
- case END_CITY:
- return Color.MAGENTA;
- case MANSION:
- return new Color(139, 69, 19);
- }
- return Color.WHITE;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-public class WorldData {
- private long seed;
- private int spawnX;
- private int spawnZ;
-
- public WorldData(long seed, int spawnX, int spawnZ) {
- this.seed = seed;
- this.spawnX = spawnX;
- this.spawnZ = spawnZ;
- }
-
- public long getSeed() {
- return seed;
- }
-
- public int getSpawnX() {
- return spawnX;
- }
-
- public int getSpawnZ() {
- return spawnZ;
- }
-}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+
+import java.io.File;
+
+public class BoundingBoxOutlineReloaded {
+ public static ClientProxy proxy;
+
+ public static void init() {
+ proxy = new ClientProxy();
+ proxy.init(new ConfigManager(new File(Minecraft.getMinecraft().mcDataDir, "config")));
+ }
+
+ public static void chunkLoaded(Chunk chunk) {
+ proxy.chunkLoaded(chunk);
+ }
+
+ public static void worldLoaded(World world) {
+ proxy.worldLoaded(world);
+ }
+
+ public static void keyPressed() {
+ proxy.keyPressed();
+ }
+
+ public static void render(float partialTicks) {
+ proxy.render(partialTicks);
+ }
+
+ public static void playerConnectedToServer(NetworkManager networkManager) {
+ proxy.playerConnectedToServer(networkManager);
+ }
+
+ public static void playerDisconnectedFromServer() {
+ proxy.playerDisconnectedFromServer();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.common.BoundingBoxCache;
+import com.irtimaled.bbor.common.CommonProxy;
+import com.irtimaled.bbor.common.StructureType;
+import com.irtimaled.bbor.common.models.*;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.multiplayer.WorldClient;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.client.settings.KeyBinding;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.world.DimensionType;
+import org.apache.commons.lang3.ArrayUtils;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+public class ClientProxy extends CommonProxy {
+ private double activeY;
+ private boolean active;
+ private boolean outerBoxOnly;
+ private KeyBinding activeHotKey;
+ private KeyBinding outerBoxOnlyHotKey;
+ private double playerX;
+ private double playerY;
+ private double playerZ;
+ private BoundingBox worldSpawnBoundingBox;
+ private BoundingBox spawnChunksBoundingBox;
+ private BoundingBox lazySpawnChunksBoundingBox;
+
+ public void keyPressed() {
+ if (activeHotKey.isPressed()) {
+ active = !active;
+ if (active)
+ activeY = playerY;
+ } else if (outerBoxOnlyHotKey.isPressed()) {
+ outerBoxOnly = !outerBoxOnly;
+ }
+ }
+
+ @Override
+ public void init(ConfigManager configManager) {
+ super.init(configManager);
+ String category = "Bounding Box Outline Reloaded";
+ activeHotKey = new KeyBinding("Toggle On/Off", Keyboard.KEY_B, category);
+ outerBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", Keyboard.KEY_O, category);
+ Minecraft.getMinecraft().gameSettings.keyBindings = ArrayUtils.addAll(Minecraft.getMinecraft().gameSettings.keyBindings, activeHotKey, outerBoxOnlyHotKey);
+ }
+
+ @Override
+ public void setWorldData(WorldData worldData) {
+ worldSpawnBoundingBox = null;
+ spawnChunksBoundingBox = null;
+ lazySpawnChunksBoundingBox = null;
+ super.setWorldData(worldData);
+ }
+
+ public void render(float partialTicks) {
+ EntityPlayer entityPlayer = Minecraft.getMinecraft().player;
+ playerX = entityPlayer.lastTickPosX + (entityPlayer.posX - entityPlayer.lastTickPosX) * (double) partialTicks;
+ playerY = entityPlayer.lastTickPosY + (entityPlayer.posY - entityPlayer.lastTickPosY) * (double) partialTicks;
+ playerZ = entityPlayer.lastTickPosZ + (entityPlayer.posZ - entityPlayer.lastTickPosZ) * (double) partialTicks;
+
+ if (this.active) {
+ DimensionType dimensionType = DimensionType.getById(entityPlayer.dimension);
+ Map<BoundingBox, Set<BoundingBox>> boundingBoxes = null;
+ if (boundingBoxCacheMap.containsKey(dimensionType)) {
+ boundingBoxes = boundingBoxCacheMap.get(dimensionType).getBoundingBoxes();
+ }
+ renderBoundingBoxes(boundingBoxes, getClientBoundingBoxes(dimensionType));
+ }
+ }
+
+ public void playerConnectedToServer(NetworkManager networkManager) {
+ SocketAddress remoteAddress = networkManager.getRemoteAddress();
+ if (remoteAddress instanceof InetSocketAddress) {
+ InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress;
+ loadLocalStructures(socketAddress.getHostName(), socketAddress.getPort());
+ }
+ }
+
+ private void loadLocalStructures(String host, int port) {
+ Logger.info("Looking for local structures (host:port=%s:%d)", host, port);
+ String path = String.format("BBOutlineReloaded%s%s%s%d", File.separator, host, File.separator, port);
+ File localStructuresFolder = new File(configManager.configDir, path);
+ Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
+ if (!localStructuresFolder.exists()) {
+ path = String.format("BBOutlineReloaded%s%s", File.separator, host);
+ localStructuresFolder = new File(configManager.configDir, path);
+ Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
+ }
+ if (!localStructuresFolder.exists()) {
+ path = String.format("BBOutlineReloaded%s%s,%d", File.separator, host, port);
+ localStructuresFolder = new File(configManager.configDir, path);
+ Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
+ }
+ if (!localStructuresFolder.exists()) {
+ Logger.info("No local structures folders found");
+ return;
+ }
+ loadLevelDat(localStructuresFolder);
+ loadNetherStructures(localStructuresFolder);
+ loadOverworldStructures(localStructuresFolder);
+ loadEndStructures(localStructuresFolder);
+ }
+
+ private void loadOverworldStructures(File localStructuresFolder) {
+ BoundingBoxCache cache = new BoundingBoxCache();
+ if (configManager.drawDesertTemples.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Temple.dat", StructureType.DesertTemple.getColor(), "TeDP");
+ }
+ if (configManager.drawJungleTemples.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Temple.dat", StructureType.JungleTemple.getColor(), "TeJP");
+ }
+ if (configManager.drawWitchHuts.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Temple.dat", StructureType.WitchHut.getColor(), "TeSH");
+ }
+ if (configManager.drawOceanMonuments.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Monument.dat", StructureType.OceanMonument.getColor(), "*");
+ }
+ if (configManager.drawStrongholds.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Stronghold.dat", StructureType.Stronghold.getColor(), "*");
+ }
+ if (configManager.drawMansions.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Mansion.dat", StructureType.Mansion.getColor(), "*");
+ }
+ if (configManager.drawMineShafts.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "Mineshaft.dat", StructureType.MineShaft.getColor(), "*");
+ }
+ if (configManager.drawVillages.getBoolean()) {
+ loadVillageNbtFile(localStructuresFolder, cache, "Villages.dat");
+ }
+
+ boundingBoxCacheMap.put(DimensionType.OVERWORLD, cache);
+ }
+
+ private void loadNetherStructures(File localStructuresFolder) {
+ BoundingBoxCache cache = new BoundingBoxCache();
+ if (configManager.drawNetherFortresses.getBoolean())
+ loadStructureNbtFile(localStructuresFolder, cache, "Fortress.dat", StructureType.NetherFortress.getColor(), "*");
+ if (configManager.drawVillages.getBoolean()) {
+ loadVillageNbtFile(localStructuresFolder, cache, "villages_nether.dat");
+ }
+ boundingBoxCacheMap.put(DimensionType.NETHER, cache);
+ }
+
+ private void loadEndStructures(File localStructuresFolder) {
+ BoundingBoxCache cache = new BoundingBoxCache();
+ if (configManager.drawVillages.getBoolean()) {
+ loadVillageNbtFile(localStructuresFolder, cache, "Villages_end.dat");
+ }
+ if (configManager.drawEndCities.getBoolean()) {
+ loadStructureNbtFile(localStructuresFolder, cache, "EndCity.dat", StructureType.EndCity.getColor(), "*");
+ }
+ boundingBoxCacheMap.put(DimensionType.THE_END, cache);
+ }
+
+ private void loadVillageNbtFile(File localStructuresFolder, BoundingBoxCache cache, String fileName) {
+ File file = new File(localStructuresFolder, fileName);
+ NBTTagCompound nbt = loadNbtFile(file);
+ if (nbt == null)
+ return;
+
+ NBTTagCompound[] villages = getChildCompoundTags(nbt.getCompoundTag("data"), "Villages");
+ for (NBTTagCompound village : villages) {
+ BlockPos center = new BlockPos(village.getInteger("CX"), village.getInteger("CY"), village.getInteger("CZ"));
+ int radius = village.getInteger("Radius");
+ int population = village.getInteger("PopSize");
+ Set<BlockPos> doors = getDoors(village);
+ BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, population, doors);
+ cache.addBoundingBox(boundingBox);
+ }
+
+ Logger.info("Loaded %s (%d villages)", fileName, villages.length);
+ }
+
+ private Set<BlockPos> getDoors(NBTTagCompound village) {
+ Set<BlockPos> doors = new HashSet<>();
+ for (NBTTagCompound door : getChildCompoundTags(village, "Doors")) {
+ doors.add(new BlockPos(door.getInteger("X"), door.getInteger("Y"), door.getInteger("Z")));
+ }
+ return doors;
+ }
+
+ private void loadStructureNbtFile(File localStructuresFolder, BoundingBoxCache cache, String fileName, Color color, String id) {
+ File file = new File(localStructuresFolder, fileName);
+ NBTTagCompound nbt = loadNbtFile(file);
+ if (nbt == null)
+ return;
+
+ NBTTagCompound features = nbt.getCompoundTag("data")
+ .getCompoundTag("Features");
+ int loadedStructureCount = 0;
+ for (Object key : features.getKeySet()) {
+ NBTTagCompound feature = features.getCompoundTag((String) key);
+ BoundingBox structure = BoundingBoxStructure.from(feature.getIntArray("BB"), color);
+ Set<BoundingBox> boundingBoxes = new HashSet<>();
+ NBTTagCompound[] children = getChildCompoundTags(feature, "Children");
+ for (NBTTagCompound child : children) {
+ if (id.equals(child.getString("id")) || id.equals("*"))
+ boundingBoxes.add(BoundingBoxStructure.from(child.getIntArray("BB"), color));
+ }
+ if (boundingBoxes.size() > 0)
+ ++loadedStructureCount;
+ cache.addBoundingBoxes(structure, boundingBoxes);
+ }
+
+ Logger.info("Loaded %s (%d structures with type %s)", fileName, loadedStructureCount, id);
+ }
+
+ private NBTTagCompound[] getChildCompoundTags(NBTTagCompound parent, String key) {
+ NBTTagList tagList = parent.getTagList(key, 10);
+ NBTTagCompound[] result = new NBTTagCompound[tagList.tagCount()];
+ for (int index = 0; index < tagList.tagCount(); index++) {
+ result[index] = tagList.getCompoundTagAt(index);
+ }
+ return result;
+ }
+
+ private void loadLevelDat(File localStructuresFolder) {
+ File file = new File(localStructuresFolder, "level.dat");
+ NBTTagCompound nbt = loadNbtFile(file);
+ if (nbt == null)
+ return;
+
+ NBTTagCompound data = nbt.getCompoundTag("Data");
+ long seed = data.getLong("RandomSeed");
+ int spawnX = data.getInteger("SpawnX");
+ int spawnZ = data.getInteger("SpawnZ");
+ setWorldData(new WorldData(seed, spawnX, spawnZ));
+ Logger.info("Loaded level.dat (seed: %d, spawn: %d,%d)", worldData.getSeed(), worldData.getSpawnX(), worldData.getSpawnZ());
+ }
+
+ private NBTTagCompound loadNbtFile(File file) {
+ if (!file.exists())
+ return null;
+ try {
+ return CompressedStreamTools.readCompressed(new FileInputStream(file));
+ } catch (IOException e) {
+ }
+ return null;
+ }
+
+ public void playerDisconnectedFromServer() {
+ active = false;
+ if (configManager.keepCacheBetweenSessions.getBoolean()) return;
+ worldData = null;
+ worldSpawnBoundingBox = null;
+ spawnChunksBoundingBox = null;
+ for (BoundingBoxCache cache : boundingBoxCacheMap.values()) {
+ cache.close();
+ }
+ boundingBoxCacheMap.clear();
+ }
+
+ private void renderBoundingBoxes(Map<BoundingBox, Set<BoundingBox>> map, Set<BoundingBox> clientBoundingBoxes) {
+ if (map == null && clientBoundingBoxes == null)
+ return;
+
+ 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()) {
+ GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
+ }
+
+ if (map != null)
+ for (BoundingBox bb : map.keySet()) {
+ if (outerBoxOnly) {
+ renderBoundingBoxSet(map.get(bb));
+ } else {
+ renderBoundingBoxByType(bb);
+ }
+ }
+
+ if (clientBoundingBoxes != null)
+ renderBoundingBoxSet(clientBoundingBoxes);
+
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+ GL11.glEnable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ }
+
+ private void renderBoundingBoxSet(Set<BoundingBox> bbList) {
+ if (bbList != null)
+ for (BoundingBox bb : bbList) {
+ renderBoundingBoxByType(bb);
+ }
+ }
+
+ private void renderBoundingBoxByType(BoundingBox bb) {
+ WorldClient world = Minecraft.getMinecraft().world;
+ if (!world.isAreaLoaded(bb.getMinBlockPos(), bb.getMaxBlockPos())) {
+ return;
+ }
+
+ if (bb instanceof BoundingBoxVillage) {
+ BoundingBoxVillage villageBB = (BoundingBoxVillage) bb;
+ if (configManager.renderVillageAsSphere.getBoolean()) {
+ renderBoundingBoxVillageAsSphere(villageBB);
+ } else {
+ renderBoundingBox(villageBB);
+ }
+ if (configManager.drawIronGolemSpawnArea.getBoolean() &&
+ villageBB.getSpawnsIronGolems()) {
+ renderIronGolemSpawnArea(villageBB);
+ }
+ if (configManager.drawVillageDoors.getBoolean())
+ renderVillageDoors(villageBB);
+ } else if (bb instanceof BoundingBoxSlimeChunk) {
+ renderSlimeChunk((BoundingBoxSlimeChunk) bb);
+ } else if (bb instanceof BoundingBoxWorldSpawn) {
+ renderWorldSpawn((BoundingBoxWorldSpawn) bb);
+ } else {
+ renderBoundingBox(bb);
+ }
+ }
+
+ private void renderBoundingBox(BoundingBox bb) {
+ AxisAlignedBB aaBB = bb.toAxisAlignedBB();
+ Color color = bb.getColor();
+ renderCuboid(aaBB, color, fill());
+ }
+
+ private void renderWorldSpawn(BoundingBoxWorldSpawn bb) {
+ AxisAlignedBB aaBB = bb.toAxisAlignedBB(false);
+ Color color = bb.getColor();
+ double y = getMaxY(configManager.worldSpawnMaxY.getInt()) + 0.001F;
+ renderRectangle(aaBB, y, y, color, false);
+ }
+
+ private void renderSlimeChunk(BoundingBoxSlimeChunk bb) {
+ AxisAlignedBB aaBB = bb.toAxisAlignedBB();
+ Color color = bb.getColor();
+ renderCuboid(aaBB, color, fill());
+
+ double maxY = getMaxY(configManager.slimeChunkMaxY.getInt());
+ if (maxY > 39) {
+ renderRectangle(aaBB, 39, maxY, color, fill());
+ }
+ }
+
+ private double getMaxY(double configMaxY) {
+ if (configMaxY == -1) {
+ return activeY;
+ } else if ((configMaxY == 0) || (playerY < configMaxY)) {
+ return playerY;
+ }
+ return configMaxY;
+ }
+
+ private void renderRectangle(AxisAlignedBB aaBB, double minY, double maxY, Color color, Boolean fill) {
+ aaBB = new AxisAlignedBB(aaBB.minX, minY, aaBB.minZ, aaBB.maxX, maxY, aaBB.maxZ);
+ renderCuboid(aaBB, color, fill);
+ }
+
+ private boolean fill() {
+ return configManager.fill.getBoolean();
+ }
+
+ private void renderIronGolemSpawnArea(BoundingBoxVillage villageBB) {
+ BlockPos center = villageBB.getCenter();
+ AxisAlignedBB abb = new AxisAlignedBB(new BlockPos(center.getX() - 8,
+ center.getY() - 3,
+ center.getZ() - 8),
+ new BlockPos(center.getX() + 8,
+ center.getY() + 3,
+ center.getZ() + 8))
+ .offset(villageBB.getCenterOffsetX(), 0.0, villageBB.getCenterOffsetZ());
+
+ renderCuboid(abb, villageBB.getColor(), false);
+ }
+
+ private void renderVillageDoors(BoundingBoxVillage villageBB) {
+ OffsetPoint center = new OffsetPoint(villageBB.getCenter())
+ .add(villageBB.getCenterOffsetX(), 0.0, villageBB.getCenterOffsetZ());
+ Color color = villageBB.getColor();
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+
+ int colorR = color.getRed();
+ int colorG = color.getGreen();
+ int colorB = color.getBlue();
+
+ worldRenderer.begin(GL11.GL_LINES, worldRenderer.getVertexFormat());
+ for (BlockPos door : villageBB.getDoors()) {
+ OffsetPoint point = new OffsetPoint(door).add(0.5, 0, 0.5);
+
+ worldRenderer.pos(point.getX(), point.getY(), point.getZ()).color(colorR, colorG, colorB, 255).endVertex();
+ worldRenderer.pos(center.getX(), center.getY(), center.getZ()).color(colorR, colorG, colorB, 255).endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private void renderCuboid(AxisAlignedBB aaBB, Color color, boolean fill) {
+ aaBB = offsetAxisAlignedBB(aaBB);
+ if (fill) {
+ renderFilledCuboid(aaBB, color);
+ }
+ renderUnfilledCuboid(aaBB, color);
+ }
+
+ private void renderFilledCuboid(AxisAlignedBB aaBB, Color color) {
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+ GL11.glEnable(GL11.GL_BLEND);
+ renderCuboid(aaBB, 30, color);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
+ GL11.glPolygonOffset(-1.f, -1.f);
+ }
+
+ private void renderUnfilledCuboid(AxisAlignedBB aaBB, Color color) {
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
+ renderCuboid(aaBB, 255, color);
+ }
+
+ private void renderCuboid(AxisAlignedBB bb, int alphaChannel, Color color) {
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+
+ int colorR = color.getRed();
+ int colorG = color.getGreen();
+ int colorB = color.getBlue();
+
+ worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ if (bb.minY != bb.maxY) {
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private AxisAlignedBB offsetAxisAlignedBB(AxisAlignedBB axisAlignedBB) {
+ double growXZ = 0.001F;
+ double growY = 0;
+ if (axisAlignedBB.minY != axisAlignedBB.maxY) {
+ growY = growXZ;
+ }
+ return axisAlignedBB
+ .grow(growXZ, growY, growXZ)
+ .offset(-playerX, -playerY, -playerZ);
+ }
+
+ private void renderBoundingBoxVillageAsSphere(BoundingBoxVillage bb) {
+ OffsetPoint center = new OffsetPoint(bb.getCenter())
+ .add(bb.getCenterOffsetX(), 0.0, bb.getCenterOffsetZ());
+ ;
+ int radius = bb.getRadius();
+ Color color = bb.getColor();
+ renderSphere(center, radius, color);
+ }
+
+ private void renderSphere(OffsetPoint center, double radius, Color color) {
+ GL11.glEnable(GL11.GL_POINT_SMOOTH);
+ GL11.glPointSize(2f);
+
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+ worldRenderer.begin(GL11.GL_POINTS, DefaultVertexFormats.POSITION_COLOR);
+ for (OffsetPoint point : buildPoints(center, radius)) {
+ worldRenderer.pos(point.getX(), point.getY(), point.getZ())
+ .color(color.getRed(), color.getGreen(), color.getBlue(), 255)
+ .endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private class OffsetPoint {
+ private final double x;
+ private final double y;
+ private final double z;
+
+ public OffsetPoint(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public OffsetPoint(BlockPos blockPos) {
+ x = blockPos.getX();
+ y = blockPos.getY();
+ z = blockPos.getZ();
+ }
+
+ public double getX() {
+ return x - playerX;
+ }
+
+ public double getY() {
+ return y - playerY;
+ }
+
+ public double getZ() {
+ return z - playerZ;
+ }
+
+ public OffsetPoint add(double x, double y, double z) {
+ return new OffsetPoint(this.x + x, this.y + y, this.z + z);
+ }
+ }
+
+ private Set<OffsetPoint> buildPoints(OffsetPoint center, double radius) {
+ Set<OffsetPoint> points = new HashSet<>(1200);
+
+ double tau = 6.283185307179586D;
+ double pi = tau / 2D;
+ double segment = tau / 48D;
+
+ for (double t = 0.0D; t < tau; t += segment)
+ for (double theta = 0.0D; theta < pi; theta += segment) {
+ double dx = radius * Math.sin(t) * Math.cos(theta);
+ double dz = radius * Math.sin(t) * Math.sin(theta);
+ double dy = radius * Math.cos(t);
+
+ points.add(center.add(dx, dy, dz));
+ }
+ return points;
+ }
+
+ private Set<BoundingBox> getClientBoundingBoxes(DimensionType dimensionType) {
+ if (worldData == null || dimensionType != DimensionType.OVERWORLD) {
+ return null;
+ }
+
+ Set<BoundingBox> boundingBoxes = new HashSet<>();
+ if (configManager.drawWorldSpawn.getBoolean()) {
+ boundingBoxes.add(getWorldSpawnBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
+ boundingBoxes.add(getSpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
+ }
+ if (configManager.drawLazySpawnChunks.getBoolean()) {
+ boundingBoxes.add(getLazySpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
+ }
+ if (configManager.drawSlimeChunks.getBoolean()) {
+ boundingBoxes.addAll(this.getSlimeChunks());
+ }
+ return boundingBoxes;
+ }
+
+ private Set<BoundingBoxSlimeChunk> getSlimeChunks() {
+ Minecraft minecraft = Minecraft.getMinecraft();
+ int renderDistanceChunks = minecraft.gameSettings.renderDistanceChunks;
+ int playerChunkX = MathHelper.floor(minecraft.player.posX / 16.0D);
+ int playerChunkZ = MathHelper.floor(minecraft.player.posZ / 16.0D);
+ Set<BoundingBoxSlimeChunk> slimeChunks = new HashSet<>();
+ for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; ++chunkX) {
+ for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; ++chunkZ) {
+ if (isSlimeChunk(chunkX, chunkZ)) {
+ ChunkPos chunk = new ChunkPos(chunkX, chunkZ);
+ BlockPos minBlockPos = new BlockPos(chunk.getXStart(), 1, chunk.getZStart());
+ BlockPos maxBlockPos = new BlockPos(chunk.getXEnd(), 38, chunk.getZEnd());
+ if (minecraft.world.isAreaLoaded(minBlockPos, maxBlockPos)) {
+ slimeChunks.add(BoundingBoxSlimeChunk.from(minBlockPos, maxBlockPos, Color.GREEN));
+ }
+ }
+ }
+ }
+ return slimeChunks;
+ }
+
+ private boolean isSlimeChunk(int chunkX, int chunkZ) {
+ Random r = new Random(worldData.getSeed() +
+ (long) (chunkX * chunkX * 4987142) +
+ (long) (chunkX * 5947611) +
+ (long) (chunkZ * chunkZ) * 4392871L +
+ (long) (chunkZ * 389711) ^ 987234911L);
+ return r.nextInt(10) == 0;
+ }
+
+ private BoundingBox getSpawnChunksBoundingBox(int spawnX, int spawnZ) {
+ if (spawnChunksBoundingBox != null) {
+ return spawnChunksBoundingBox;
+ }
+ BoundingBox boundingBox = getSpawnChunksBoundingBox(spawnX, spawnZ, 12, Color.RED);
+ spawnChunksBoundingBox = boundingBox;
+ return boundingBox;
+ }
+
+ private BoundingBox getLazySpawnChunksBoundingBox(int spawnX, int spawnZ) {
+ if (lazySpawnChunksBoundingBox != null)
+ return lazySpawnChunksBoundingBox;
+
+ BoundingBox boundingBox = getSpawnChunksBoundingBox(spawnX, spawnZ, 16, Color.RED);
+ lazySpawnChunksBoundingBox = boundingBox;
+ return boundingBox;
+ }
+
+ private BoundingBox getSpawnChunksBoundingBox(int spawnX, int spawnZ, int size, Color color) {
+ double chunkSize = 16;
+ double midOffset = chunkSize * (size / 2);
+ double midX = Math.round((float) (spawnX / chunkSize)) * chunkSize;
+ double midZ = Math.round((float) (spawnZ / chunkSize)) * chunkSize;
+ BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
+ if (spawnX / chunkSize % 0.5D == 0.0D && spawnZ / chunkSize % 0.5D == 0.0D) {
+ midX += chunkSize;
+ midZ += chunkSize;
+ }
+ BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
+ return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, color);
+ }
+
+ private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
+ if (worldSpawnBoundingBox != null)
+ return worldSpawnBoundingBox;
+
+ BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
+ BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
+
+ BoundingBox boundingBox = BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, Color.RED);
+ worldSpawnBoundingBox = boundingBox;
+ return boundingBox;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.BoundingBox;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class BoundingBoxCache {
+ private Map<BoundingBox, Set<BoundingBox>> cache = new ConcurrentHashMap<>();
+
+ public Map<BoundingBox, Set<BoundingBox>> getBoundingBoxes() {
+ return cache;
+ }
+
+ public synchronized void refresh() {
+ }
+
+ public void close() {
+ cache.clear();
+ }
+
+ public boolean isCached(BoundingBox key) {
+ return cache.containsKey(key);
+ }
+
+ public void addBoundingBoxes(BoundingBox key, Set<BoundingBox> boundingBoxes) {
+ cache.put(key, boundingBoxes);
+ }
+
+ public void addBoundingBox(BoundingBox key) {
+ Set<BoundingBox> boundingBoxes = new HashSet<>();
+ boundingBoxes.add(key);
+ addBoundingBoxes(key, boundingBoxes);
+ }
+
+ public void removeBoundingBox(BoundingBox key) {
+ if (cache.containsKey(key)) {
+ cache.remove(key);
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.ReflectionHelper;
+import com.irtimaled.bbor.common.models.WorldData;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.world.DimensionType;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraft.world.chunk.IChunkProvider;
+import net.minecraft.world.gen.ChunkProviderServer;
+import net.minecraft.world.gen.IChunkGenerator;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class CommonProxy {
+ public Map<DimensionType, BoundingBoxCache> boundingBoxCacheMap = new ConcurrentHashMap<>();
+
+ public ConfigManager configManager;
+ protected WorldData worldData;
+ private IEventHandler eventHandler = null;
+
+ public void init(ConfigManager configManager) {
+ this.configManager = configManager;
+ }
+
+ public void worldLoaded(World world) {
+ IChunkProvider chunkProvider = world.getChunkProvider();
+ if (chunkProvider instanceof ChunkProviderServer) {
+ IChunkGenerator chunkGenerator = ReflectionHelper.getPrivateValue(ChunkProviderServer.class, (ChunkProviderServer) chunkProvider, IChunkGenerator.class);
+ setWorldData(new WorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ()));
+ DimensionType dimensionType = world.provider.getDimensionType();
+ Logger.info("create world dimension: %s, %s (chunkprovider: %s) (seed: %d)", dimensionType, world.getClass().toString(), chunkGenerator.getClass().toString(), worldData.getSeed());
+ boundingBoxCacheMap.put(dimensionType, new DimensionProcessor(eventHandler, configManager, world, dimensionType, chunkGenerator));
+ }
+ }
+
+ public void chunkLoaded(Chunk chunk) {
+ DimensionType dimensionType = chunk.getWorld().provider.getDimensionType();
+ if (boundingBoxCacheMap.containsKey(dimensionType)) {
+ boundingBoxCacheMap.get(dimensionType).refresh();
+ }
+ }
+
+ public WorldData getWorldData() {
+ return worldData;
+ }
+
+ public void setWorldData(WorldData worldData) {
+ this.worldData = worldData;
+ }
+
+ public void setEventHandler(IEventHandler eventHandler) {
+ this.eventHandler = eventHandler;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.ReflectionHelper;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
+import net.minecraft.village.Village;
+import net.minecraft.village.VillageDoorInfo;
+import net.minecraft.world.DimensionType;
+import net.minecraft.world.World;
+import net.minecraft.world.gen.ChunkGeneratorEnd;
+import net.minecraft.world.gen.ChunkGeneratorHell;
+import net.minecraft.world.gen.ChunkGeneratorOverworld;
+import net.minecraft.world.gen.IChunkGenerator;
+import net.minecraft.world.gen.structure.*;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+public class DimensionProcessor extends BoundingBoxCache {
+ private ConfigManager configManager;
+ private World world;
+ private IEventHandler eventHandler;
+
+ public DimensionProcessor(IEventHandler eventHandler, ConfigManager configManager, World world, DimensionType dimensionType, IChunkGenerator chunkGenerator) {
+ this.eventHandler = eventHandler;
+ this.configManager = configManager;
+ this.world = world;
+ this.dimensionType = dimensionType;
+ this.chunkGenerator = chunkGenerator;
+ villageCache = new HashMap<>();
+ slimeChunkCache = new HashSet<>();
+ worldSpawnCache = new HashSet<>();
+ }
+
+ private DimensionType dimensionType;
+ private IChunkGenerator chunkGenerator;
+ private Map<Integer, BoundingBoxVillage> villageCache;
+ private Set<BoundingBox> slimeChunkCache;
+ private Set<BoundingBox> worldSpawnCache;
+
+ private boolean closed = false;
+
+ @Override
+ public void close() {
+ closed = true;
+ chunkGenerator = null;
+ villageCache.clear();
+ slimeChunkCache.clear();
+ worldSpawnCache.clear();
+ super.close();
+ }
+
+ private static <T extends IChunkGenerator, R extends MapGenStructure> Collection<StructureStart> getStructures(T chunkGenerator, Class<R> generatorClass) {
+ Class<T> chunkGeneratorClass = (Class<T>) chunkGenerator.getClass();
+ R structureGenerator = ReflectionHelper.getPrivateValue(chunkGeneratorClass, chunkGenerator, generatorClass);
+ if (structureGenerator != null) {
+ Map<ChunkPos, StructureStart> structureMap = ReflectionHelper.getPrivateValue(MapGenStructure.class, structureGenerator, Map.class);
+ return structureMap.values();
+ }
+ return Collections.emptyList();
+ }
+
+ private Map<StructureType, Collection<StructureStart>> getStructures() {
+ Map<StructureType, Collection<StructureStart>> structureMap = new HashMap<>();
+ if (chunkGenerator instanceof ChunkGeneratorOverworld) {
+ if (configManager.drawDesertTemples.getBoolean()) {
+ structureMap.put(StructureType.DesertTemple, getStructuresWithComponent(getStructures(chunkGenerator, MapGenScatteredFeature.class), ComponentScatteredFeaturePieces.DesertPyramid.class));
+ }
+
+ if (configManager.drawJungleTemples.getBoolean()) {
+ structureMap.put(StructureType.JungleTemple, getStructuresWithComponent(getStructures(chunkGenerator, MapGenScatteredFeature.class), ComponentScatteredFeaturePieces.JunglePyramid.class));
+ }
+
+ if (configManager.drawWitchHuts.getBoolean()) {
+ structureMap.put(StructureType.WitchHut, getStructuresWithComponent(getStructures(chunkGenerator, MapGenScatteredFeature.class), ComponentScatteredFeaturePieces.SwampHut.class));
+ }
+
+ if (configManager.drawOceanMonuments.getBoolean()) {
+ structureMap.put(StructureType.OceanMonument, getStructures(chunkGenerator, StructureOceanMonument.class));
+ }
+
+ if (configManager.drawStrongholds.getBoolean()) {
+ structureMap.put(StructureType.Stronghold, getStructures(chunkGenerator, MapGenStronghold.class));
+ }
+
+ if (configManager.drawMansions.getBoolean()) {
+ structureMap.put(StructureType.Mansion, getStructures(chunkGenerator, WoodlandMansion.class));
+ }
+
+ if (configManager.drawMineShafts.getBoolean()) {
+ structureMap.put(StructureType.MineShaft, getStructures(chunkGenerator, MapGenMineshaft.class));
+ }
+ } else if (chunkGenerator instanceof ChunkGeneratorHell) {
+ if (configManager.drawNetherFortresses.getBoolean()) {
+ structureMap.put(StructureType.NetherFortress, getStructures(chunkGenerator, MapGenNetherBridge.class));
+ }
+ } else if (chunkGenerator instanceof ChunkGeneratorEnd) {
+ if (configManager.drawEndCities.getBoolean()) {
+ structureMap.put(StructureType.EndCity, getStructures(chunkGenerator, MapGenEndCity.class));
+ }
+ }
+
+ return structureMap;
+ }
+
+ private Collection<StructureStart> getStructuresWithComponent(Collection<StructureStart> structures, Class structureComponent) {
+ Collection<StructureStart> validStructures = new HashSet<>();
+ for (StructureStart structure : structures) {
+ if (structure.getComponents().get(0).getClass().equals(structureComponent)) {
+ validStructures.add(structure);
+ }
+ }
+ return validStructures;
+ }
+
+ @Override
+ public synchronized void refresh() {
+ if (closed) return;
+
+ Map<StructureType, Collection<StructureStart>> structureMap = getStructures();
+ for (StructureType structureType : structureMap.keySet()) {
+ Color color = structureType.getColor();
+ for (StructureStart structureStart : structureMap.get(structureType)) {
+ if (structureStart.getBoundingBox() != null) {
+ BoundingBox boundingBox = BoundingBoxStructure.from(structureStart.getBoundingBox(), color);
+ if (!isCached(boundingBox)) {
+ Set<BoundingBox> structureBoundingBoxes = new HashSet<>();
+ for (StructureComponent structureComponent : structureStart.getComponents()) {
+ structureBoundingBoxes.add(BoundingBoxStructure.from(structureComponent.getBoundingBox(), color));
+ }
+ addBoundingBoxes(boundingBox, structureBoundingBoxes);
+ Logger.info("[%s] new boundingBoxCacheMap entries: %d", dimensionType, structureBoundingBoxes.size());
+ }
+ }
+ }
+ }
+
+ if (configManager.drawVillages.getBoolean() &&
+ world.getVillageCollection() != null) {
+ Map<Integer, BoundingBoxVillage> villageBoundingBoxes = new HashMap<>();
+ List<Village> villages = world.getVillageCollection().getVillageList();
+ for (Village village : villages) {
+ int villageId = village.hashCode();
+ BlockPos center = village.getCenter();
+ Color color = null;
+ if (villageCache.containsKey(villageId)) {
+ BoundingBoxVillage boundingBoxVillage = villageCache.get(villageId);
+ if (boundingBoxVillage.getCenter() == center) {
+ villageBoundingBoxes.put(villageId, boundingBoxVillage);
+ villageCache.remove(villageId);
+ continue;
+ }
+ color = boundingBoxVillage.getColor();
+ }
+
+ Integer radius = village.getVillageRadius();
+ int population = village.getNumVillagers();
+ Set<BlockPos> doors = getDoorsFromVillage(village);
+ villageBoundingBoxes.put(villageId, BoundingBoxVillage.from(center, radius, color, population, doors));
+ }
+ processDelta(villageCache, villageBoundingBoxes);
+ villageCache = villageBoundingBoxes;
+ }
+ }
+
+ private Set<BlockPos> getDoorsFromVillage(Village village) {
+ Set<BlockPos> doors = new HashSet<>();
+ for (Object doorInfo : village.getVillageDoorInfoList()) {
+ VillageDoorInfo villageDoorInfo = (VillageDoorInfo) doorInfo;
+ doors.add(villageDoorInfo.getDoorBlockPos());
+ }
+ return doors;
+ }
+
+ private void processDelta(Map<Integer, BoundingBoxVillage> oldVillages, Map<Integer, BoundingBoxVillage> newVillages) {
+ for (BoundingBox village : oldVillages.values()) {
+ removeBoundingBox(village);
+ if (eventHandler != null) {
+ eventHandler.boundingBoxRemoved(this.dimensionType, village);
+ }
+ }
+ for (BoundingBox village : newVillages.values()) {
+ if (!isCached(village))
+ addBoundingBox(village);
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.BoundingBox;
+import net.minecraft.world.DimensionType;
+
+public interface IEventHandler {
+ void boundingBoxRemoved(DimensionType dimensionType, BoundingBox bb);
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import java.awt.*;
+
+public class StructureType {
+ private static final int JUNGLE_TEMPLE = 1;
+ private static final int DESERT_TEMPLE = 2;
+ private static final int WITCH_HUT = 3;
+ private static final int OCEAN_MONUMENT = 4;
+ private static final int STRONGHOLD = 5;
+ private static final int MINE_SHAFT = 6;
+ private static final int NETHER_FORTRESS = 7;
+ private static final int END_CITY = 8;
+ private static final int MANSION = 9;
+
+ public final static StructureType JungleTemple = new StructureType(JUNGLE_TEMPLE);
+ public final static StructureType DesertTemple = new StructureType(DESERT_TEMPLE);
+ public final static StructureType WitchHut = new StructureType(WITCH_HUT);
+ public final static StructureType OceanMonument = new StructureType(OCEAN_MONUMENT);
+ public final static StructureType Stronghold = new StructureType(STRONGHOLD);
+ public final static StructureType MineShaft = new StructureType(MINE_SHAFT);
+ public final static StructureType NetherFortress = new StructureType(NETHER_FORTRESS);
+ public final static StructureType EndCity = new StructureType(END_CITY);
+ public final static StructureType Mansion = new StructureType(MANSION);
+
+ private final int type;
+
+ private StructureType(int type) {
+ this.type = type;
+ }
+
+ public Color getColor() {
+ switch (type) {
+ case DESERT_TEMPLE:
+ return Color.ORANGE;
+ case JUNGLE_TEMPLE:
+ return Color.GREEN;
+ case WITCH_HUT:
+ return Color.BLUE;
+ case MINE_SHAFT:
+ return Color.LIGHT_GRAY;
+ case NETHER_FORTRESS:
+ return Color.RED;
+ case OCEAN_MONUMENT:
+ return Color.CYAN;
+ case STRONGHOLD:
+ return Color.YELLOW;
+ case END_CITY:
+ return Color.MAGENTA;
+ case MANSION:
+ return new Color(139, 69, 19);
+ }
+ return Color.WHITE;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+
+public abstract class BoundingBox {
+ private final Color color;
+ private final BlockPos minBlockPos;
+ private final BlockPos maxBlockPos;
+
+ protected BoundingBox(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ this.minBlockPos = minBlockPos;
+ this.maxBlockPos = maxBlockPos;
+ this.color = color;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + minBlockPos.hashCode();
+ result = prime * result + maxBlockPos.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BoundingBox other = (BoundingBox) obj;
+ if (!minBlockPos.equals(other.minBlockPos))
+ return false;
+ if (!maxBlockPos.equals(other.maxBlockPos))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + minBlockPos.toString() + "; " + maxBlockPos.toString() + ")";
+ }
+
+ public AxisAlignedBB toAxisAlignedBB() {
+ return toAxisAlignedBB(true);
+ }
+
+ public AxisAlignedBB toAxisAlignedBB(boolean extendMaxByOne) {
+ AxisAlignedBB axisAlignedBB = new AxisAlignedBB(minBlockPos, maxBlockPos);
+ if (extendMaxByOne)
+ return axisAlignedBB.expand(1, 1, 1);
+ return axisAlignedBB;
+ }
+
+ public BlockPos getMinBlockPos() {
+ return minBlockPos;
+ }
+
+ public BlockPos getMaxBlockPos() {
+ return maxBlockPos;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
+
+import java.awt.*;
+
+public class BoundingBoxSlimeChunk extends BoundingBox {
+ private BoundingBoxSlimeChunk(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ super(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxSlimeChunk from(ChunkPos chunkCoordIntPair, Color color) {
+ BlockPos minBlockPos = new BlockPos(chunkCoordIntPair.getXStart(), 1, chunkCoordIntPair.getZStart());
+ BlockPos maxBlockPos = new BlockPos(chunkCoordIntPair.getXEnd(), 38, chunkCoordIntPair.getZEnd());
+ return new BoundingBoxSlimeChunk(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxSlimeChunk from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ return new BoundingBoxSlimeChunk(minBlockPos, maxBlockPos, color);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.gen.structure.StructureBoundingBox;
+
+import java.awt.*;
+
+public class BoundingBoxStructure extends BoundingBox {
+ private BoundingBoxStructure(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ super(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxStructure from(StructureBoundingBox bb, Color color) {
+ BlockPos minBlockPos = new BlockPos(bb.minX, bb.minY, bb.minZ);
+ BlockPos maxBlockPos = new BlockPos(bb.maxX, bb.maxY, bb.maxZ);
+ return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxStructure from(int[] bb, Color color) {
+ BlockPos minBlockPos = new BlockPos(bb[0], bb[1], bb[2]);
+ BlockPos maxBlockPos = new BlockPos(bb[3], bb[4], bb[5]);
+ return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxStructure from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+import java.util.Set;
+
+public class BoundingBoxVillage extends BoundingBox {
+ private final BlockPos center;
+ private final Integer radius;
+ private final boolean spawnsIronGolems;
+ private Set<BlockPos> doors;
+ private Double centerOffsetX;
+ private Double centerOffsetZ;
+
+ protected BoundingBoxVillage(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors, BlockPos minBlockPos, BlockPos maxBlockPos) {
+ super(minBlockPos, maxBlockPos, color);
+ this.center = center;
+ this.radius = radius;
+ this.spawnsIronGolems = spawnsIronGolems;
+ this.doors = doors;
+ calculateCenterOffsets(doors);
+ }
+
+ public static BoundingBoxVillage from(BlockPos center, Integer radius, int population, Set<BlockPos> doors) {
+ return from(center, radius, null, population, doors);
+ }
+
+ public static BoundingBoxVillage from(BlockPos center, Integer radius, Color color, int population, Set<BlockPos> doors) {
+ Boolean spawnsIronGolems = population >= 10 && doors.size() >= 21;
+ return from(center, radius, color, spawnsIronGolems, doors);
+ }
+
+ public static BoundingBoxVillage from(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors) {
+ BlockPos minBlockPos = new BlockPos(center.getX() - radius,
+ center.getY() - 4,
+ center.getZ() - radius);
+ BlockPos maxBlockPos = new BlockPos(center.getX() + radius,
+ center.getY() + 4,
+ center.getZ() + radius);
+ if (color == null)
+ color = getNextColor();
+ return new BoundingBoxVillage(center, radius, color, spawnsIronGolems, doors, minBlockPos, maxBlockPos);
+ }
+
+ private void calculateCenterOffsets(Set<BlockPos> doors) {
+ boolean processedFirstDoor = false;
+ int minX = 0;
+ int maxX = 0;
+ int minZ = 0;
+ int maxZ = 0;
+ for (BlockPos door : doors) {
+ if (!processedFirstDoor ||
+ (minX > door.getX()))
+ minX = door.getX();
+ if (!processedFirstDoor ||
+ maxX < door.getX())
+ maxX = door.getX();
+ if (!processedFirstDoor ||
+ minZ > door.getZ())
+ minZ = door.getZ();
+ if (!processedFirstDoor ||
+ maxZ < door.getZ())
+ maxZ = door.getZ();
+
+ processedFirstDoor = true;
+ }
+ centerOffsetX = Math.abs(maxX - minX) % 2 == 0 ? 0.5 : (minX < 0 ? 0 : 1);
+ centerOffsetZ = Math.abs(maxZ - minZ) % 2 == 0 ? 0.5 : (minZ < 0 ? 0 : 1);
+ }
+
+ @Override
+ public String toString() {
+ return "(" + center.toString() + "; " + radius.toString() + ")";
+ }
+
+ public Integer getRadius() {
+ return radius;
+ }
+
+ public BlockPos getCenter() {
+ return center;
+ }
+
+ public Double getCenterOffsetX() {
+ return centerOffsetX;
+ }
+
+ public Double getCenterOffsetZ() {
+ return centerOffsetZ;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ for (BlockPos door : doors) {
+ result = prime * result + door.hashCode();
+ }
+ return result;
+ }
+
+ public boolean getSpawnsIronGolems() {
+ return spawnsIronGolems;
+ }
+
+ private static int colorIndex = -1;
+
+ public static Color getNextColor() {
+ ++colorIndex;
+ switch (colorIndex % 6) {
+ case 0:
+ return Color.RED;
+ case 1:
+ return Color.GREEN;
+ case 2:
+ return Color.BLUE;
+ case 3:
+ return Color.MAGENTA;
+ case 4:
+ return Color.YELLOW;
+ case 5:
+ return Color.CYAN;
+ }
+ return Color.WHITE;
+ }
+
+ public Set<BlockPos> getDoors() {
+ return doors;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+
+public class BoundingBoxWorldSpawn extends BoundingBox {
+ protected BoundingBoxWorldSpawn(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ super(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxWorldSpawn from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, color);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+public class WorldData {
+ private long seed;
+ private int spawnX;
+ private int spawnZ;
+
+ public WorldData(long seed, int spawnX, int spawnZ) {
+ this.seed = seed;
+ this.spawnX = spawnX;
+ this.spawnZ = spawnZ;
+ }
+
+ public long getSeed() {
+ return seed;
+ }
+
+ public int getSpawnX() {
+ return spawnX;
+ }
+
+ public int getSpawnZ() {
+ return spawnZ;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.config;
+
+import java.io.File;
+
+public class ConfigManager {
+ public final File configDir;
+
+ public Setting fill;
+ public Setting drawVillages;
+ public Setting drawDesertTemples;
+ public Setting drawJungleTemples;
+ public Setting drawWitchHuts;
+ public Setting drawStrongholds;
+ public Setting drawMineShafts;
+ public Setting drawNetherFortresses;
+ public Setting drawOceanMonuments;
+ public Setting alwaysVisible;
+ public Setting renderVillageAsSphere;
+ public Setting drawIronGolemSpawnArea;
+ public Setting drawVillageDoors;
+ public Setting drawSlimeChunks;
+ public Setting slimeChunkMaxY;
+ public Setting keepCacheBetweenSessions;
+ public Setting drawWorldSpawn;
+ public Setting worldSpawnMaxY;
+ public Setting drawLazySpawnChunks;
+ public Setting drawEndCities;
+ public Setting drawMansions;
+
+ private Configuration config;
+
+ public ConfigManager(File configDir) {
+ this.configDir = configDir;
+ config = new Configuration(new File(configDir, "BBOutlineReloaded.cfg"));
+ config.load();
+
+ fill = SetupBooleanProperty(config, "general", "fill", true, "If set to true the bounding boxes are filled. (default: true)");
+ alwaysVisible = SetupBooleanProperty(config, "general", "alwaysVisible", false, "If set to true boxes will be visible even through other blocks. (default: false)");
+ keepCacheBetweenSessions = SetupBooleanProperty(config, "general", "keepCacheBetweenSessions", false, "If set to true bounding box caches will be kept between sessions. (default: false)");
+ drawVillages = SetupBooleanProperty(config, "features", "drawVillages", true, "If set to true village bounding boxes are drawn. (default: true)");
+ renderVillageAsSphere = SetupBooleanProperty(config, "features", "renderVillageAsSphere", true, "If set to true villages will be drawn as a sphere. (default:true)");
+ drawIronGolemSpawnArea = SetupBooleanProperty(config, "features", "drawIronGolemSpawnArea", true, "If set to true the iron golem spawn area of the village will be drawn. (default:true)");
+ drawVillageDoors = SetupBooleanProperty(config, "features", "drawVillageDoors", false, "If set to true lines between the village centre and doors will be drawn. (default:false)");
+ drawDesertTemples = SetupBooleanProperty(config, "features", "drawDesertTemples", true, "If set to true desert temple bounding boxes are drawn. (default: true)");
+ drawJungleTemples = SetupBooleanProperty(config, "features", "drawJungleTemples", true, "If set to true jungle temple bounding boxes are drawn. (default: true)");
+ drawWitchHuts = SetupBooleanProperty(config, "features", "drawWitchHuts", true, "If set to true witch hut bounding boxes are drawn. (default: true)");
+ drawStrongholds = SetupBooleanProperty(config, "features", "drawStrongholds", false, "If set to true stronghold bounding boxes are drawn. (default: false)");
+ drawMineShafts = SetupBooleanProperty(config, "features", "drawMineShafts", false, "If set to true mineshaft bounding boxes are drawn. (default: false)");
+ drawNetherFortresses = SetupBooleanProperty(config, "features", "drawNetherFortresses", true, "If set to true nether fortress bounding boxes are drawn. (default: true)");
+ drawOceanMonuments = SetupBooleanProperty(config, "features", "drawOceanMonuments", true, "If set to true ocean monument bounding boxes are drawn. (default: true)");
+ drawSlimeChunks = SetupBooleanProperty(config, "features", "drawSlimeChunks", true, "If set to true slime chunks bounding boxes are drawn. (default: true)");
+ slimeChunkMaxY = SetupIntegerProperty(config, "features", "slimeChunkMaxY", -1, "The maximum top of the slime chunk bounding box. If set to -1 it will use the value when activated, if set to 0 it will always track the player's feet. (default: -1)");
+ drawWorldSpawn = SetupBooleanProperty(config, "features", "drawWorldSpawn", true, "If set to true world spawn and spawn chunks bounding boxes are drawn. (default: true)");
+ worldSpawnMaxY = SetupIntegerProperty(config, "features", "worldSpawnMaxY", -1, "The maximum top of the world spawn bounding boxes. If set to -1 it will use the value when activated, if set to 0 it will always track the players feet. (default: -1)");
+ drawLazySpawnChunks = SetupBooleanProperty(config, "features", "drawLazySpawnChunks", false, "If set to true the lazy spawn chunks bounding boxes will be drawn. (default: false)");
+ drawEndCities = SetupBooleanProperty(config, "features", "drawEndCities", true, "If set to true end city bounding boxes will be drawn. (default: true)");
+ drawMansions = SetupBooleanProperty(config, "features", "drawMansions", true, "If set to true woodland mansions will be drawn. (default: true)");
+ config.save();
+ }
+
+ private Setting SetupBooleanProperty(Configuration config, String category, String settingName, Boolean defaultValue, String comment) {
+ Setting property = config.get(category, settingName, defaultValue);
+ property.comment = comment;
+ property.set(property.getBoolean(defaultValue));
+ return property;
+ }
+
+ private Setting SetupIntegerProperty(Configuration config, String category, String settingName, int defaultValue, String comment) {
+ Setting property = config.get(category, settingName, defaultValue);
+ property.comment = comment;
+ property.set(property.getInt(defaultValue));
+ return property;
+ }
+}
package com.irtimaled.bbor.forge;
-import com.irtimaled.bbor.ClientProxy;
+import com.irtimaled.bbor.client.ClientProxy;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.client.event.RenderWorldLastEvent;
package com.irtimaled.bbor.forge;
-import com.irtimaled.bbor.*;
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.common.BoundingBoxCache;
+import com.irtimaled.bbor.common.CommonProxy;
+import com.irtimaled.bbor.common.IEventHandler;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.WorldData;
+import com.irtimaled.bbor.config.ConfigManager;
import com.irtimaled.bbor.forge.messages.*;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
package com.irtimaled.bbor.forge;
-import com.irtimaled.bbor.ConfigManager;
+import com.irtimaled.bbor.config.ConfigManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
package com.irtimaled.bbor.forge.messages;
-import com.irtimaled.bbor.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBox;
import io.netty.buffer.ByteBuf;
import net.minecraft.world.DimensionType;
import net.minecraftforge.fml.common.network.ByteBufUtils;
package com.irtimaled.bbor.forge.messages;
-import com.irtimaled.bbor.BoundingBox;
-import com.irtimaled.bbor.BoundingBoxStructure;
-import com.irtimaled.bbor.BoundingBoxVillage;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.common.network.ByteBufUtils;
package com.irtimaled.bbor.forge.messages;
-import com.irtimaled.bbor.BoundingBox;
-import com.irtimaled.bbor.BoundingBoxStructure;
-import com.irtimaled.bbor.BoundingBoxVillage;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.common.network.ByteBufUtils;
package com.irtimaled.bbor.forge.messages;
-import com.irtimaled.bbor.WorldData;
+import com.irtimaled.bbor.common.models.WorldData;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
package com.irtimaled.bbor.forge.messages;
-import com.irtimaled.bbor.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBox;
import io.netty.buffer.ByteBuf;
import net.minecraft.world.DimensionType;
import net.minecraftforge.fml.common.network.ByteBufUtils;