From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Sat, 12 Sep 2020 19:17:05 +0300 Subject: [PATCH] Optimize Villagers These changes aim to fix the following: - Villagers trying to push farther POIs (Points Of Interest) - Villagers ignoring doors most of the times - Villagers pushing POIs (Points Of Interest) to unloaded chunks The following has been done to fix the mentioned problems: - Replaced stream off BehaviorFindPosition - Made sure that chunks are loaded for the POIs (Points Of Interest) that are gonna be tried. - Added a profession cache, which followed by a stream removal. diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFindPosition.java b/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFindPosition.java index 09133c5822bc1386bc3d8a5f3c94196420bbfaea..5397a74e244e9cd6886068e0dfe283ec12ccd922 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFindPosition.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/BehaviorFindPosition.java @@ -58,7 +58,7 @@ public class BehaviorFindPosition extends Behavior { if (this.d && entitycreature.isBaby()) { return false; } else if (this.f == 0L) { - this.f = entitycreature.world.getTime() + (long) worldserver.random.nextInt(20); + this.f = entitycreature.world.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Yatopia return false; } else { return worldserver.getTime() >= this.f; @@ -66,7 +66,7 @@ public class BehaviorFindPosition extends Behavior { } protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) { - this.f = i + 20L + (long) worldserver.getRandom().nextInt(20); + this.f = i + 20L + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Yatopia if (entitycreature.getNavigation().isStuck()) this.f += 200L; // Airplane - wait an additional 10s to check again if they're stuck VillagePlace villageplace = worldserver.y(); @@ -77,12 +77,20 @@ public class BehaviorFindPosition extends Behavior { BehaviorFindPosition.a behaviorfindposition_a = (BehaviorFindPosition.a) this.g.get(blockposition.asLong()); if (behaviorfindposition_a == null) { - return true; + return worldserver.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; // Yatopia } else if (!behaviorfindposition_a.c(i)) { return false; } else { - behaviorfindposition_a.a(i); - return true; + // Yatopia start - make sure chunks are loaded + int chunkX = blockposition.getX() >> 4; + int chunkZ = blockposition.getZ() >> 4; + if (worldserver.getChunkIfLoaded(chunkX, chunkZ) != null) { + behaviorfindposition_a.a(i); + return true; + } else { + return false; + } + // Yatopia end } }; // Tuinity start - optimise POI access @@ -113,7 +121,7 @@ public class BehaviorFindPosition extends Behavior { BlockPosition blockposition1 = (BlockPosition) iterator.next(); this.g.computeIfAbsent(blockposition1.asLong(), (j) -> { - return new BehaviorFindPosition.a(entitycreature.world.random, i); + return new BehaviorFindPosition.a(java.util.concurrent.ThreadLocalRandom.current(), i); // Yatopia }); } } diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlaceType.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlaceType.java index 6a45ab049a4beeeaf7b3b5acf2946767f6e1198f..4af526ecbed506161cb021ea320b0f21112d7bf0 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlaceType.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlaceType.java @@ -23,11 +23,20 @@ import net.minecraft.world.level.block.state.properties.BlockPropertyBedPart; public class VillagePlaceType { + public static Set professionCache; // Yatopia private static final Supplier> y = Suppliers.memoize(() -> { return (Set) IRegistry.VILLAGER_PROFESSION.g().map(VillagerProfession::b).collect(Collectors.toSet()); }); public static final Predicate a = (villageplacetype) -> { - return ((Set) VillagePlaceType.y.get()).contains(villageplacetype); + // Yatopia start + if (professionCache == null) { + professionCache = new java.util.HashSet<>(); + for (VillagerProfession profession : IRegistry.VILLAGER_PROFESSION) { + professionCache.add(profession.getPlaceType()); + } + } + return professionCache.contains(villageplacetype); + // Yatopia end }; public static final Predicate b = (villageplacetype) -> { return true; diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java index dd9b678481620856fb7eaaa04c3b812c861e892a..d8fc1795b07945b41bd7368529db92fe5cdc4c19 100644 --- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java +++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java @@ -44,6 +44,7 @@ public class VillagerProfession { this.t = soundeffect; } + public final VillagePlaceType getPlaceType() { return b(); } // Yatopia - OBFHELPER public VillagePlaceType b() { return this.q; } @@ -70,6 +71,7 @@ public class VillagerProfession { } static VillagerProfession a(String s, VillagePlaceType villageplacetype, ImmutableSet immutableset, ImmutableSet immutableset1, @Nullable SoundEffect soundeffect) { + VillagePlaceType.professionCache = null; // Yatopia return (VillagerProfession) IRegistry.a((IRegistry) IRegistry.VILLAGER_PROFESSION, new MinecraftKey(s), (Object) (new VillagerProfession(s, villageplacetype, immutableset, immutableset1, soundeffect))); } }