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;
9 import net.minecraft.world.WorldServer;
13 class VillageProcessor {
14 private final BoundingBoxCache boundingBoxCache;
16 private Map<Integer, BoundingBoxVillage> villageCache = new HashMap<>();
17 private int dimensionId;
19 VillageProcessor(int dimensionId, BoundingBoxCache boundingBoxCache) {
20 this.dimensionId = dimensionId;
21 this.boundingBoxCache = boundingBoxCache;
24 void process(WorldServer world) {
25 Map<Integer, BoundingBoxVillage> oldVillages = new HashMap<>(villageCache);
26 Map<Integer, BoundingBoxVillage> newVillages = new HashMap<>();
27 VillageCollection villageCollection = world.getVillageCollection();
28 for (Village village : villageCollection.getVillageList()) {
29 int villageId = village.hashCode();
30 BoundingBoxVillage newVillage = oldVillages.get(villageId);
31 if (areEquivalent(village, newVillage)) {
32 oldVillages.remove(villageId);
34 newVillage = buildBoundingBox(village);
35 boundingBoxCache.addBoundingBox(newVillage);
37 newVillages.put(villageId, newVillage);
39 for (BoundingBoxVillage village : oldVillages.values()) {
40 boundingBoxCache.removeBoundingBox(village);
41 EventBus.publish(new VillageRemoved(dimensionId, village));
43 villageCache = newVillages;
46 private static Set<Coords> getDoorsFromVillage(Village village) {
47 Set<Coords> doors = new HashSet<>();
48 List<VillageDoorInfo> doorInfoList = village.getVillageDoorInfoList();
49 for (VillageDoorInfo doorInfo : doorInfoList) {
50 doors.add(new Coords(doorInfo.getDoorBlockPos()));
55 private boolean areEquivalent(Village village, BoundingBoxVillage newVillage) {
56 if (newVillage == null) return false;
57 Coords center = new Coords(village.getCenter());
58 int radius = village.getVillageRadius();
59 boolean spawnsIronGolems = VillageHelper.shouldSpawnIronGolems(village.getNumVillagers(), village.getNumVillageDoors());
60 Set<Coords> doors = getDoorsFromVillage(village);
61 int villageHash = VillageHelper.computeHash(center, radius, spawnsIronGolems, doors);
62 return newVillage.getVillageHash() == villageHash;
65 private BoundingBoxVillage buildBoundingBox(Village village) {
66 Coords center = new Coords(village.getCenter());
67 int radius = village.getVillageRadius();
68 Set<Coords> doors = getDoorsFromVillage(village);
69 return BoundingBoxVillage.from(center, radius, village.hashCode(), village.getNumVillagers(), doors);