1 package com.irtimaled.bbor.common;
3 import com.irtimaled.bbor.common.events.VillageRemoved;
4 import com.irtimaled.bbor.common.models.BoundingBoxVillage;
5 import com.irtimaled.bbor.common.models.Coords;
6 import net.minecraft.village.Village;
7 import net.minecraft.village.VillageCollection;
8 import net.minecraft.village.VillageDoorInfo;
12 class VillageProcessor {
13 private final BoundingBoxCache boundingBoxCache;
15 private Map<Integer, BoundingBoxVillage> villageCache = new HashMap<>();
16 private int dimensionId;
18 VillageProcessor(int dimensionId, BoundingBoxCache boundingBoxCache) {
19 this.dimensionId = dimensionId;
20 this.boundingBoxCache = boundingBoxCache;
23 void process(VillageCollection villageCollection) {
24 Map<Integer, BoundingBoxVillage> oldVillages = new HashMap<>(villageCache);
25 Map<Integer, BoundingBoxVillage> newVillages = new HashMap<>();
26 for (Village village : villageCollection.getVillageList()) {
27 int villageId = village.hashCode();
28 BoundingBoxVillage newVillage = oldVillages.get(villageId);
29 if (areEquivalent(village, newVillage)) {
30 oldVillages.remove(villageId);
32 newVillage = buildBoundingBox(village);
33 boundingBoxCache.addBoundingBox(newVillage);
35 newVillages.put(villageId, newVillage);
37 for (BoundingBoxVillage village : oldVillages.values()) {
38 boundingBoxCache.removeBoundingBox(village);
39 EventBus.publish(new VillageRemoved(dimensionId, village));
41 villageCache = newVillages;
44 private static Set<Coords> getDoorsFromVillage(Village village) {
45 Set<Coords> doors = new HashSet<>();
46 List<VillageDoorInfo> doorInfoList = village.getVillageDoorInfoList();
47 for (VillageDoorInfo doorInfo : doorInfoList) {
48 doors.add(new Coords(doorInfo.getDoorBlockPos()));
53 private boolean areEquivalent(Village village, BoundingBoxVillage newVillage) {
54 if (newVillage == null) return false;
55 Coords center = new Coords(village.getCenter());
56 int radius = village.getVillageRadius();
57 boolean spawnsIronGolems = VillageHelper.shouldSpawnIronGolems(village.getNumVillagers(), village.getNumVillageDoors());
58 Set<Coords> doors = getDoorsFromVillage(village);
59 int villageHash = VillageHelper.computeHash(center, radius, spawnsIronGolems, doors);
60 return newVillage.getVillageHash() == villageHash;
63 private BoundingBoxVillage buildBoundingBox(Village village) {
64 Coords center = new Coords(village.getCenter());
65 int radius = village.getVillageRadius();
66 Set<Coords> doors = getDoorsFromVillage(village);
67 return BoundingBoxVillage.from(center, radius, village.hashCode(), village.getNumVillagers(), doors);