This is done by sending the seed from the server to the client.
It will enable future smartness!
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
+import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import java.awt.*;
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 KeyBinding hotKey;
+ private double playerX;
+ private double playerY;
+ private double playerZ;
@SubscribeEvent
public void onKeyInputEvent(InputEvent.KeyInputEvent evt) {
}
}
- private boolean active;
- private KeyBinding hotKey;
-
@Override
public void init() {
super.init();
return true;
}
- private double playerX;
- private double playerY;
- private double playerZ;
-
@SubscribeEvent
public void renderWorldLastEvent(RenderWorldLastEvent event) {
EntityPlayer entityPlayer = Minecraft.getMinecraft().thePlayer;
public void clientDisconnectionFromServerEvent(FMLNetworkEvent.ClientDisconnectionFromServerEvent evt) {
active = false;
if (configManager.keepCacheBetweenSessions.getBoolean()) return;
+ initialized = false;
for (BoundingBoxCache cache : boundingBoxCacheMap.values()) {
cache.close();
}
renderBoundingBoxes(map.get(bb));
}
+ renderBoundingBoxes(getClientBoundingBoxes());
+
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_TEXTURE_2D);
private void renderBoundingBoxes(Set<BoundingBox> bbList) {
World world = Minecraft.getMinecraft().theWorld;
- Set activeChunks = ReflectionHelper.getPrivateValue(World.class, world, 33);
+ Set activeChunks = getActiveChunks(world);
for (BoundingBox bb : bbList) {
if (activeChunks.contains(world.getChunkFromBlockCoords(bb.getMinBlockPos()).getChunkCoordIntPair()) ||
}
}
+ private Set getActiveChunks(World world) {
+ return ReflectionHelper.getPrivateValue(World.class, world, 33);
+ }
+
private void renderBoundingBox(BoundingBox bb) {
AxisAlignedBB aaBB = bb.toAxisAlignedBB();
Color color = bb.getColor();
}
return points;
}
+
+ private Set<BoundingBox> getClientBoundingBoxes() {
+ Set<BoundingBox> boundingBoxes = new HashSet<BoundingBox>();
+ World world = Minecraft.getMinecraft().theWorld;
+ int dimensionId = world.provider.getDimensionId();
+ if (dimensionId == 0) {
+ if (configManager.drawWorldSpawn.getBoolean()) {
+ int spawnX = world.getWorldInfo().getSpawnX();
+ int spawnZ = world.getWorldInfo().getSpawnZ();
+ boundingBoxes.add(getSpawnBoundingBox(spawnX, spawnZ));
+ boundingBoxes.add(getSpawnChunksBoundingBox(spawnX, spawnZ));
+
+ }
+
+ if (initialized &&
+ configManager.drawSlimeChunks.getBoolean()) {
+ Set<ChunkCoordIntPair> activeChunks = getActiveChunks(world);
+ for (ChunkCoordIntPair chunk : activeChunks) {
+ if (isSlimeChunk(chunk.chunkXPos, chunk.chunkZPos)) {
+ boundingBoxes.add(BoundingBoxSlimeChunk.from(chunk, Color.GREEN));
+ }
+ }
+ }
+ }
+ return boundingBoxes;
+ }
+
+ private boolean isSlimeChunk(int chunkX, int chunkZ) {
+ Random r = new Random(seed +
+ (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) {
+ double chunkSize = 16;
+ double midOffset = chunkSize * 6;
+ 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 new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, Color.RED);
+ }
+
+ private BoundingBoxWorldSpawn getSpawnBoundingBox(int spawnX, int spawnZ) {
+ BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
+ BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
+
+ return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, Color.RED);
+ }
}
package com.irtimaled.bbor;
-import com.irtimaled.bbor.messages.AddBoundingBoxMessage;
-import com.irtimaled.bbor.messages.AddBoundingBoxMessageHandler;
-import com.irtimaled.bbor.messages.RemoveBoundingBoxMessage;
-import com.irtimaled.bbor.messages.RemoveBoundingBoxMessageHandler;
+import com.irtimaled.bbor.messages.*;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
private Map<EntityPlayerMP, Set<BoundingBox>> playerBoundingBoxesCache = new HashMap<EntityPlayerMP, Set<BoundingBox>>();
-
public ConfigManager configManager;
protected SimpleNetworkWrapper network;
+ protected long seed;
+ protected boolean initialized;
public void init() {
network = NetworkRegistry.INSTANCE.newSimpleChannel("bbor");
network.registerMessage(AddBoundingBoxMessageHandler.class, AddBoundingBoxMessage.class, 0, Side.CLIENT);
network.registerMessage(RemoveBoundingBoxMessageHandler.class, RemoveBoundingBoxMessage.class, 1, Side.CLIENT);
+ network.registerMessage(InitializeClientMessageHandler.class, InitializeClientMessage.class, 2, Side.CLIENT);
}
@SubscribeEvent
IChunkProvider chunkProvider = event.world.getChunkProvider();
if (chunkProvider instanceof ChunkProviderServer) {
chunkProvider = ((ChunkProviderServer) chunkProvider).serverChunkGenerator;
- long seed = event.world.getSeed();
+ setSeed(event.world.getSeed());
int dimensionId = event.world.provider.getDimensionId();
FMLLog.info("create world dimension: %d, %s (chunkprovider: %s) (seed: %d)", dimensionId, event.world.getClass().toString(), chunkProvider.getClass().toString(), seed);
- boundingBoxCacheMap.put(dimensionId, new DimensionProcessor(configManager, event.world, seed, dimensionId, chunkProvider));
+ boundingBoxCacheMap.put(dimensionId, new DimensionProcessor(configManager, event.world, dimensionId, chunkProvider));
}
}
@SubscribeEvent
public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent evt) {
- if (evt.player instanceof EntityPlayerMP && isRemotePlayer(evt.player)) {
-
+ if (evt.player instanceof EntityPlayerMP &&
+ isRemotePlayer(evt.player)) {
EntityPlayerMP player = (EntityPlayerMP) evt.player;
+ initializeClient(player);
int dimension = player.dimension;
playerDimensions.put(player, dimension);
-
sendToPlayer(player, boundingBoxCacheMap.get(dimension));
}
}
}
}
+ private void initializeClient(EntityPlayerMP player) {
+ network.sendTo(InitializeClientMessage.from(seed), player);
+ }
+
private void sendToPlayer(EntityPlayerMP player, BoundingBoxCache boundingBoxCache) {
Map<BoundingBox, Set<BoundingBox>> cacheSubset = getBoundingBoxMap(player, boundingBoxCache.getBoundingBoxes());
}
}
}
+
+ public void setSeed(long seed) {
+ this.seed = seed;
+ this.initialized = true;
+ }
}
private ConfigManager configManager;
private World world;
- private long seed;
- public DimensionProcessor(ConfigManager configManager, World world, long seed, int dimensionId, IChunkProvider chunkProvider) {
+ public DimensionProcessor(ConfigManager configManager, World world, int dimensionId, IChunkProvider chunkProvider) {
this.configManager = configManager;
this.world = world;
- this.seed = seed;
this.dimensionId = dimensionId;
this.chunkProvider = chunkProvider;
villageCache = new HashSet<BoundingBox>();
}
}
- if (dimensionId == 0) {
- if (configManager.drawWorldSpawn.getBoolean()) {
- Set<BoundingBox> worldSpawnBoundingBoxes = new HashSet<BoundingBox>();
- int spawnX = world.getWorldInfo().getSpawnX();
- int spawnZ = world.getWorldInfo().getSpawnZ();
- worldSpawnBoundingBoxes.add(getSpawnBoundingBox(spawnX, spawnZ));
- worldSpawnBoundingBoxes.add(getSpawnChunksBoundingBox(spawnX, spawnZ));
- processDelta(worldSpawnCache, worldSpawnBoundingBoxes);
-
- worldSpawnCache = worldSpawnBoundingBoxes;
- }
-
-
- if (configManager.drawSlimeChunks.getBoolean()) {
- Set<BoundingBox> slimeChunkBoundingBoxes = new HashSet<BoundingBox>();
- Set<ChunkCoordIntPair> activeChunks = ReflectionHelper.getPrivateValue(World.class, world, 33);
- for (ChunkCoordIntPair chunk : activeChunks) {
- if (isSlimeChunk(chunk.chunkXPos, chunk.chunkZPos)) {
- slimeChunkBoundingBoxes.add(BoundingBoxSlimeChunk.from(chunk, Color.GREEN));
- }
- }
-
- processDelta(slimeChunkCache, slimeChunkBoundingBoxes);
-
- slimeChunkCache = slimeChunkBoundingBoxes;
- }
-
- if (configManager.drawVillages.getBoolean() &&
- (world.villageCollectionObj != null)) {
-
- Set<BoundingBox> villageBoundingBoxes = new HashSet<BoundingBox>();
- List<Village> villages = world.villageCollectionObj.getVillageList();
- int c = 0;
- for (Village village : villages) {
- BlockPos center = ReflectionHelper.getPrivateValue(Village.class, village, 3);
- Integer radius = ReflectionHelper.getPrivateValue(Village.class, village, 4);
- boolean spawnsIronGolems = village.getNumVillagers() >= 10 &&
- village.getNumVillageDoors() >= 21;
- Color color = getVillageColor(c % 6);
- villageBoundingBoxes.add(BoundingBoxVillage.from(center, radius, spawnsIronGolems, color));
- ++c;
- }
- processDelta(villageCache, villageBoundingBoxes);
-
- villageCache = villageBoundingBoxes;
+ if (configManager.drawVillages.getBoolean() &&
+ (world.villageCollectionObj != null)) {
+
+ Set<BoundingBox> villageBoundingBoxes = new HashSet<BoundingBox>();
+ List<Village> villages = world.villageCollectionObj.getVillageList();
+ int c = 0;
+ for (Village village : villages) {
+ BlockPos center = ReflectionHelper.getPrivateValue(Village.class, village, 3);
+ Integer radius = ReflectionHelper.getPrivateValue(Village.class, village, 4);
+ boolean spawnsIronGolems = village.getNumVillagers() >= 10 &&
+ village.getNumVillageDoors() >= 21;
+ Color color = getVillageColor(c % 6);
+ villageBoundingBoxes.add(BoundingBoxVillage.from(center, radius, spawnsIronGolems, color));
+ ++c;
}
- }
- }
+ processDelta(villageCache, villageBoundingBoxes);
- private BoundingBox getSpawnChunksBoundingBox(int spawnX, int spawnZ) {
- double chunkSize = 16;
- double midOffset = chunkSize * 6;
- 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;
+ villageCache = villageBoundingBoxes;
}
- BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
- return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, Color.RED);
- }
-
- private BoundingBoxWorldSpawn getSpawnBoundingBox(int spawnX, int spawnZ) {
- BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
- BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
-
- return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, Color.RED);
}
private void processDelta(Set<BoundingBox> oldBoundingBoxes, Set<BoundingBox> newBoundingBoxes) {
}
}
- private boolean isSlimeChunk(int chunkX, int chunkZ) {
- Random r = new Random(seed +
- (long) (chunkX * chunkX * 4987142) +
- (long) (chunkX * 5947611) +
- (long) (chunkZ * chunkZ) * 4392871L +
- (long) (chunkZ * 389711) ^ 987234911L);
- return r.nextInt(10) == 0;
- }
-
private Color getVillageColor(int c) {
switch (c) {
case 0:
--- /dev/null
+package com.irtimaled.bbor.messages;
+
+import io.netty.buffer.ByteBuf;
+import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
+
+public class InitializeClientMessage implements IMessage {
+
+ private long seed;
+
+ public static InitializeClientMessage from(long seed) {
+ InitializeClientMessage message = new InitializeClientMessage();
+ message.seed = seed;
+ return message;
+ }
+
+ @Override
+ public void fromBytes(ByteBuf buf) {
+ seed = buf.readLong();
+ }
+
+ @Override
+ public void toBytes(ByteBuf buf) {
+ buf.writeLong(seed);
+ }
+
+ public long getSeed() {
+ return seed;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.messages;
+
+import com.irtimaled.bbor.BoundingBoxOutlineReloaded;
+import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
+import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
+import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
+
+public class InitializeClientMessageHandler implements IMessageHandler<InitializeClientMessage, IMessage> {
+ @Override
+ public IMessage onMessage(InitializeClientMessage message, MessageContext ctx) {
+ BoundingBoxOutlineReloaded.proxy.setSeed(message.getSeed());
+ return null;
+ }
+}