Uses persistent hashcode of villages to get the right color. If the village is 'new' it'll fallback to checking for the village by it's doors!
import net.minecraft.util.BlockPos;
import java.awt.*;
+import java.util.Set;
public class BoundingBoxVillage extends BoundingBox {
private final BlockPos center;
private final Integer radius;
private final boolean spawnsIronGolems;
+ private Set<BlockPos> doors;
- private static int colorIndex = 0;
-
- protected BoundingBoxVillage(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, BlockPos minBlockPos, BlockPos maxBlockPos) {
+ protected 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;
}
+ public static BoundingBoxVillage from(BlockPos center, Integer radius, int population, Set<BlockPos> doors) {
+ return from(center, radius, null, population, doors);
+ }
- public static BoundingBox from(BlockPos center, Integer radius, int numVillagers, int numVillageDoors) {
- Color color = getVillageColor(colorIndex % 6);
- ++colorIndex;
- Boolean spawnsIronGolems = numVillagers >= 10 && numVillageDoors >= 21;
- return from(center, radius, spawnsIronGolems, color);
+ 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 BoundingBox from(BlockPos center, Integer radius, boolean spawnsIronGolems, Color color) {
+ 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,
center.getZ() - radius);
BlockPos maxBlockPos = new BlockPos(center.getX() + radius,
center.getY() + 4,
center.getZ() + radius);
- return new BoundingBoxVillage(center, radius, color, spawnsIronGolems, minBlockPos, maxBlockPos);
+ if (color == null)
+ color = getNextColor();
+ return new BoundingBoxVillage(center, radius, color, spawnsIronGolems, doors, minBlockPos, maxBlockPos);
}
@Override
return center;
}
+ @Override
+ public int hashCode() {
+ return center.hashCode();
+ }
+
public boolean getSpawnsIronGolems() {
return spawnsIronGolems;
}
- private static Color getVillageColor(int c) {
- switch (c) {
+ private static int colorIndex = -1;
+
+ public static Color getNextColor() {
+ ++colorIndex;
+ switch (colorIndex % 6) {
case 0:
return Color.RED;
case 1:
- return Color.MAGENTA;
+ return Color.GREEN;
case 2:
return Color.BLUE;
case 3:
- return Color.CYAN;
+ return Color.MAGENTA;
case 4:
- return Color.GREEN;
- case 5:
return Color.YELLOW;
+ case 5:
+ return Color.CYAN;
}
return Color.WHITE;
}
+
+ public Set<BlockPos> getDoors() {
+ return doors;
+ }
}
\ No newline at end of file
for (NBTTagCompound village : villages) {
BlockPos center = new BlockPos(village.getInteger("CX"), village.getInteger("CY"), village.getInteger("CZ"));
int radius = village.getInteger("Radius");
- int numVillagers = village.getInteger("PopSize");
- int numVillageDoors = village.getTagList("Doors", 10).tagCount();
- BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, numVillagers, numVillageDoors);
+ int population = village.getInteger("PopSize");
+ Set<BlockPos> doors = getDoors(village);
+ BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, population, doors);
cache.addBoundingBox(boundingBox);
}
Logger.info("Loaded %s (%d villages)", fileName, villages.length);
}
+ private Set<BlockPos> getDoors(NBTTagCompound village) {
+ Set<BlockPos> doors = new HashSet<BlockPos>();
+ for (NBTTagCompound door : getChildCompoundTags(village, "Doors")) {
+ doors.add(new BlockPos(door.getInteger("X"), door.getInteger("Y"), door.getInteger("Z")));
+ }
+ return doors;
+ }
+
private void loadStructureNbtFile(File localStructuresFolder, BoundingBoxCache cache, String fileName, Color color, String id) {
File file = new File(localStructuresFolder, fileName);
NBTTagCompound nbt = loadNbtFile(file);
import net.minecraft.util.BlockPos;
import net.minecraft.village.Village;
+import net.minecraft.village.VillageDoorInfo;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
this.world = world;
this.dimensionId = dimensionId;
this.chunkProvider = chunkProvider;
- villageCache = new HashSet<BoundingBox>();
+ villageCache = new HashMap<Integer, BoundingBoxVillage>();
slimeChunkCache = new HashSet<BoundingBox>();
worldSpawnCache = new HashSet<BoundingBox>();
}
private int dimensionId;
private IChunkProvider chunkProvider;
- private Set<BoundingBox> villageCache;
+ private Map<Integer, BoundingBoxVillage> villageCache;
private Set<BoundingBox> slimeChunkCache;
private Set<BoundingBox> worldSpawnCache;
if (configManager.drawVillages.getBoolean() &&
(world.getVillageCollection() != null)) {
- Set<BoundingBox> villageBoundingBoxes = new HashSet<BoundingBox>();
+ Map<Integer, BoundingBoxVillage> villageBoundingBoxes = new HashMap<Integer, BoundingBoxVillage>();
List<Village> villages = world.getVillageCollection().getVillageList();
- int c = 0;
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;
+ }
+ color = boundingBoxVillage.getColor();
+ }
+
Integer radius = village.getVillageRadius();
- int numVillagers = village.getNumVillagers();
- int numVillageDoors = village.getNumVillageDoors();
- villageBoundingBoxes.add(BoundingBoxVillage.from(center, radius, numVillagers, numVillageDoors));
+ int population = village.getNumVillagers();
+ Set<BlockPos> doors = getDoorsFromVillage(village);
+
+ if (color == null) {
+ //this should never happen but falls back to finding village by doors
+ BoundingBoxVillage oldBB = matchVillageByDoors(doors);
+ if (oldBB != null) {
+ color = oldBB.getColor();
+ }
+ }
+ villageBoundingBoxes.put(villageId, BoundingBoxVillage.from(center, radius, color, population, doors));
}
processDelta(villageCache, villageBoundingBoxes);
-
villageCache = villageBoundingBoxes;
}
}
- private void processDelta(Set<BoundingBox> oldBoundingBoxes, Set<BoundingBox> newBoundingBoxes) {
- for (BoundingBox bb : oldBoundingBoxes) {
- if (!newBoundingBoxes.contains(bb)) {
- removeBoundingBox(bb);
- eventHandler.boundingBoxRemoved(bb);
- } else {
- if (!isCached(bb)) {
- addBoundingBox(bb);
- }
+ protected BoundingBoxVillage matchVillageByDoors(Set<BlockPos> villageDoors) {
+ for (BoundingBoxVillage bb : villageCache.values()) {
+ Set<BlockPos> doors = bb.getDoors();
+ for (BlockPos door : villageDoors) {
+ if (doors.contains(door))
+ return bb;
}
}
+ return null;
+ }
+
+ private Set<BlockPos> getDoorsFromVillage(Village village) {
+ Set<BlockPos> doors = new HashSet<BlockPos>();
+ for (Object doorInfo : village.getVillageDoorInfoList()) {
+ doors.add(((VillageDoorInfo) doorInfo).getDoorBlockPos());
+ }
+ return doors;
+ }
+
+ private void processDelta(Map<Integer, BoundingBoxVillage> oldVillages, Map<Integer, BoundingBoxVillage> newVillages) {
+ for (BoundingBox village : oldVillages.values()) {
+ removeBoundingBox(village);
+ eventHandler.boundingBoxRemoved(village);
+ }
+ for (BoundingBox village : newVillages.values()) {
+ if (!isCached(village))
+ addBoundingBox(village);
+ }
}
}
\ No newline at end of file
int radius = ByteBufUtils.readVarInt(buf, 5);
boolean spawnsIronGolems = ByteBufUtils.readVarShort(buf) == 1;
Color color = new Color(ByteBufUtils.readVarInt(buf, 5));
- return BoundingBoxVillage.from(center, radius, spawnsIronGolems, color);
+ return BoundingBoxVillage.from(center, radius, color, spawnsIronGolems, null);
}
private static BlockPos deserializeBlockPos(ByteBuf buf) {