]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
Process villages more frequently
authorirtimaled <irtimaled@gmail.com>
Thu, 28 Dec 2017 08:28:19 +0000 (00:28 -0800)
committerirtimaled <irtimaled@gmail.com>
Sat, 30 Dec 2017 03:48:26 +0000 (19:48 -0800)
java/com/irtimaled/bbor/client/BoundingBoxOutlineReloaded.java
java/com/irtimaled/bbor/client/ClientProxy.java
java/com/irtimaled/bbor/common/CommonProxy.java
java/com/irtimaled/bbor/common/DimensionProcessor.java
java/com/irtimaled/bbor/common/VillageColorCache.java [new file with mode: 0644]
java/com/irtimaled/bbor/common/VillageProcessor.java [new file with mode: 0644]
java/com/irtimaled/bbor/common/models/BoundingBoxVillage.java
java/com/irtimaled/bbor/forge/ForgeCommonProxy.java

index a97f7f8f534be3ca7ddf665f6f86eae4b124f31f..06a260354c5e214baf0e026d2f8452747517b11e 100644 (file)
@@ -30,6 +30,7 @@ public class BoundingBoxOutlineReloaded {
     }
 
     public static void render(float partialTicks) {
+        proxy.tick();
         proxy.render(partialTicks);
     }
 
index 35955a790fe9fad42e6dd5a6bb6f8edd3e2544ca..46991169cdaab04bd08b57744d080592d0a28c86 100644 (file)
@@ -3,6 +3,8 @@ 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.VillageColorCache;
+import com.irtimaled.bbor.common.VillageProcessor;
 import com.irtimaled.bbor.common.StructureType;
 import com.irtimaled.bbor.common.models.*;
 import com.irtimaled.bbor.config.ConfigManager;
@@ -176,7 +178,7 @@ public class ClientProxy extends CommonProxy {
             int radius = village.getInteger("Radius");
             int population = village.getInteger("PopSize");
             Set<BlockPos> doors = getDoors(village);
-            BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, population, doors);
+            BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, village.hashCode(), population, doors);
             cache.addBoundingBox(boundingBox);
         }
 
