package com.irtimaled.bbor.common; import com.irtimaled.bbor.common.events.VillageRemoved; import com.irtimaled.bbor.common.models.BoundingBoxVillage; import com.irtimaled.bbor.common.models.Coords; import net.minecraft.village.Village; import net.minecraft.village.VillageCollection; import net.minecraft.village.VillageDoorInfo; import net.minecraft.world.WorldServer; import java.util.*; class VillageProcessor { private final BoundingBoxCache boundingBoxCache; private Map villageCache = new HashMap<>(); private int dimensionId; VillageProcessor(int dimensionId, BoundingBoxCache boundingBoxCache) { this.dimensionId = dimensionId; this.boundingBoxCache = boundingBoxCache; } void process(WorldServer world) { Map oldVillages = new HashMap<>(villageCache); Map newVillages = new HashMap<>(); VillageCollection villageCollection = world.getVillageCollection(); for (Village village : villageCollection.getVillageList()) { int villageId = village.hashCode(); BoundingBoxVillage newVillage = oldVillages.get(villageId); if (areEquivalent(village, newVillage)) { oldVillages.remove(villageId); } else { newVillage = buildBoundingBox(village); boundingBoxCache.addBoundingBox(newVillage); } newVillages.put(villageId, newVillage); } for (BoundingBoxVillage village : oldVillages.values()) { boundingBoxCache.removeBoundingBox(village); EventBus.publish(new VillageRemoved(dimensionId, village)); } villageCache = newVillages; } private static Set getDoorsFromVillage(Village village) { Set doors = new HashSet<>(); List doorInfoList = village.getVillageDoorInfoList(); for (VillageDoorInfo doorInfo : doorInfoList) { doors.add(new Coords(doorInfo.getDoorBlockPos())); } return doors; } private boolean areEquivalent(Village village, BoundingBoxVillage newVillage) { if (newVillage == null) return false; Coords center = new Coords(village.getCenter()); int radius = village.getVillageRadius(); boolean spawnsIronGolems = VillageHelper.shouldSpawnIronGolems(village.getNumVillagers(), village.getNumVillageDoors()); Set doors = getDoorsFromVillage(village); int villageHash = VillageHelper.computeHash(center, radius, spawnsIronGolems, doors); return newVillage.getVillageHash() == villageHash; } private BoundingBoxVillage buildBoundingBox(Village village) { Coords center = new Coords(village.getCenter()); int radius = village.getVillageRadius(); Set doors = getDoorsFromVillage(village); return BoundingBoxVillage.from(center, radius, village.hashCode(), village.getNumVillagers(), doors); } void clear() { villageCache.clear(); } }