]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/ClientProxy.java
Generate spawn bounding boxes on world load
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / ClientProxy.java
1 package com.irtimaled.bbor.client;
2
3 import com.irtimaled.bbor.client.events.*;
4 import com.irtimaled.bbor.common.*;
5 import com.irtimaled.bbor.common.models.BoundingBox;
6 import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
7 import com.irtimaled.bbor.config.ConfigManager;
8 import net.minecraft.client.Minecraft;
9 import net.minecraft.client.settings.KeyBinding;
10 import net.minecraft.entity.player.EntityPlayer;
11 import net.minecraft.network.NetworkManager;
12 import net.minecraft.util.math.BlockPos;
13 import net.minecraft.world.dimension.DimensionType;
14
15 import java.net.InetSocketAddress;
16 import java.net.SocketAddress;
17 import java.util.Set;
18
19 import static com.irtimaled.bbor.client.Constants.CHUNK_SIZE;
20
21 public class ClientProxy extends CommonProxy {
22     public static final String KeyCategory = "Bounding Box Outline Reloaded";
23     public static KeyBinding ActiveHotKey = new KeyBinding("Toggle On/Off", 0x42, KeyCategory);
24     public static KeyBinding OuterBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", 0x4f, KeyCategory);
25
26     private boolean active;
27     private boolean outerBoxOnly;
28     private ClientRenderer renderer;
29
30     @Override
31     public void init() {
32         super.init();
33         EventBus.subscribe(Render.class, e -> render(e.getPartialTicks()));
34         EventBus.subscribe(KeyPressed.class, e -> keyPressed());
35         EventBus.subscribe(ConnectedToRemoteServer.class, e -> connectedToServer(e.getNetworkManager()));
36         EventBus.subscribe(DisconnectedFromRemoteServer.class, e -> disconnectedFromServer());
37         EventBus.subscribe(InitializeClientReceived.class, e -> setWorldData(e.getSeed(), e.getSpawnX(), e.getSpawnZ()));
38         EventBus.subscribe(AddBoundingBoxReceived.class, e -> addBoundingBox(e.getDimensionType(), e.getKey(), e.getBoundingBoxes()));
39         EventBus.subscribe(RemoveBoundingBoxReceived.class, e -> removeBoundingBox(e.getDimensionType(), e.getKey()));
40
41         renderer = new ClientRenderer(dimensionCache);
42     }
43
44     private void render(float partialTicks) {
45         EntityPlayer entityPlayer = Minecraft.getInstance().player;
46         PlayerData.setPlayerPosition(partialTicks, entityPlayer);
47
48         if (this.active) {
49             renderer.render(DimensionType.getById(entityPlayer.dimension), outerBoxOnly);
50         }
51     }
52
53     private void keyPressed() {
54         if (ActiveHotKey.isPressed()) {
55             active = !active;
56             if (active)
57                 PlayerData.setActiveY();
58         } else if (OuterBoxOnlyHotKey.isPressed()) {
59             outerBoxOnly = !outerBoxOnly;
60         }
61     }
62
63     private void connectedToServer(NetworkManager networkManager) {
64         SocketAddress remoteAddress = networkManager.getRemoteAddress();
65         if (remoteAddress instanceof InetSocketAddress) {
66             InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress;
67             NBTFileParser.loadLocalDatFiles(socketAddress.getHostName(), socketAddress.getPort(), dimensionCache, this::setWorldData);
68         }
69     }
70
71     private void disconnectedFromServer() {
72         active = false;
73         if (ConfigManager.keepCacheBetweenSessions.getBoolean()) return;
74         VillageColorCache.clear();
75         clearCaches();
76     }
77
78     private void addBoundingBox(DimensionType dimensionType, BoundingBox key, Set<BoundingBox> boundingBoxes) {
79         BoundingBoxCache cache = dimensionCache.get(dimensionType);
80         if (cache == null) {
81             dimensionCache.put(dimensionType, cache = new BoundingBoxCache());
82         }
83
84         cache.addBoundingBoxes(key, boundingBoxes);
85     }
86
87     @Override
88     protected void setWorldData(long seed, int spawnX, int spawnZ) {
89         super.setWorldData(seed, spawnX, spawnZ);
90         addSpawnChunkBoundingBoxes(spawnX, spawnZ);
91     }
92
93     private void addSpawnChunkBoundingBoxes(int spawnX, int spawnZ) {
94         BoundingBoxCache cache = dimensionCache.get(DimensionType.OVERWORLD);
95         if (cache == null) return;
96
97         cache.addBoundingBox(getWorldSpawnBoundingBox(spawnX, spawnZ));
98         cache.addBoundingBox(buildSpawnChunksBoundingBox(spawnX, spawnZ, 12, BoundingBoxType.SpawnChunks));
99         cache.addBoundingBox(buildSpawnChunksBoundingBox(spawnX, spawnZ, 16, BoundingBoxType.LazySpawnChunks));
100     }
101
102     private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
103         BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
104         BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
105
106         return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, BoundingBoxType.WorldSpawn);
107     }
108
109     private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ, int size, BoundingBoxType type) {
110         double midOffset = CHUNK_SIZE * (size / 2.0);
111         double midX = Math.round((float) (spawnX / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
112         double midZ = Math.round((float) (spawnZ / (double) CHUNK_SIZE)) * (double) CHUNK_SIZE;
113         BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
114         if (spawnX / (double) CHUNK_SIZE % 0.5D == 0.0D && spawnZ / (double) CHUNK_SIZE % 0.5D == 0.0D) {
115             midX += (double) CHUNK_SIZE;
116             midZ += (double) CHUNK_SIZE;
117         }
118         BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
119         return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, type);
120     }
121 }