]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
Add: flower forest overlay
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / ClientRenderer.java
1 package com.irtimaled.bbor.client;
2
3 import com.irtimaled.bbor.client.interop.ClientInterop;
4 import com.irtimaled.bbor.client.models.*;
5 import com.irtimaled.bbor.client.providers.*;
6 import com.irtimaled.bbor.client.renderers.*;
7 import com.irtimaled.bbor.common.MathHelper;
8 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
9 import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
10 import com.irtimaled.bbor.common.models.DimensionId;
11
12 import java.util.*;
13 import java.util.stream.Stream;
14
15 public class ClientRenderer {
16     private static final int CHUNK_SIZE = 16;
17     private static final Map<Class<? extends AbstractBoundingBox>, AbstractRenderer> boundingBoxRendererMap = new HashMap<>();
18
19     private static boolean active;
20     private static final Set<IBoundingBoxProvider> providers = new HashSet<>();
21
22     public static boolean getActive() {
23         return active;
24     }
25
26     public static void toggleActive() {
27         active = !active;
28         if (!active) return;
29
30         Player.setActiveY();
31     }
32
33     static void deactivate() {
34         active = false;
35     }
36
37     static {
38         registerRenderer(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
39         registerRenderer(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
40         registerRenderer(BoundingBoxCuboid.class, new CuboidRenderer());
41         registerRenderer(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
42         registerRenderer(BoundingBoxSpawningSphere.class, new SpawningSphereRenderer());
43         registerRenderer(BoundingBoxBeacon.class, new BeaconRenderer());
44         registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
45         registerRenderer(BoundingBoxConduit.class, new ConduitRenderer());
46         registerRenderer(BoundingBoxSpawnableBlocks.class, new SpawnableBlocksRenderer());
47         registerRenderer(BoundingBoxLine.class, new LineRenderer());
48         registerRenderer(BoundingBoxSphere.class, new SphereRenderer());
49         registerRenderer(BoundingBoxFlowerForest.class, new FlowerForestRenderer());
50
51         registerProvider(new SlimeChunkProvider());
52         registerProvider(new WorldSpawnProvider());
53         registerProvider(new SpawningSphereProvider());
54         registerProvider(new BeaconProvider());
55         registerProvider(new CustomBoxProvider());
56         registerProvider(new CustomBeaconProvider());
57         registerProvider(new BiomeBorderProvider());
58         registerProvider(new MobSpawnerProvider());
59         registerProvider(new ConduitProvider());
60         registerProvider(new SpawnableBlocksProvider());
61         registerProvider(new CustomLineProvider());
62         registerProvider(new CustomSphereProvider());
63         registerProvider(new FlowerForestProvider());
64     }
65
66     public static <T extends AbstractBoundingBox> void registerProvider(IBoundingBoxProvider<T> provider) {
67         providers.add(provider);
68     }
69
70     public static <T extends AbstractBoundingBox> void registerRenderer(Class<? extends T> type, AbstractRenderer<T> renderer) {
71         boundingBoxRendererMap.put(type, renderer);
72     }
73
74     private static boolean isWithinRenderDistance(AbstractBoundingBox boundingBox) {
75         int renderDistanceBlocks = ClientInterop.getRenderDistanceChunks() * CHUNK_SIZE;
76         int minX = MathHelper.floor(Player.getX() - renderDistanceBlocks);
77         int maxX = MathHelper.floor(Player.getX() + renderDistanceBlocks);
78         int minZ = MathHelper.floor(Player.getZ() - renderDistanceBlocks);
79         int maxZ = MathHelper.floor(Player.getZ() + renderDistanceBlocks);
80
81         return boundingBox.intersectsBounds(minX, minZ, maxX, maxZ);
82     }
83
84     public static void render(DimensionId dimensionId) {
85         if (!active) return;
86
87         RenderHelper.beforeRender();
88
89         getBoundingBoxes(dimensionId).forEach(key -> {
90             AbstractRenderer renderer = boundingBoxRendererMap.get(key.getClass());
91             if (renderer != null) renderer.render(key);
92         });
93
94         RenderHelper.afterRender();
95     }
96
97     public static Stream<AbstractBoundingBox> getBoundingBoxes(DimensionId dimensionId) {
98         Stream.Builder<AbstractBoundingBox> boundingBoxes = Stream.builder();
99         for (IBoundingBoxProvider<?> provider : providers) {
100             if (provider.canProvide(dimensionId)) {
101                 for (AbstractBoundingBox boundingBox : provider.get(dimensionId)) {
102                     if (isWithinRenderDistance(boundingBox)) {
103                         boundingBoxes.accept(boundingBox);
104                     }
105                 }
106             }
107         }
108
109         Point point = Player.getPoint();
110         return boundingBoxes.build()
111                 .sorted(Comparator
112                         .comparingDouble((AbstractBoundingBox boundingBox) -> boundingBox.getDistance(point.getX(), point.getY(), point.getZ())).reversed());
113     }
114
115 }