@@ -256,7 +258,9 @@ public class ClientProxy extends CommonProxy {
         worldSpawnBoundingBox = null;
         spawnChunksBoundingBox = null;
         lazySpawnChunksBoundingBox = null;
+        VillageColorCache.clear();
         dimensionCache.clear();
+        villageProcessors.forEach(VillageProcessor::clear);
     }
 
     private void renderBoundingBoxes(Map<BoundingBox, Set<BoundingBox>> map, Set<BoundingBox> clientBoundingBoxes) {
index db749d6061044692f708ab55c4002427e5b26e92..fc4aab8d4d6f6d92f1fc59164f9ef323138d0d9d 100644 (file)
@@ -2,6 +2,7 @@ package com.irtimaled.bbor.common;
 
 import com.irtimaled.bbor.Logger;
 import com.irtimaled.bbor.ReflectionHelper;
+import com.irtimaled.bbor.config.ConfigManager;
 import net.minecraft.world.DimensionType;
 import net.minecraft.world.World;
 import net.minecraft.world.chunk.Chunk;
@@ -9,8 +10,12 @@ import net.minecraft.world.chunk.IChunkProvider;
 import net.minecraft.world.gen.ChunkProviderServer;
 import net.minecraft.world.gen.IChunkGenerator;
 
+import java.util.HashSet;
+import java.util.Set;
+
 public class CommonProxy {
     protected DimensionCache dimensionCache = new DimensionCache();
+    protected Set<VillageProcessor> villageProcessors = new HashSet<>();
 
     private IVillageEventHandler eventHandler = null;
 
@@ -21,8 +26,11 @@ public class CommonProxy {
             dimensionCache.setWorldData(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(), world.getSeed());
-            DimensionProcessor boundingBoxCache = new DimensionProcessor(eventHandler, world, dimensionType, chunkGenerator);
+            DimensionProcessor boundingBoxCache = new DimensionProcessor(dimensionType, chunkGenerator);
             dimensionCache.put(dimensionType, boundingBoxCache);
+            if (ConfigManager.drawVillages.getBoolean()) {
+                villageProcessors.add(new VillageProcessor(world, dimensionType, eventHandler, boundingBoxCache));
+            }
         }
     }
 
@@ -31,6 +39,10 @@ public class CommonProxy {
         dimensionCache.refresh(dimensionType);
     }
 
+    public void tick() {
+        villageProcessors.forEach(VillageProcessor::process);
+    }
+
     public void init() {
     }
 
index 108586e5e5dd25d08e21bd5329590de7e963c81c..7ea59c411d4e9dde23faac7025d0e701e6148252 100644 (file)
@@ -4,14 +4,9 @@ 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;
@@ -20,27 +15,15 @@ import net.minecraft.world.gen.structure.*;
 
 import java.awt.*;
 import java.util.*;
-import java.util.List;
 
 public class DimensionProcessor extends BoundingBoxCache {
-    private World world;
-    private IVillageEventHandler eventHandler;
-
-    DimensionProcessor(IVillageEventHandler eventHandler, World world, DimensionType dimensionType, IChunkGenerator chunkGenerator) {
-        this.eventHandler = eventHandler;
-        this.world = world;
+    DimensionProcessor(DimensionType dimensionType, IChunkGenerator chunkGenerator) {
         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;
 
@@ -48,9 +31,6 @@ public class DimensionProcessor extends BoundingBoxCache {
     public void close() {
         closed = true;
         chunkGenerator = null;
-        villageCache.clear();
-        slimeChunkCache.clear();
-        worldSpawnCache.clear();
         super.close();
     }
 
@@ -133,59 +113,10 @@ public class DimensionProcessor extends BoundingBoxCache {
                             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;
+                        Logger.info("[%s] new dimensionCache entries: %d", dimensionType, structureBoundingBoxes.size());
                     }
-                    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.villageRemoved(this.dimensionType, village);
-            }
-        }
-        for (BoundingBox village : newVillages.values()) {
-            if (!isCached(village))
-                addBoundingBox(village);
         }
     }
 }
diff --git a/java/com/irtimaled/bbor/common/VillageColorCache.java b/java/com/irtimaled/bbor/common/VillageColorCache.java
new file mode 100644 (file)
index 0000000..464773b
--- /dev/null
@@ -0,0 +1,39 @@
+package com.irtimaled.bbor.common;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.Map;
+
+public class VillageColorCache {
+    private static int colorIndex = -1;
+
+    public static void clear() {
+        colorIndex = -1;
+        villageColorCache.clear();
+    }
+
+    private 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;
+    }
+
+    private static Map<Integer, Color> villageColorCache = new HashMap<>();
+
+    public static Color getColor(int villageId) {
+        return villageColorCache.computeIfAbsent(villageId, k -> getNextColor());
+    }
+}
diff --git a/java/com/irtimaled/bbor/common/VillageProcessor.java b/java/com/irtimaled/bbor/common/VillageProcessor.java
new file mode 100644 (file)
index 0000000..5dd0109
--- /dev/null
@@ -0,0 +1,60 @@
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
+import net.minecraft.village.Village;
+import net.minecraft.village.VillageCollection;
+import net.minecraft.world.DimensionType;
+import net.minecraft.world.World;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class VillageProcessor {
+    private final World world;
+    private final DimensionType dimensionType;
+    private final IVillageEventHandler eventHandler;
+    private BoundingBoxCache boundingBoxCache;
+    private Map<Integer, BoundingBoxVillage> villageCache = new HashMap<>();
+
+    VillageProcessor(World world, DimensionType dimensionType, IVillageEventHandler eventHandler, BoundingBoxCache boundingBoxCache) {
+        this.world = world;
+        this.dimensionType = dimensionType;
+        this.eventHandler = eventHandler;
+        this.boundingBoxCache = boundingBoxCache;
+    }
+
+    synchronized void process() {
+        Map<Integer, BoundingBoxVillage> oldVillages = new HashMap<>(villageCache);
+        Map<Integer, BoundingBoxVillage> newVillages = new HashMap<>();
+        VillageCollection villageCollection = world.getVillageCollection();
+        if (villageCollection != null) {
+            List<Village> villages = villageCollection.getVillageList();
+            for (Village village : villages) {
+                int villageId = village.hashCode();
+                BoundingBoxVillage newVillage = oldVillages.get(villageId);
+                if (newVillage != null && newVillage.matches(village)) {
+                    oldVillages.remove(villageId);
+                } else {
+                    newVillage = BoundingBoxVillage.from(village);
+                }
+                newVillages.put(villageId, newVillage);
+            }
+
+        }
+        for (BoundingBoxVillage village : oldVillages.values()) {
+            boundingBoxCache.removeBoundingBox(village);
+            if (eventHandler != null) {
+                eventHandler.villageRemoved(dimensionType, village);
+            }
+        }
+        for (BoundingBoxVillage village : newVillages.values()) {
+            boundingBoxCache.addBoundingBox(village);
+        }
+        villageCache = newVillages;
+    }
+
+    public void clear() {
+        villageCache.clear();
+    }
+}
index a2ebcfa2839c435ebcb1d8d8f56cfc43ba66d102..95a8f4e05b47993d8822cdd7e1f0a69131c6bd97 100644 (file)
@@ -1,8 +1,12 @@
 package com.irtimaled.bbor.common.models;
 
