From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Paul Sauve Date: Fri, 15 Jan 2021 19:05:01 -0600 Subject: [PATCH] Pufferfish: Dynamic Activation of Brain Dreeam TODO: waiting Paper dealing with the newGoalRate Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish This replaces the current method of ticking an inactive entity's pathfinder 1/4 times with a new method that's dynamic based off how far away it is from a player. If an entity is within 32 blocks, it gets ticked every tick. If it's within 45 blocks, it gets ticked every other tick. If it's within 55 blocks, it gets ticked once every three ticks. (these numbers have since been changed, but the idea is the same.) Airplane Copyright (C) 2020 Technove LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 8353c264597de5b1ddcc1643c87f6ea09a22523b..881f507ff6fcac86f8ef04cbd3ff10c41c840d52 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -701,6 +701,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. org.spigotmc.ActivationRange.activateEntities(this); // Spigot this.timings.entityTick.startTiming(); // Spigot this.entityTickList.forEach((entity) -> { + 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 cdf7063bc7ae02652c55363e44c9ae809a999436..be9815bdf5652a7856fd72d3fca3e2562b2fb8c6 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -430,6 +430,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private UUID originWorld; public boolean freezeLocked = false; // Paper - Freeze Tick Lock API public boolean fixedPose = false; // Paper - Expand Pose API + public boolean activatedPriorityReset = false; // Pufferfish - DAB + public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // Pufferfish - DAB (golf score) public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java index cb61462d4691a055a4b25f7b953609d8a154fdfe..b2d8a858d8767bd6ca52e0b8db84757986c6ed61 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -316,6 +316,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 5f5265631641171345fc6564eb93b68dd8131b28..552b9f0ec8ab1aaea4cf0a212be628b49416c806 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -237,10 +237,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @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(); } } @@ -923,10 +923,14 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab int i = this.tickCount + this.getId(); if (i % 2 != 0 && this.tickCount > 1) { + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tickRunningGoals(false); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tickRunningGoals(false); } else { + if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.targetSelector.tick(); + if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking this.goalSelector.tick(); } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java index 758f62416ca9c02351348ac0d41deeb4624abc0e..69130969c9a434ec2361e573c9a1ec9f462dfda2 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerPanicTrigger.java @@ -36,7 +36,11 @@ public class VillagerPanicTrigger extends Behavior { @Override protected void tick(ServerLevel world, Villager entity, long time) { - if (time % 100L == 0L) { + // Pufferfish start + if (entity.nextGolemPanic < 0) entity.nextGolemPanic = time + 100; + if (--entity.nextGolemPanic < time) { + entity.nextGolemPanic = -1; + // Pufferfish end entity.spawnGolemIfNeeded(world, time, 3); } } 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 6fd5f65d8fb8830e000af6556c4009befa65b66f..6e01c7ba7720d6b08e4e98f59e0c086179e2ee0d 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 @@ -39,9 +39,13 @@ public class GoalSelector { } // Paper start - public boolean inactiveTick() { + public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start + if (inactive && !org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled) tickRate = 4; // reset to Paper's + tickRate = Math.min(tickRate, 3); // Dreeam TODO - Waiting Paper this.curRate++; - return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct + //return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct + 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 a6b8c6540886af41ef1bccbd76784fe327e8277b..d908b7723d1810a91a7bc8783bb72c64231ac8c3 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 @@ -217,8 +217,10 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS return 0.4F; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); AllayAi.updateActivity(this); super.customServerAiStep(); 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 1147bf32f6efe02e51c838eb371f11c6430a80a9..c75dccb977e0d620e3834ca0197e8fd51bf3bfd4 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 @@ -269,8 +269,10 @@ public class Axolotl extends Animal implements LerpingModel, VariantHolder> { .ifPresent(this::setVariant); } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel)this.level(), this); FrogAi.updateActivity(this); super.customServerAiStep(); 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 ab27bfb8b5a036eb13e77c8baeaa47e86a9ed2d6..d3cf26a3bdf40f6c827880bc394e7034a1adf4dc 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 @@ -83,8 +83,10 @@ public class Tadpole extends AbstractFish { return SoundEvents.TADPOLE_FLOP; } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); TadpoleAi.updateActivity(this); super.customServerAiStep(); 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 a6b6dd1715f7cb278b66381cbb0dd9d7069ce6ed..79ef4a1a4f4d404121087e2e6bcc3855556a88db 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 @@ -190,8 +190,10 @@ public class Goat extends Animal { return (Brain) super.getBrain(); // CraftBukkit - decompile error } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); GoatAi.updateActivity(this); super.customServerAiStep(); 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 8453c20a4b5f3a1205d0530b5c3b9f2c38a234a2..14878f825cc80296ffa09b5b2c0d8ed9a134491b 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 @@ -153,8 +153,10 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { return (Brain)super.getBrain(); } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel)this.level(), this); HoglinAi.updateActivity(this); if (this.isConverting()) { 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 37452ff83fe07c9fa14a337cbf5018bfc7543f5a..6da1335186a6d31d8e78542f8b3bd11d214ef13c 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 @@ -293,8 +293,10 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento return !this.cannotHunt; } + private int behaviorTick; // Pufferfish @Override protected void customServerAiStep() { + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick((ServerLevel) this.level(), this); PiglinAi.updateActivity(this); super.customServerAiStep(); 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 1cb55c9240dfa46cf117ac5b8923b064a96788c3..37e682452ecc30646faf1ae8da47f91779619d42 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,10 +272,12 @@ public class Warden extends Monster implements VibrationSystem { } + private int behaviorTick = 0; // Pufferfish @Override protected void customServerAiStep() { ServerLevel worldserver = (ServerLevel) this.level(); + if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish this.getBrain().tick(worldserver, this); super.customServerAiStep(); if ((this.tickCount + this.getId()) % 120 == 0) { 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 71a3eadd2f1e00fa066dbfe9918d749d43435a18..03513d3b6118ac5d0a58788462dcbc9890cf1a18 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -145,6 +145,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); } @@ -248,6 +250,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } // Spigot End + private int behaviorTick = 0; // Pufferfish @Override @Deprecated // Paper protected void customServerAiStep() { @@ -256,7 +259,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } protected void customServerAiStep(final boolean inactive) { // Paper end - 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 if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java b/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java new file mode 100644 index 0000000000000000000000000000000000000000..9fa2104554c3022c5189b6edb5768b3cd4963fb1 --- /dev/null +++ b/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java @@ -0,0 +1,53 @@ +package org.dreeam.leaf.config.modules.opt; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.entity.EntityType; +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; +import org.dreeam.leaf.config.LeafConfig; + +import java.util.ArrayList; +import java.util.List; + +public class DynamicActivationofBrain extends ConfigModules { + + public String getBasePath() { + return EnumConfigCategory.PERF.getBaseKeyName() + ".dab"; + } + + public static boolean enabled = true; + public static int startDistance = 12; + public static int startDistanceSquared; + public static int maximumActivationPrio = 20; + public static int activationDistanceMod = 8; + public static List blackedEntities = new ArrayList<>(); + + @Override + public void onLoaded() { + config.addComment(getBasePath(), """ + Optimizes entity brains when + they're far away from the player"""); + + enabled = config.getBoolean(getBasePath() + ".enabled", enabled); + startDistance = config.getInt(getBasePath() + ".start-distance", startDistance, """ + This value determines how far away an entity has to be + from the player to start being effected by DEAR."""); + maximumActivationPrio = config.getInt(getBasePath() + ".max-tick-freq", maximumActivationPrio, """ + This value defines how often in ticks, the furthest entity + will get their pathfinders and behaviors ticked. 20 = 1s"""); + activationDistanceMod = config.getInt(getBasePath() + ".activation-dist-mod", activationDistanceMod, """ + 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."""); + blackedEntities = config.getList(getBasePath() + ".blacklisted-entities", blackedEntities, + "A list of entities to ignore for activation"); + + startDistanceSquared = startDistance * startDistance; + for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { + entityType.dabEnabled = true; // reset all, before setting the ones to true + } + blackedEntities.forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> + entityType.dabEnabled = false, () -> LeafConfig.LOGGER.warn("Unknown entity \"{}\"", name))); + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 0b2f2fbe462ed628ef3d640824d4162e79279089..456f64fcae7a12ca141d8061f69797e58efa1899 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -238,6 +238,25 @@ public class ActivationRange } // Paper end - Configurable marker ticking ActivationRange.activateEntity(entity); + + // Pufferfish start + if (org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled && entity.getType().dabEnabled) { + if (!entity.activatedPriorityReset) { + entity.activatedPriorityReset = true; + entity.activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; + } + net.minecraft.world.phys.Vec3 playerVec = player.position(); + net.minecraft.world.phys.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 > org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.startDistanceSquared ? + Math.max(1, Math.min(squaredDistance >> org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.activationDistanceMod, entity.activatedPriority)) : + 1; + } else { + entity.activatedPriority = 1; + } + // Pufferfish end + } // Paper end } @@ -254,12 +273,12 @@ public class ActivationRange if ( MinecraftServer.currentTick > entity.activatedTick ) { if ( entity.defaultActivationState ) - { + { // Pufferfish - diff on change entity.activatedTick = MinecraftServer.currentTick; return; } if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) ) - { + { // Pufferfish - diff on change entity.activatedTick = MinecraftServer.currentTick; } }