1 package com.irtimaled.bbor.client.providers;
3 import com.irtimaled.bbor.client.Player;
4 import com.irtimaled.bbor.client.config.BoundingBoxTypeHelper;
5 import com.irtimaled.bbor.client.config.ConfigManager;
6 import com.irtimaled.bbor.client.interop.BiomeBorderHelper;
7 import com.irtimaled.bbor.client.models.BoundingBoxBiomeBorder;
8 import com.irtimaled.bbor.common.BoundingBoxType;
9 import com.irtimaled.bbor.common.MathHelper;
10 import com.irtimaled.bbor.common.models.Coords;
11 import com.irtimaled.bbor.common.models.DimensionId;
12 import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
14 import java.util.HashMap;
17 public class BiomeBorderProvider implements IBoundingBoxProvider<BoundingBoxBiomeBorder>, ICachingProvider {
18 private static Coords lastPlayerCoords = null;
19 private static Boolean lastRenderAllTransitions = null;
20 private static Integer lastRenderDistance = null;
21 private static Integer lastMaxY = null;
22 private static Map<Coords, BoundingBoxBiomeBorder> lastBorders = new Object2ObjectLinkedOpenHashMap<>();
25 public boolean canProvide(DimensionId dimensionId) {
26 return BoundingBoxTypeHelper.shouldRender(BoundingBoxType.BiomeBorder);
30 public Iterable<BoundingBoxBiomeBorder> get(DimensionId dimensionId) {
31 Coords playerCoords = Player.getCoords();
32 Integer renderDistance = ConfigManager.biomeBordersRenderDistance.get();
33 Boolean renderAllTransitions = !ConfigManager.renderOnlyCurrentBiome.get();
34 Integer maxY = (int) Player.getMaxY(ConfigManager.biomeBordersMaxY.get());
35 if (!playerCoords.equals(lastPlayerCoords) ||
36 !renderDistance.equals(lastRenderDistance) ||
37 renderAllTransitions != lastRenderAllTransitions ||
38 !maxY.equals(lastMaxY)) {
39 lastPlayerCoords = playerCoords;
40 lastRenderDistance = renderDistance;
41 lastRenderAllTransitions = renderAllTransitions;
43 lastBorders = getBiomeBorders();
45 return lastBorders.values();
48 public void clearCache() {
49 lastBorders = new HashMap<>();
50 lastPlayerCoords = null;
53 private Map<Coords, BoundingBoxBiomeBorder> getBiomeBorders() {
54 int renderDistance = lastRenderDistance;
55 Coords playerCoords = lastPlayerCoords;
56 boolean renderAllTransitions = lastRenderAllTransitions;
59 int width = MathHelper.floor(Math.pow(2, 3 + renderDistance));
61 int blockX = playerCoords.getX();
62 int minX = blockX - width;
63 int maxX = blockX + width;
65 int blockZ = playerCoords.getZ();
66 int minZ = blockZ - width;
67 int maxZ = blockZ + width;
69 int size = (width * 2) + 1;
70 int[][] biomeIds = new int[size][size];
71 for (int x = minX; x <= maxX; x++) {
72 int matchX = (x - minX);
73 for (int z = minZ; z <= maxZ; z++) {
74 int matchZ = (z - minZ);
75 biomeIds[matchX][matchZ] = BiomeBorderHelper.getBiomeId(x, maxY, z);
79 int playerBiomeId = BiomeBorderHelper.getBiomeId(playerCoords);
81 Map<Coords, BoundingBoxBiomeBorder> borders = new HashMap<>();
82 for (int matchX = 1; matchX < size - 2; matchX++) {
83 for (int matchZ = 1; matchZ < size - 2; matchZ++) {
84 int x = matchX + minX;
85 int z = matchZ + minZ;
86 int biomeId = biomeIds[matchX][matchZ];
87 if (renderAllTransitions || biomeId == playerBiomeId) {
88 Coords coords = new Coords(x, maxY, z);
89 if (lastBorders.containsKey(coords)) {
90 borders.put(coords, lastBorders.get(coords));
92 boolean north = biomeIds[matchX][matchZ - 1] != biomeId;
93 boolean east = biomeIds[matchX + 1][matchZ] != biomeId;
94 boolean south = biomeIds[matchX][matchZ + 1] != biomeId;
95 boolean west = biomeIds[matchX - 1][matchZ] != biomeId;
96 if (north || east || south || west) {
97 borders.put(coords, new BoundingBoxBiomeBorder(coords, north, east, south, west));