improve chunk limit

This commit is contained in:
xGinko 2023-09-27 13:55:20 +02:00
parent ac197a73a1
commit 7103f21baf

View File

@ -1,8 +1,8 @@
package me.xginko.villageroptimizer.modules; package me.xginko.villageroptimizer.modules;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask; import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.VillagerCache; import me.xginko.villageroptimizer.VillagerCache;
import me.xginko.villageroptimizer.VillagerOptimizer;
import me.xginko.villageroptimizer.config.Config; import me.xginko.villageroptimizer.config.Config;
import me.xginko.villageroptimizer.utils.LogUtil; import me.xginko.villageroptimizer.utils.LogUtil;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -23,17 +23,13 @@ import java.util.logging.Level;
public class VillagerChunkLimit implements VillagerOptimizerModule, Listener { public class VillagerChunkLimit implements VillagerOptimizerModule, Listener {
/*
* TODO: expand villager chunk limit with settings for optimized and unoptimized.
* */
private final VillagerOptimizer plugin; private final VillagerOptimizer plugin;
private final VillagerCache villagerCache; private final VillagerCache villagerCache;
private ScheduledTask scheduledTask; private ScheduledTask scheduledTask;
private final List<Villager.Profession> removalPriority = new ArrayList<>(16); private final List<Villager.Profession> removalPriority = new ArrayList<>(16);
private final int global_max_villagers_per_chunk, max_unoptimized_per_chunk, max_optimized_per_chunk;
private final boolean logIsEnabled;
private final long check_period; private final long check_period;
private final int max_unoptimized_per_chunk, max_optimized_per_chunk;
private final boolean logIsEnabled;
protected VillagerChunkLimit() { protected VillagerChunkLimit() {
shouldEnable(); shouldEnable();
@ -44,10 +40,6 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener {
Checks chunks for too many villagers and removes excess villagers based on priority.\s Checks chunks for too many villagers and removes excess villagers based on priority.\s
Naturally, optimized villagers will be picked last since they don't affect performance\s Naturally, optimized villagers will be picked last since they don't affect performance\s
as much as unoptimized villagers."""); as much as unoptimized villagers.""");
this.global_max_villagers_per_chunk = config.getInt("villager-chunk-limit.global-max-villagers-per-chunk", 50, """
The total amount of villagers, no matter if optimized or unoptimized per chunk.\s
You want this number to be minimum as high as the sum of optimized and unoptimized\s
per chunk if you don't want to risk deleting the wrong villagers.""");
this.max_unoptimized_per_chunk = config.getInt("villager-chunk-limit.max-unoptimized-per-chunk", 30, this.max_unoptimized_per_chunk = config.getInt("villager-chunk-limit.max-unoptimized-per-chunk", 30,
"The maximum amount of unoptimized villagers per chunk."); "The maximum amount of unoptimized villagers per chunk.");
this.max_optimized_per_chunk = config.getInt("villager-chunk-limit.max-optimized-per-chunk", 20, this.max_optimized_per_chunk = config.getInt("villager-chunk-limit.max-optimized-per-chunk", 20,
@ -111,32 +103,53 @@ public class VillagerChunkLimit implements VillagerOptimizerModule, Listener {
} }
private void checkVillagersInChunk(Chunk chunk) { private void checkVillagersInChunk(Chunk chunk) {
// Create a list with all villagers in that chunk // Create lists with all optimized and unoptimzed villagers in that chunk
List<Villager> villagers_in_chunk = new ArrayList<>(); List<Villager> unoptimized_villagers = new ArrayList<>();
List<Villager> optimized_villagers = new ArrayList<>();
// Collect villagers accordingly
for (Entity entity : chunk.getEntities()) { for (Entity entity : chunk.getEntities()) {
if (entity.getType().equals(EntityType.VILLAGER)) { if (entity.getType().equals(EntityType.VILLAGER)) {
villagers_in_chunk.add((Villager) entity); Villager villager = (Villager) entity;
if (villagerCache.getOrAdd(villager).isOptimized()) {
optimized_villagers.add(villager);
} else {
unoptimized_villagers.add(villager);
}
} }
} }
// Check if there are more villagers in that chunk than allowed // Check if there are more unoptimized villagers in that chunk than allowed
int amount_over_the_limit = villagers_in_chunk.size() - global_max_villagers_per_chunk; int unoptimized_vils_too_many = unoptimized_villagers.size() - max_unoptimized_per_chunk;
if (amount_over_the_limit <= 0) return; if (unoptimized_vils_too_many > 0) {
// Sort villagers by profession priority
// Sort villager list by profession priority unoptimized_villagers.sort(Comparator.comparingInt(this::getProfessionPriority));
villagers_in_chunk.sort(Comparator.comparingInt(this::getProfessionPriority));
// Remove prioritized villagers that are too many // Remove prioritized villagers that are too many
for (int i = 0; i < amount_over_the_limit; i++) { for (int i = 0; i < unoptimized_vils_too_many; i++) {
Villager villager = villagers_in_chunk.get(i); Villager villager = unoptimized_villagers.get(i);
villager.remove(); villager.remove();
if (logIsEnabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit", if (logIsEnabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit",
"Removed villager of profession type '"+villager.getProfession()+"' at "+villager.getLocation()); "Removed unoptimized villager of profession type '"+villager.getProfession().name()+"' at "+villager.getLocation());
}
}
// Check if there are more optimized villagers in that chunk than allowed
int optimized_vils_too_many = optimized_villagers.size() - max_optimized_per_chunk;
if (optimized_vils_too_many > 0) {
// Sort villagers by profession priority
optimized_villagers.sort(Comparator.comparingInt(this::getProfessionPriority));
// Remove prioritized villagers that are too many
for (int i = 0; i < optimized_vils_too_many; i++) {
Villager villager = unoptimized_villagers.get(i);
villager.remove();
if (logIsEnabled) LogUtil.moduleLog(Level.INFO, "villager-chunk-limit",
"Removed optimized villager of profession type '"+villager.getProfession().name()+"' at "+villager.getLocation());
}
} }
} }
private int getProfessionPriority(Villager villager) { private int getProfessionPriority(Villager villager) {
final Villager.Profession profession = villager.getProfession(); final Villager.Profession profession = villager.getProfession();
return removalPriority.contains(profession) && !villagerCache.getOrAdd(villager).isOptimized() ? removalPriority.indexOf(profession) : Integer.MAX_VALUE; return removalPriority.contains(profession) ? removalPriority.indexOf(profession) : Integer.MAX_VALUE;
} }
} }