+import com.irtimaled.bbor.common.VillageColorCache;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.village.Village;
+import net.minecraft.village.VillageDoorInfo;
 
 import java.awt.*;
+import java.util.HashSet;
 import java.util.Set;
 
 public class BoundingBoxVillage extends BoundingBox {
@@ -12,25 +16,18 @@ public class BoundingBoxVillage extends BoundingBox {
     private Set<BlockPos> doors;
     private Double centerOffsetX;
     private Double centerOffsetZ;
+    private int villageHash;
 
-    protected BoundingBoxVillage(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors, BlockPos minBlockPos, BlockPos maxBlockPos) {
+    private 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;
+        this.villageHash = computeHash(center, radius, spawnsIronGolems, 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,
@@ -38,11 +35,35 @@ public class BoundingBoxVillage extends BoundingBox {
         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);
     }
 
+    public static BoundingBoxVillage from(BlockPos center, Integer radius, int villageId, int population, Set<BlockPos> doors) {
+        Boolean spawnsIronGolems = shouldSpawnIronGolems(population, doors.size());
+        Color color = VillageColorCache.getColor(villageId);
+        return from(center, radius, color, spawnsIronGolems, doors);
+    }
+
+    private static boolean shouldSpawnIronGolems(int population, int doorCount) {
+        return population >= 10 && doorCount >= 21;
+    }
+
+    public static BoundingBoxVillage from(Village village) {
+        BlockPos center = village.getCenter();
+        int radius = village.getVillageRadius();
+        Set<BlockPos> doors = getDoorsFromVillage(village);
+        return from(center, radius, village.hashCode(), village.getNumVillagers(), doors);
+    }
+
+    private static 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 calculateCenterOffsets(Set<BlockPos> doors) {
         boolean processedFirstDoor = false;
         int minX = 0;
@@ -90,39 +111,31 @@ public class BoundingBoxVillage extends BoundingBox {
         return centerOffsetZ;
     }
 
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = super.hashCode();
+    private static int computeHash(BlockPos center, Integer radius, boolean spawnsIronGolems, Set<BlockPos> doors) {
+        int result = (center.hashCode() * 31) + radius;
         for (BlockPos door : doors) {
-            result = prime * result + door.hashCode();
+            result = (31 * result) + door.hashCode();
+        }
+        if (spawnsIronGolems) {
+            result = 31 * result;
         }
         return result;
     }
 
-    public boolean getSpawnsIronGolems() {
-        return spawnsIronGolems;
+    public boolean matches(Village village) {
+        return this.villageHash == computeHash(village.getCenter(),
+                village.getVillageRadius(),
+                shouldSpawnIronGolems(village.getNumVillagers(), village.getNumVillageDoors()),
+                getDoorsFromVillage(village));
     }
 
-    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;
+    @Override
+    public int hashCode() {
+        return (super.hashCode() * 31) + villageHash;
+    }
+
+    public boolean getSpawnsIronGolems() {
+        return spawnsIronGolems;
     }
 
     public Set<BlockPos> getDoors() {
index 234a61335ee9d6fba66c1c08a15afbdf86b4852d..3fefee8a496e5947c182edc573308713b8ecaea6 100644 (file)
@@ -126,6 +126,7 @@ public class ForgeCommonProxy implements IVillageEventHandler {
                 sendToPlayer(player, getDimensionCache().getBoundingBoxes(dimensionType));
             }
         }
+        getProxy().tick();
     }
 
     private void sendToPlayer(EntityPlayerMP player, BoundingBoxCache boundingBoxCache) {