From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: M2ke4U <79621885+MrHua269@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:44:23 +0800 Subject: [PATCH] Pufferfish Dynamic Activation of Brain diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java index 11c1a367fbc25cb63738a00ad93fb0b0b3500e7d..4f6af1fa55047e7be9e57c1dd1c60e9d96d12187 100644 --- a/src/main/java/me/earthme/luminol/LuminolConfig.java +++ b/src/main/java/me/earthme/luminol/LuminolConfig.java @@ -11,13 +11,16 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; +import java.util.*; import java.util.logging.Level; import java.io.File; import java.io.IOException; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.server.MinecraftServer; +import org.bukkit.configuration.ConfigurationSection; +import net.minecraft.world.entity.EntityType; + public class LuminolConfig { private static final Logger logger = LogManager.getLogger(); private static final File PARENT_FOLDER = new File("luminol_config"); @@ -48,6 +51,12 @@ public class LuminolConfig { public static boolean enableSuffocationOptimization = true; public static int maxProjectileLoadsPerTick; public static int maxProjectileLoadsPerProjectile; + public static boolean dearEnabled; + public static int startDistance; + public static int startDistanceSquared; + public static int maximumActivationPrio; + public static int activationDistanceMod; + public static void init() throws IOException { PARENT_FOLDER.mkdir(); @@ -86,6 +95,33 @@ public class LuminolConfig { } } + private static void initDAB(){ + dearEnabled = get("optimizations.dab.enabled", true); + startDistance = get("optimizations.dab.start-distance", 12, + "This value determines how far away an entity has to be\n"+ + "from the player to start being effected by DEAR."); + startDistanceSquared = startDistance * startDistance; + maximumActivationPrio = get("optimizations.dab.max-tick-freq",20, + "This value defines how often in ticks, the furthest entity\n"+ + "will get their pathfinders and behaviors ticked. 20 = 1s"); + activationDistanceMod = get("optimizations.dab.activation-dist-mod",8, + """ + This value defines how much distance modifies an entity's + tick frequency. freq = (distanceToPlayer^2) / (2^value) + If you want further away entities to tick less often, use 7. + If you want further away entities to tick more often, try 9."""); + + for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { + entityType.dabEnabled = true; // reset all, before setting the ones to true + } + get("optimizations.dab.blacklisted-entities",Collections.emptyList(), "A list of entities to ignore for activation") + .forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> { + entityType.dabEnabled = false; + }, () -> MinecraftServer.LOGGER.warn("Unknown entity \"" + name + "\""))); + + MAIN_CONFIG.setComment("optimizations.dab", "Optimizes entity brains when\n"+"they're far away from the player"); + } + public static void initValues(){ serverModName = get("misc.server_mod_name",serverModName,"The servermod name will be sent to players,and you can see it in F3 or motd responses"); fakeVanillaModeEnabled = get("misc.enable_fake_vanilla_mode",fakeVanillaModeEnabled,"Enable this to make the ping response of your server like a vanilla server"); @@ -130,6 +166,7 @@ public class LuminolConfig { initEntityTTL(); maxProjectileLoadsPerTick = get("optimizations.projectile.max-loads-per-tick", maxProjectileLoadsPerTick, "Controls how many chunks are allowed \nto be sync loaded by projectiles in a tick."); maxProjectileLoadsPerProjectile = get("optimizations.projectile.max-loads-per-projectile", maxProjectileLoadsPerProjectile, "Controls how many chunks a projectile \n can load in its lifetime before it gets \nautomatically removed."); + initDAB(); } public static T get(String key,T def){ diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 561681deaf647277ecde64eed4cfbd9f38b5fed1..2ba86122ccb444908c35ea5cc1e245f5068a054a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -982,6 +982,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.timings.entityTick.startTiming(); // Spigot profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler regionizedWorldData.forEachTickingEntity((entity) -> { // Folia - regionised ticking + entity.activatedPriorityReset = false; // Pufferfish - DAB if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 8bdaab46c2e128aa58d13101170ce358146377a8..56efbcc29adca0239ef09a269f0899a3a6e2801b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -436,6 +436,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return this.originWorld; } // Paper end + // Pufferfish start + public boolean activatedPriorityReset = false; // DAB + public int activatedPriority = LuminolConfig.maximumActivationPrio; // golf score + // Pufferfish end + public float getBukkitYaw() { return this.yRot; } diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java index 4d60ac50a1d3860f2a2e9265aef9507d790220a3..0867c85964952ec118ea7517cd5ef570be1ee982 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -301,6 +301,7 @@ public class EntityType implements FeatureElement, EntityTypeT private final boolean canSpawnFarFromPlayer; private final int clientTrackingRange; private final int updateInterval; + public boolean dabEnabled = false; // Pufferfish @Nullable private String descriptionId; @Nullable diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java index d3f8aa29b05a3813c0ec6e2ea5a253868abd6b07..54e821351e46d25e8b0ead52d2c8dfecd1957544 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -234,10 +234,10 @@ public abstract class Mob extends LivingEntity implements Targeting { @Override public void inactiveTick() { super.inactiveTick(); - if (this.goalSelector.inactiveTick()) { + if (this.goalSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priroity this.goalSelector.tick(); } - if (this.targetSelector.inactiveTick()) { + if (this.targetSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priority this.targetSelector.tick(); } } @@ -934,16 +934,20 @@ public abstract class Mob extends LivingEntity implements Targeting { if (i % 2 != 0 && this.tickCount > 1) { this.level().getProfiler().push("targetSelector"); + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tickRunningGoals(false); this.level().getProfiler().pop(); this.level().getProfiler().push("goalSelector"); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tickRunningGoals(false); this.level().getProfiler().pop(); } else { this.level().getProfiler().push("targetSelector"); + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); this.level().getProfiler().pop(); this.level().getProfiler().push("goalSelector"); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tick(); this.level().getProfiler().pop(); } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java index b738ee2d3801fadfd09313f05ae24593e56b0ec6..9306ab8d2b6eeb73f86d4d94c0065d461905d702 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java @@ -11,6 +11,8 @@ import java.util.Set; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Stream; + +import me.earthme.luminol.LuminolConfig; import net.minecraft.util.profiling.ProfilerFiller; import org.slf4j.Logger; @@ -53,9 +55,12 @@ public class GoalSelector { } // Paper start - public boolean inactiveTick() { + public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start + if (inactive && !LuminolConfig.dearEnabled) tickRate = 4; // reset to Paper's + tickRate = Math.min(tickRate, this.newGoalRate); this.curRate++; - return this.curRate % this.newGoalRate == 0; + return this.curRate % tickRate == 0; + // Pufferfish end } public boolean hasTasks() { for (WrappedGoal task : this.availableGoals) { diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java index 5ad5f22e5aa26445e5eb229958e7bf356bdd460e..d241ca4d0295f9fce39c11197bd435cfac7f6e54 100644 --- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java @@ -221,9 +221,11 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS return 0.4F; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { this.level().getProfiler().push("allayBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); this.level().getProfiler().pop(); this.level().getProfiler().push("allayActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java index d5b97d4316390028f54aa9bb9fa52b0b003e32a0..b4793b88688bd568a428aa520e880f0038de45a7 100644 --- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java +++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java @@ -280,9 +280,11 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder { return true; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { this.level().getProfiler().push("frogBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel)this.level(), this); this.level().getProfiler().pop(); this.level().getProfiler().push("frogActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java index 4aeab90e778629c355189dfe79c39c4b21f5f5ac..6ed4ac06c76b8d0d6e8db778cade15dbd1e3e5f5 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java @@ -77,9 +77,11 @@ public class Tadpole extends AbstractFish { return SoundEvents.TADPOLE_FLOP; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { this.level().getProfiler().push("tadpoleBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); this.level().getProfiler().pop(); this.level().getProfiler().push("tadpoleActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java index 111a244087e24f25ba8524a46a228da10cd9498a..ff12ba2b79cb2e7e0bfd0e3b58ff6cb9e770092b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java +++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java @@ -191,9 +191,11 @@ public class Goat extends Animal { return (Brain) super.getBrain(); // CraftBukkit - decompile error } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { this.level().getProfiler().push("goatBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); this.level().getProfiler().pop(); this.level().getProfiler().push("goatActivityUpdate"); diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java index 4257f2282152aee09533c9a2e53018d3e49effa4..e703320717ff620a19ff76d1c10066117c9895d5 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java @@ -128,9 +128,11 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { return (Brain) super.getBrain(); // Paper - decompile fix } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { this.level().getProfiler().push("hoglinBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel)this.level(), this); this.level().getProfiler().pop(); HoglinAi.updateActivity(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java index 6407ddef8442fce4f310ac4babf3e3de0dd5fc9a..cfdc1650783d6855e0d4f33ec68aab48dbee09f0 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java @@ -300,9 +300,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento return !this.cannotHunt; } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { this.level().getProfiler().push("piglinBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); this.level().getProfiler().pop(); PiglinAi.updateActivity(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java index b2bc3a832c310448046ccde37a04918aa6d63197..5e43912708f9074dee1bb351efa737a7e6796fc3 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java @@ -272,11 +272,13 @@ public class Warden extends Monster implements VibrationSystem { } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { ServerLevel worldserver = (ServerLevel) this.level(); worldserver.getProfiler().push("wardenBrain"); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick(worldserver, this); this.level().getProfiler().pop(); super.customServerAiStep(); diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java index 4e9ccc518f37755e86687653f7724240db754682..a94661deaa6e1288bb957dc5d7711c5d03b9e460 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -142,6 +142,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return holder.is(PoiTypes.MEETING); }); + public long nextGolemPanic = -1; // Pufferfish + public Villager(EntityType entityType, Level world) { this(entityType, world, VillagerType.PLAINS); } @@ -245,6 +247,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } // Spigot End + private int behaviorTick = 0; // Pufferfish @Override @Deprecated // Paper protected void customServerAiStep() { @@ -254,7 +257,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler protected void customServerAiStep(final boolean inactive) { // Paper end this.level().getProfiler().push("villagerBrain"); - if (!inactive) this.getBrain().tick((ServerLevel) this.level(), this); // Paper + // Pufferfish start + if (!inactive && this.behaviorTick++ % this.activatedPriority == 0) { + this.getBrain().tick((ServerLevel) this.level(), this); // Paper + } + // Pufferfish end this.level().getProfiler().pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 22daed525b023998a05884db603e2c7385ce0873..e77e1c60a611c49489c65d66e54236a86c3093e3 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -1,5 +1,6 @@ package org.spigotmc; +import me.earthme.luminol.LuminolConfig; import net.minecraft.core.BlockPos; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerChunkCache; @@ -38,6 +39,10 @@ import co.aikar.timings.MinecraftTimings; import net.minecraft.world.entity.schedule.Activity; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; +// Pufferfish start +import net.minecraft.world.phys.Vec3; +import java.util.List; +// Pufferfish end public class ActivationRange { @@ -230,6 +235,25 @@ public class ActivationRange } // Paper end - configurable marker ticking ActivationRange.activateEntity(entity); + + // Pufferfish start + if (LuminolConfig.dearEnabled && entity.getType().dabEnabled) { + if (!entity.activatedPriorityReset) { + entity.activatedPriorityReset = true; + entity.activatedPriority = LuminolConfig.maximumActivationPrio; + } + Vec3 playerVec = player.position(); + Vec3 entityVec = entity.position(); + double diffX = playerVec.x - entityVec.x, diffY = playerVec.y - entityVec.y, diffZ = playerVec.z - entityVec.z; + int squaredDistance = (int) (diffX * diffX + diffY * diffY + diffZ * diffZ); + entity.activatedPriority = squaredDistance > LuminolConfig.startDistanceSquared ? + Math.max(1, Math.min(squaredDistance >> LuminolConfig.activationDistanceMod, entity.activatedPriority)) : + 1; + } else { + entity.activatedPriority = 1; + } + // Pufferfish end + } // Paper end } @@ -246,12 +270,12 @@ public class ActivationRange if ( io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() > entity.activatedTick ) // Folia - threaded regions { if ( entity.defaultActivationState ) - { + { // Pufferfish - diff on change entity.activatedTick = io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(); // Folia - threaded regions return; } if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) ) - { + { // Pufferfish - diff on change entity.activatedTick = io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(); // Folia - threaded regions } }