aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNassim Jahnke <[email protected]>2024-12-16 14:08:25 +0100
committerNassim Jahnke <[email protected]>2024-12-16 14:08:25 +0100
commitf8cb014d207ce40edf9195e558083cfb87387264 (patch)
tree9a873af24a038747380ef19c031402cafee77425
parent47c06357f71ff81759d3748ef0c26a6921e25d63 (diff)
downloadPaper-f8cb014d207ce40edf9195e558083cfb87387264.tar.gz
Paper-f8cb014d207ce40edf9195e558083cfb87387264.zip
Move Aikar's EAR 1 into EAR 2 patch
-rw-r--r--feature-patches/1043-Entity-Activation-Range-2.0.patch649
-rw-r--r--paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch42
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch32
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch19
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch23
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch9
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch37
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch18
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch12
-rw-r--r--paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch27
-rw-r--r--paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java47
-rw-r--r--paper-server/src/main/java/org/spigotmc/ActivationRange.java387
-rw-r--r--paper-server/src/main/java/org/spigotmc/TrackingRange.java9
13 files changed, 666 insertions, 645 deletions
diff --git a/feature-patches/1043-Entity-Activation-Range-2.0.patch b/feature-patches/1043-Entity-Activation-Range-2.0.patch
index 2a9fee105b..3767bb01b0 100644
--- a/feature-patches/1043-Entity-Activation-Range-2.0.patch
+++ b/feature-patches/1043-Entity-Activation-Range-2.0.patch
@@ -13,38 +13,499 @@ Adds water Mobs to activation range config and nerfs fish
Adds flying monsters to control ghast and phantoms
Adds villagers as separate config
-
+diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..bd888ef719b9bfc93bace0b1d0fb771ac659f515
+--- /dev/null
++++ b/io/papermc/paper/entity/activation/ActivationRange.java
+@@ -0,0 +1,318 @@
++package io.papermc.paper.entity.activation;
++
++import net.minecraft.core.BlockPos;
++import net.minecraft.server.MinecraftServer;
++import net.minecraft.world.entity.Entity;
++import net.minecraft.world.entity.ExperienceOrb;
++import net.minecraft.world.entity.FlyingMob;
++import net.minecraft.world.entity.LightningBolt;
++import net.minecraft.world.entity.LivingEntity;
++import net.minecraft.world.entity.Mob;
++import net.minecraft.world.entity.ai.Brain;
++import net.minecraft.world.entity.animal.Animal;
++import net.minecraft.world.entity.animal.Bee;
++import net.minecraft.world.entity.animal.Sheep;
++import net.minecraft.world.entity.animal.horse.Llama;
++import net.minecraft.world.entity.boss.EnderDragonPart;
++import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
++import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
++import net.minecraft.world.entity.boss.wither.WitherBoss;
++import net.minecraft.world.entity.item.ItemEntity;
++import net.minecraft.world.entity.item.PrimedTnt;
++import net.minecraft.world.entity.monster.Creeper;
++import net.minecraft.world.entity.monster.Pillager;
++import net.minecraft.world.entity.npc.Villager;
++import net.minecraft.world.entity.player.Player;
++import net.minecraft.world.entity.projectile.AbstractArrow;
++import net.minecraft.world.entity.projectile.AbstractHurtingProjectile;
++import net.minecraft.world.entity.projectile.EyeOfEnder;
++import net.minecraft.world.entity.projectile.FireworkRocketEntity;
++import net.minecraft.world.entity.projectile.ThrowableProjectile;
++import net.minecraft.world.entity.projectile.ThrownTrident;
++import net.minecraft.world.entity.schedule.Activity;
++import net.minecraft.world.level.Level;
++import net.minecraft.world.phys.AABB;
++import org.spigotmc.SpigotWorldConfig;
++
++public final class ActivationRange {
++
++ private ActivationRange() {
++ }
++
++ static Activity[] VILLAGER_PANIC_IMMUNITIES = {
++ Activity.HIDE,
++ Activity.PRE_RAID,
++ Activity.RAID,
++ Activity.PANIC
++ };
++
++ private static int checkInactiveWakeup(final Entity entity) {
++ final Level world = entity.level();
++ final SpigotWorldConfig config = world.spigotConfig;
++ final long inactiveFor = MinecraftServer.currentTick - entity.activatedTick;
++ if (entity.activationType == ActivationType.VILLAGER) {
++ if (inactiveFor > config.wakeUpInactiveVillagersEvery && world.wakeupInactiveRemainingVillagers > 0) {
++ world.wakeupInactiveRemainingVillagers--;
++ return config.wakeUpInactiveVillagersFor;
++ }
++ } else if (entity.activationType == ActivationType.ANIMAL) {
++ if (inactiveFor > config.wakeUpInactiveAnimalsEvery && world.wakeupInactiveRemainingAnimals > 0) {
++ world.wakeupInactiveRemainingAnimals--;
++ return config.wakeUpInactiveAnimalsFor;
++ }
++ } else if (entity.activationType == ActivationType.FLYING_MONSTER) {
++ if (inactiveFor > config.wakeUpInactiveFlyingEvery && world.wakeupInactiveRemainingFlying > 0) {
++ world.wakeupInactiveRemainingFlying--;
++ return config.wakeUpInactiveFlyingFor;
++ }
++ } else if (entity.activationType == ActivationType.MONSTER || entity.activationType == ActivationType.RAIDER) {
++ if (inactiveFor > config.wakeUpInactiveMonstersEvery && world.wakeupInactiveRemainingMonsters > 0) {
++ world.wakeupInactiveRemainingMonsters--;
++ return config.wakeUpInactiveMonstersFor;
++ }
++ }
++ return -1;
++ }
++
++ static AABB maxBB = new AABB(0, 0, 0, 0, 0, 0);
++
++ /**
++ * These entities are excluded from Activation range checks.
++ *
++ * @param entity
++ * @param config
++ * @return boolean If it should always tick.
++ */
++ public static boolean initializeEntityActivationState(final Entity entity, final SpigotWorldConfig config) {
++ return (entity.activationType == ActivationType.MISC && config.miscActivationRange == 0)
++ || (entity.activationType == ActivationType.RAIDER && config.raiderActivationRange == 0)
++ || (entity.activationType == ActivationType.ANIMAL && config.animalActivationRange == 0)
++ || (entity.activationType == ActivationType.MONSTER && config.monsterActivationRange == 0)
++ || (entity.activationType == ActivationType.VILLAGER && config.villagerActivationRange <= 0)
++ || (entity.activationType == ActivationType.WATER && config.waterActivationRange <= 0)
++ || (entity.activationType == ActivationType.FLYING_MONSTER && config.flyingMonsterActivationRange <= 0)
++ || entity instanceof EyeOfEnder
++ || entity instanceof Player
++ || entity instanceof ThrowableProjectile
++ || entity instanceof EnderDragon
++ || entity instanceof EnderDragonPart
++ || entity instanceof WitherBoss
++ || entity instanceof AbstractHurtingProjectile
++ || entity instanceof LightningBolt
++ || entity instanceof PrimedTnt
++ || entity instanceof net.minecraft.world.entity.item.FallingBlockEntity
++ || entity instanceof net.minecraft.world.entity.vehicle.AbstractMinecart
++ || entity instanceof net.minecraft.world.entity.vehicle.AbstractBoat
++ || entity instanceof EndCrystal
++ || entity instanceof FireworkRocketEntity
++ || entity instanceof ThrownTrident;
++ }
++
++ /**
++ * Find what entities are in range of the players in the world and set
++ * active if in range.
++ *
++ * @param world
++ */
++ public static void activateEntities(final Level world) {
++ final int miscActivationRange = world.spigotConfig.miscActivationRange;
++ final int raiderActivationRange = world.spigotConfig.raiderActivationRange;
++ final int animalActivationRange = world.spigotConfig.animalActivationRange;
++ final int monsterActivationRange = world.spigotConfig.monsterActivationRange;
++ final int waterActivationRange = world.spigotConfig.waterActivationRange;
++ final int flyingActivationRange = world.spigotConfig.flyingMonsterActivationRange;
++ final int villagerActivationRange = world.spigotConfig.villagerActivationRange;
++ world.wakeupInactiveRemainingAnimals = Math.min(world.wakeupInactiveRemainingAnimals + 1, world.spigotConfig.wakeUpInactiveAnimals);
++ world.wakeupInactiveRemainingVillagers = Math.min(world.wakeupInactiveRemainingVillagers + 1, world.spigotConfig.wakeUpInactiveVillagers);
++ world.wakeupInactiveRemainingMonsters = Math.min(world.wakeupInactiveRemainingMonsters + 1, world.spigotConfig.wakeUpInactiveMonsters);
++ world.wakeupInactiveRemainingFlying = Math.min(world.wakeupInactiveRemainingFlying + 1, world.spigotConfig.wakeUpInactiveFlying);
++
++ int maxRange = Math.max(monsterActivationRange, animalActivationRange);
++ maxRange = Math.max(maxRange, raiderActivationRange);
++ maxRange = Math.max(maxRange, miscActivationRange);
++ maxRange = Math.max(maxRange, flyingActivationRange);
++ maxRange = Math.max(maxRange, waterActivationRange);
++ maxRange = Math.max(maxRange, villagerActivationRange);
++ maxRange = Math.min((world.spigotConfig.simulationDistance << 4) - 8, maxRange);
++
++ for (final Player player : world.players()) {
++ player.activatedTick = MinecraftServer.currentTick;
++ if (world.spigotConfig.ignoreSpectatorActivation && player.isSpectator()) {
++ continue;
++ }
++
++ final int worldHeight = world.getHeight();
++ ActivationRange.maxBB = player.getBoundingBox().inflate(maxRange, worldHeight, maxRange);
++ ActivationType.MISC.boundingBox = player.getBoundingBox().inflate(miscActivationRange, worldHeight, miscActivationRange);
++ ActivationType.RAIDER.boundingBox = player.getBoundingBox().inflate(raiderActivationRange, worldHeight, raiderActivationRange);
++ ActivationType.ANIMAL.boundingBox = player.getBoundingBox().inflate(animalActivationRange, worldHeight, animalActivationRange);
++ ActivationType.MONSTER.boundingBox = player.getBoundingBox().inflate(monsterActivationRange, worldHeight, monsterActivationRange);
++ ActivationType.WATER.boundingBox = player.getBoundingBox().inflate(waterActivationRange, worldHeight, waterActivationRange);
++ ActivationType.FLYING_MONSTER.boundingBox = player.getBoundingBox().inflate(flyingActivationRange, worldHeight, flyingActivationRange);
++ ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate(villagerActivationRange, worldHeight, villagerActivationRange);
++
++ final java.util.List<Entity> entities = world.getEntities((Entity) null, ActivationRange.maxBB, e -> true);
++ final boolean tickMarkers = world.paperConfig().entities.markers.tick;
++ for (final Entity entity : entities) {
++ if (!tickMarkers && entity instanceof net.minecraft.world.entity.Marker) {
++ continue;
++ }
++
++ ActivationRange.activateEntity(entity);
++ }
++ }
++ }
++
++ /**
++ * Tries to activate an entity.
++ *
++ * @param entity
++ */
++ private static void activateEntity(final Entity entity) {
++ if (MinecraftServer.currentTick > entity.activatedTick) {
++ if (entity.defaultActivationState) {
++ entity.activatedTick = MinecraftServer.currentTick;
++ return;
++ }
++ if (entity.activationType.boundingBox.intersects(entity.getBoundingBox())) {
++ entity.activatedTick = MinecraftServer.currentTick;
++ }
++ }
++ }
++
++ /**
++ * If an entity is not in range, do some more checks to see if we should
++ * give it a shot.
++ *
++ * @param entity
++ * @return
++ */
++ public static int checkEntityImmunities(final Entity entity) { // return # of ticks to get immunity
++ final SpigotWorldConfig config = entity.level().spigotConfig;
++ final int inactiveWakeUpImmunity = checkInactiveWakeup(entity);
++ if (inactiveWakeUpImmunity > -1) {
++ return inactiveWakeUpImmunity;
++ }
++ if (entity.getRemainingFireTicks() > 0) {
++ return 2;
++ }
++ if (entity.activatedImmunityTick >= MinecraftServer.currentTick) {
++ return 1;
++ }
++ final long inactiveFor = MinecraftServer.currentTick - entity.activatedTick;
++ if ((entity.activationType != ActivationType.WATER && entity.isInWater() && entity.isPushedByFluid())) {
++ return 100;
++ }
++ if (!entity.onGround() || entity.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D) {
++ return 100;
++ }
++ if (!(entity instanceof final AbstractArrow arrow)) {
++ if ((!entity.onGround() && !(entity instanceof FlyingMob))) {
++ return 10;
++ }
++ } else if (!arrow.isInGround()) {
++ return 1;
++ }
++ // special cases.
++ if (entity instanceof final LivingEntity living) {
++ if (living.onClimbable() || living.jumping || living.hurtTime > 0 || !living.activeEffects.isEmpty() || living.isFreezing()) {
++ return 1;
++ }
++ if (entity instanceof final Mob mob && mob.getTarget() != null) {
++ return 20;
++ }
++ if (entity instanceof final Bee bee) {
++ final BlockPos movingTarget = bee.getMovingTarget();
++ if (bee.isAngry() ||
++ (bee.getHivePos() != null && bee.getHivePos().equals(movingTarget)) ||
++ (bee.getSavedFlowerPos() != null && bee.getSavedFlowerPos().equals(movingTarget))
++ ) {
++ return 20;
++ }
++ }
++ if (entity instanceof final Villager villager) {
++ final Brain<Villager> behaviorController = villager.getBrain();
++
++ if (config.villagersActiveForPanic) {
++ for (final Activity activity : VILLAGER_PANIC_IMMUNITIES) {
++ if (behaviorController.isActive(activity)) {
++ return 20 * 5;
++ }
++ }
++ }
++
++ if (config.villagersWorkImmunityAfter > 0 && inactiveFor >= config.villagersWorkImmunityAfter) {
++ if (behaviorController.isActive(Activity.WORK)) {
++ return config.villagersWorkImmunityFor;
++ }
++ }
++ }
++ if (entity instanceof final Llama llama && llama.inCaravan()) {
++ return 1;
++ }
++ if (entity instanceof final Animal animal) {
++ if (animal.isBaby() || animal.isInLove()) {
++ return 5;
++ }
++ if (entity instanceof final Sheep sheep && sheep.isSheared()) {
++ return 1;
++ }
++ }
++ if (entity instanceof final Creeper creeper && creeper.isIgnited()) { // isExplosive
++ return 20;
++ }
++ if (entity instanceof final Mob mob && mob.targetSelector.hasTasks()) {
++ return 0;
++ }
++ if (entity instanceof final Pillager pillager) {
++ // TODO:?
++ }
++ }
++ // SPIGOT-6644: Otherwise the target refresh tick will be missed
++ if (entity instanceof ExperienceOrb) {
++ return 20;
++ }
++ return -1;
++ }
++
++ /**
++ * Checks if the entity is active for this tick.
++ *
++ * @param entity
++ * @return
++ */
++ public static boolean checkIfActive(final Entity entity) {
++ // Never safe to skip fireworks or item gravity
++ if (entity instanceof FireworkRocketEntity || (entity instanceof ItemEntity && (entity.tickCount + entity.getId()) % 4 == 0)) { // Needed for item gravity, see ItemEntity tick
++ return true;
++ }
++ // special case always immunities
++ // immunize brand-new entities, dead entities, and portal scenarios
++ if (entity.defaultActivationState || entity.tickCount < 20 * 10 || !entity.isAlive() || (entity.portalProcess != null && !entity.portalProcess.hasExpired()) || entity.portalCooldown > 0) {
++ return true;
++ }
++ // immunize leashed entities
++ if (entity instanceof final Mob mob && mob.getLeashHolder() instanceof Player) {
++ return true;
++ }
++
++ boolean isActive = entity.activatedTick >= MinecraftServer.currentTick;
++ entity.isTemporarilyActive = false;
++
++ // Should this entity tick?
++ if (!isActive) {
++ if ((MinecraftServer.currentTick - entity.activatedTick - 1) % 20 == 0) {
++ // Check immunities every 20 ticks.
++ final int immunity = checkEntityImmunities(entity);
++ if (immunity >= 0) {
++ entity.activatedTick = MinecraftServer.currentTick + immunity;
++ } else {
++ entity.isTemporarilyActive = true;
++ }
++ isActive = true;
++ }
++ }
++ // removed the original's dumb tick skipping for active entities
++ return isActive;
++ }
++}
+diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
+index 9bbcafa8e70f95d5ab6318211a0265acbfc76b1c..f8f145cd9614f7e38d6aa72501fe31837340a8bb 100644
+--- a/net/minecraft/server/level/ChunkMap.java
++++ b/net/minecraft/server/level/ChunkMap.java
+@@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableList;
+ import com.google.common.collect.Iterables;
+ import com.google.common.collect.Lists;
+ import com.google.common.collect.Queues;
+-import com.google.common.collect.Sets;
+ import com.google.common.collect.ImmutableList.Builder;
+ import com.mojang.datafixers.DataFixer;
+ import com.mojang.logging.LogUtils;
+@@ -19,7 +18,6 @@ import it.unimi.dsi.fastutil.longs.LongIterator;
+ import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet;
+ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+ import it.unimi.dsi.fastutil.longs.LongSet;
+-import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
+ import java.io.IOException;
+ import java.io.Writer;
+ import java.nio.file.Path;
+@@ -95,7 +93,6 @@ import net.minecraft.world.level.levelgen.structure.StructureStart;
+ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
+ import net.minecraft.world.level.storage.DimensionDataStorage;
+ import net.minecraft.world.level.storage.LevelStorageSource;
+-import net.minecraft.world.phys.Vec3;
+ import org.apache.commons.lang3.mutable.MutableBoolean;
+ import org.slf4j.Logger;
+
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
-index 1d7e9492a474c99dff372d6b57f1f195e42d5114..aa5eed48871b5ab67d18213e532271241aae9182 100644
+index 678b3027e8c53e6021ea49afa69cdbe5f60dcf25..c2d9f1e6c68f4945e3b9e5b95326e8180fa7a0fb 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
-@@ -963,10 +963,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ profilerFiller.pop();
+ }
+
++ io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
+ this.entityTickList
+ .forEach(
+ entity -> {
+@@ -960,16 +961,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ entity.tickCount++;
+ profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString());
profilerFiller.incrementCounter("tickNonPassenger");
- // Spigot start
- final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2
-- if (isActive) {
++ final boolean isActive = io.papermc.paper.entity.activation.ActivationRange.checkIfActive(entity); // Paper - EAR 2
+ if (isActive) { // Paper - EAR 2
entity.tick();
entity.postTick(); // CraftBukkit
-- } else {entity.inactiveTick();} // Spigot end
+ } else {entity.inactiveTick();} // Paper - EAR 2
profilerFiller.pop();
for (Entity entity1 : entity.getPassengers()) {
+- this.tickPassenger(entity, entity1);
++ this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
+ }
+ }
+
+- private void tickPassenger(Entity ridingEntity, Entity passengerEntity) {
++ private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2
+ if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) {
+ passengerEntity.stopRiding();
+ } else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) {
+@@ -978,12 +982,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ ProfilerFiller profilerFiller = Profiler.get();
+ profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString());
+ profilerFiller.incrementCounter("tickPassenger");
++ // Paper start - EAR 2
++ if (isActive) {
+ passengerEntity.rideTick();
+ passengerEntity.postTick(); // CraftBukkit
++ } else {
++ passengerEntity.setDeltaMovement(Vec3.ZERO);
++ passengerEntity.inactiveTick();
++ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary
++ ridingEntity.positionRider(passengerEntity);
++ }
++ // Paper end - EAR 2
+ profilerFiller.pop();
+
+ for (Entity entity : passengerEntity.getPassengers()) {
+- this.tickPassenger(passengerEntity, entity);
++ this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2
+ }
+ }
+ }
+diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java
+index a9f01e616ef6b0d74caf57cd68eb371a4fd30fd5..179f4e4b9b1eb57f78bbb2f9fa34b11ea79b7a88 100644
+--- a/net/minecraft/world/entity/AgeableMob.java
++++ b/net/minecraft/world/entity/AgeableMob.java
+@@ -126,6 +126,23 @@ public abstract class AgeableMob extends PathfinderMob {
+ super.onSyncedDataUpdated(key);
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ super.inactiveTick();
++ if (this.level().isClientSide || this.ageLocked) { // CraftBukkit
++ this.refreshDimensions();
++ } else {
++ int age = this.getAge();
++ if (age < 0) {
++ this.setAge(++age);
++ } else if (age > 0) {
++ this.setAge(--age);
++ }
++ }
++ }
++ // Paper end - EAR 2
++
+ @Override
+ public void aiStep() {
+ super.aiStep();
+diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java
+index b4a1202a9f43525caf215d2f5c86ad92ea4f6de7..47db6ac3ef23fd0da127cfb5a4d3ba9ebd2ab54d 100644
+--- a/net/minecraft/world/entity/AreaEffectCloud.java
++++ b/net/minecraft/world/entity/AreaEffectCloud.java
+@@ -128,6 +128,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
+ this.duration = duration;
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ super.inactiveTick();
++ if (this.tickCount >= this.waitTime + this.duration) {
++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
++ }
++ }
++ // Paper end - EAR 2
++
+ @Override
+ public void tick() {
+ super.tick();
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
-index 0aed1e455dec32c3d53d8fb2f1047e1bf177f171..8c2441a6c7abc3a80426923c1ea42000283ee167 100644
+index 020d05bb60abec10fa37e651c17f600c883af61d..2e5f1dc15ea6a20f8cbdef97ecbf00e5d56603cf 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
-@@ -383,6 +383,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- // Spigot end
- protected int numCollisions = 0; // Paper - Cap entity collisions
- public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals
-+ public long activatedImmunityTick = Integer.MIN_VALUE; // Paper - EAR
-+ public boolean isTemporarilyActive; // Paper - EAR
- public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
- // Paper start - Entity origin API
- @javax.annotation.Nullable
-@@ -959,6 +961,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -386,6 +386,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ public boolean fixedPose = false; // Paper - Expand Pose API
+ private final int despawnTime; // Paper - entity despawn time limit
+ public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges
++ // Paper start - EAR 2
++ public final boolean defaultActivationState;
++ public long activatedTick = Integer.MIN_VALUE;
++ public boolean isTemporarilyActive;
++ public long activatedImmunityTick = Integer.MIN_VALUE;
++
++ public void inactiveTick() {
++ }
++ // Paper end - EAR 2
+
+ public void setOrigin(@javax.annotation.Nonnull org.bukkit.Location location) {
+ this.origin = location.toVector();
+@@ -423,6 +432,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ this.position = Vec3.ZERO;
+ this.blockPosition = BlockPos.ZERO;
+ this.chunkPosition = ChunkPos.ZERO;
++ // Paper start - EAR 2
++ if (level != null) {
++ this.defaultActivationState = io.papermc.paper.entity.activation.ActivationRange.initializeEntityActivationState(this, level.spigotConfig);
++ } else {
++ this.defaultActivationState = false;
++ }
++ // Paper end - EAR 2
+ SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this);
+ builder.define(DATA_SHARED_FLAGS_ID, (byte)0);
+ builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply());
+@@ -946,6 +962,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} else {
this.wasOnFire = this.isOnFire();
if (type == MoverType.PISTON) {
@@ -53,20 +514,39 @@ index 0aed1e455dec32c3d53d8fb2f1047e1bf177f171..8c2441a6c7abc3a80426923c1ea42000
movement = this.limitPistonMovement(movement);
if (movement.equals(Vec3.ZERO)) {
return;
-@@ -972,6 +976,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -959,6 +977,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.stuckSpeedMultiplier = Vec3.ZERO;
this.setDeltaMovement(Vec3.ZERO);
}
+ // Paper start - ignore movement changes while inactive.
+ if (isTemporarilyActive && !(this instanceof ItemEntity) && movement == getDeltaMovement() && type == MoverType.SELF) {
+ setDeltaMovement(Vec3.ZERO);
-+ gameprofilerfiller.pop();
++ profilerFiller.pop();
+ return;
+ }
+ // Paper end
movement = this.maybeBackOffFromEdge(movement, type);
Vec3 vec3 = this.collide(movement);
+diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
+index 41ef8c24903e5efceead43796e647824a54193df..9de400977ec33e485e87cdf1cf145588527e1e10 100644
+--- a/net/minecraft/world/entity/LivingEntity.java
++++ b/net/minecraft/world/entity/LivingEntity.java
+@@ -3089,6 +3089,14 @@ public abstract class LivingEntity extends Entity implements Attackable {
+ return false;
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ super.inactiveTick();
++ ++this.noActionTime; // Above all the floats
++ }
++ // Paper end - EAR 2
++
+ @Override
+ public void tick() {
+ super.tick();
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index f7d69db61d1293510428ae275e8a50571dde5ddf..1ed07fd23985a6bf8cf8300f74c92b7531a79fc6 100644
--- a/net/minecraft/world/entity/Mob.java
@@ -105,24 +585,18 @@ index 0caf50ec50f056b83a20bbc6a2fe0144593aef39..af59a700755654eb68d6bf57d0712c4a
return this.getWalkTargetValue(pos, this.level());
}
diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java
-index 88e7e245824b670652878e03a2142a13e97508fe..2730e76228b03b1ec52108f394c20fe003801b02 100644
+index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b97f7f1c71 100644
--- a/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java
-@@ -22,12 +22,12 @@ public class GoalSelector {
- return false;
- }
- };
-+ private int curRate; // Paper - EAR 2
+@@ -25,6 +25,7 @@ public class GoalSelector {
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>();
- private static final Goal.Flag[] GOAL_FLAG_VALUES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector
- private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
+ private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
++ private int curRate; // Paper - EAR 2
--
public void addGoal(int priority, Goal goal) {
this.availableGoals.add(new WrappedGoal(priority, goal));
- }
-@@ -37,6 +37,22 @@ public class GoalSelector {
+@@ -35,6 +36,22 @@ public class GoalSelector {
this.availableGoals.removeIf(wrappedGoal -> filter.test(wrappedGoal.getGoal()));
}
@@ -172,20 +646,55 @@ index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20
return true;
}
}
+diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
+index 1c82a41acb8717b2c56498602fd1ecbe6aa58fe5..dcbd35d6bf81d7a0621020710114887b68a7dcc6 100644
+--- a/net/minecraft/world/entity/item/ItemEntity.java
++++ b/net/minecraft/world/entity/item/ItemEntity.java
+@@ -124,6 +124,29 @@ public class ItemEntity extends Entity implements TraceableEntity {
+ return 0.04;
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ super.inactiveTick();
++ if (this.pickupDelay > 0 && this.pickupDelay != 32767) {
++ this.pickupDelay--;
++ }
++ if (this.age != -32768) {
++ this.age++;
++ }
++
++ if (!this.level().isClientSide && this.age >= this.despawnRate) {// Paper - Alternative item-despawn-rate
++ // CraftBukkit start - fire ItemDespawnEvent
++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
++ this.age = 0;
++ return;
++ }
++ // CraftBukkit end
++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
++ }
++ }
++ // Paper end - EAR 2
++
+ @Override
+ public void tick() {
+ if (this.getItem().isEmpty()) {
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
-index 81a6d31d90dc139e4d99c2b8e609032e8b100b2d..0b73ad491eb6992e1d8fdd7e75264c9ce712a462 100644
+index 27568a1604d2dd5d46e836bbc25431929e218aa1..2b83262e4a13eae86df82913ce4f3121e3631a43 100644
--- a/net/minecraft/world/entity/npc/Villager.java
+++ b/net/minecraft/world/entity/npc/Villager.java
-@@ -269,18 +269,33 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
- @Override
- public void inactiveTick() {
- // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :(
-- if (this.level().spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) {
-- this.customServerAiStep((ServerLevel) this.level());
-+ // Paper start
+@@ -265,11 +265,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+ return this.assignProfessionWhenSpawned;
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :(
+ if (this.getUnhappyCounter() > 0) {
+ this.setUnhappyCounter(this.getUnhappyCounter() - 1);
- }
++ }
+ if (this.isEffectiveAi()) {
+ if (this.level().spigotConfig.tickInactiveVillagers) {
+ this.customServerAiStep(this.level().getMinecraftWorld());
@@ -194,11 +703,10 @@ index 81a6d31d90dc139e4d99c2b8e609032e8b100b2d..0b73ad491eb6992e1d8fdd7e75264c9c
+ }
+ }
+ maybeDecayGossip();
-+ // Paper end
- super.inactiveTick();
- }
- // Spigot End
-
++ super.inactiveTick();
++ }
++ // Paper end - EAR 2
++
@Override
protected void customServerAiStep(ServerLevel level) {
+ // Paper start - EAR 2
@@ -213,7 +721,7 @@ index 81a6d31d90dc139e4d99c2b8e609032e8b100b2d..0b73ad491eb6992e1d8fdd7e75264c9c
profilerFiller.pop();
if (this.assignProfessionWhenSpawned) {
this.assignProfessionWhenSpawned = false;
-@@ -304,7 +319,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -293,7 +317,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
this.lastTradedPlayer = null;
}
@@ -222,7 +730,7 @@ index 81a6d31d90dc139e4d99c2b8e609032e8b100b2d..0b73ad491eb6992e1d8fdd7e75264c9c
Raid raidAt = level.getRaidAt(this.blockPosition());
if (raidAt != null && raidAt.isActive() && !raidAt.isOver()) {
level.broadcastEntityEvent(this, (byte)42);
-@@ -314,6 +329,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
+@@ -303,6 +327,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.isTrading()) {
this.stopTrading();
}
@@ -230,6 +738,53 @@ index 81a6d31d90dc139e4d99c2b8e609032e8b100b2d..0b73ad491eb6992e1d8fdd7e75264c9c
super.customServerAiStep(level);
}
+diff --git a/net/minecraft/world/entity/projectile/Arrow.java b/net/minecraft/world/entity/projectile/Arrow.java
+index c1e09e701757a300183b62d343ded03033e63aa7..56574f8ef879159edc0114da09300143a2c79a35 100644
+--- a/net/minecraft/world/entity/projectile/Arrow.java
++++ b/net/minecraft/world/entity/projectile/Arrow.java
+@@ -66,6 +66,16 @@ public class Arrow extends AbstractArrow {
+ builder.define(ID_EFFECT_COLOR, -1);
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ if (this.isInGround()) {
++ this.life++;
++ }
++ super.inactiveTick();
++ }
++ // Paper end
++
+ @Override
+ public void tick() {
+ super.tick();
+diff --git a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
+index 7c0862c50b44555fb27ce7dc46f4ec95a3eb0022..774ca9e0b56fd175ae246051de762d0c4256ca58 100644
+--- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
++++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
+@@ -102,6 +102,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
+ return super.shouldRender(x, y, z) && !this.isAttachedToEntity();
+ }
+
++ // Paper start - EAR 2
++ @Override
++ public void inactiveTick() {
++ this.life++;
++ if (this.life > this.lifetime && this.level() instanceof ServerLevel serverLevel) {
++ // CraftBukkit start
++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
++ this.explode(serverLevel);
++ }
++ // CraftBukkit end
++ }
++ super.inactiveTick();
++ }
++ // Paper end - EAR 2
++
+ @Override
+ public void tick() {
+ super.tick();
diff --git a/net/minecraft/world/entity/vehicle/MinecartHopper.java b/net/minecraft/world/entity/vehicle/MinecartHopper.java
index c553cf0592dfa606dbbb1e6854d3377b9feb5efb..dec705ec57e4f63ef2ccaa87c5400c116aee9b35 100644
--- a/net/minecraft/world/entity/vehicle/MinecartHopper.java
diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch
index daa7e73901..0eaf3ea736 100644
--- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch
@@ -291,14 +291,6 @@
if (flag) {
this.resetEmptyTime();
}
-@@ -385,6 +_,7 @@
- profilerFiller.pop();
- }
-
-+ org.spigotmc.ActivationRange.activateEntities(this); // Spigot
- this.entityTickList
- .forEach(
- entity -> {
@@ -461,12 +_,12 @@
int minBlockZ = pos.getMinBlockZ();
ProfilerFiller profilerFiller = Profiler.get();
@@ -464,52 +456,22 @@
}
public void resetEmptyTime() {
-@@ -752,15 +_,20 @@
- entity.tickCount++;
+@@ -753,6 +_,7 @@
profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString());
profilerFiller.incrementCounter("tickNonPassenger");
-+ // Spigot start
-+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2
-+ if (isActive) {
entity.tick();
+ entity.postTick(); // CraftBukkit
-+ } else {entity.inactiveTick();} // Spigot end
profilerFiller.pop();
for (Entity entity1 : entity.getPassengers()) {
-- this.tickPassenger(entity, entity1);
-+ this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
- }
- }
-
-- private void tickPassenger(Entity ridingEntity, Entity passengerEntity) {
-+ private void tickPassenger(Entity ridingEntity, Entity passengerEntity, boolean isActive) { // Paper - EAR 2
- if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) {
- passengerEntity.stopRiding();
- } else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) {
-@@ -769,11 +_,21 @@
- ProfilerFiller profilerFiller = Profiler.get();
+@@ -770,6 +_,7 @@
profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString());
profilerFiller.incrementCounter("tickPassenger");
-+ // Paper start - EAR 2
-+ if (isActive) {
passengerEntity.rideTick();
+ passengerEntity.postTick(); // CraftBukkit
-+ } else {
-+ passengerEntity.setDeltaMovement(Vec3.ZERO);
-+ passengerEntity.inactiveTick();
-+ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary
-+ ridingEntity.positionRider(passengerEntity);
-+ // Paper end - EAR 2
-+ }
profilerFiller.pop();
for (Entity entity : passengerEntity.getPassengers()) {
-- this.tickPassenger(passengerEntity, entity);
-+ this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2
- }
- }
- }
@@ -786,6 +_,7 @@
public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) {
ServerChunkCache chunkSource = this.getChunkSource();
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch
index dcf72a4df6..a0e42a63dd 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch
@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/AgeableMob.java
+++ b/net/minecraft/world/entity/AgeableMob.java
-@@ -20,11 +_,37 @@
+@@ -20,6 +_,7 @@
protected int age;
protected int forcedAge;
protected int forcedAgeTimer;
@@ -8,36 +8,6 @@
protected AgeableMob(EntityType<? extends AgeableMob> entityType, Level level) {
super(entityType, level);
- }
-
-+ // Spigot start
-+ @Override
-+ public void inactiveTick()
-+ {
-+ super.inactiveTick();
-+ if ( this.level().isClientSide || this.ageLocked )
-+ { // CraftBukkit
-+ this.refreshDimensions();
-+ } else
-+ {
-+ int i = this.getAge();
-+
-+ if ( i < 0 )
-+ {
-+ ++i;
-+ this.setAge( i );
-+ } else if ( i > 0 )
-+ {
-+ --i;
-+ this.setAge( i );
-+ }
-+ }
-+ }
-+ // Spigot end
-+
- @Override
- public SpawnGroupData finalizeSpawn(
- ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData spawnGroupData
@@ -66,6 +_,7 @@
}
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch
index 1f6b41bf6d..adddf98077 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch
@@ -9,25 +9,6 @@
@Nullable
public UUID ownerUUID;
-@@ -128,6 +_,18 @@
- this.duration = duration;
- }
-
-+ // Spigot start - copied from below
-+ @Override
-+ public void inactiveTick() {
-+ super.inactiveTick();
-+
-+ if (this.tickCount >= this.waitTime + this.duration) {
-+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
-+ return;
-+ }
-+ }
-+ // Spigot end
-+
- @Override
- public void tick() {
- super.tick();
@@ -177,7 +_,7 @@
private void serverTick(ServerLevel level) {
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
index 7bd2ceef50..b77ca19e9f 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
@@ -133,7 +133,7 @@
private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0};
private long pistonDeltasGameTime;
private EntityDimensions dimensions;
-@@ -250,6 +_,68 @@
+@@ -250,6 +_,63 @@
private final List<Entity.Movement> movementThisTick = new ArrayList<>();
private final Set<BlockState> blocksInside = new ReferenceArraySet<>();
private final LongSet visitedBlocks = new LongOpenHashSet();
@@ -153,12 +153,6 @@
+ // Marks an entity, that it was removed by a plugin via Entity#remove
+ // Main use case currently is for SPIGOT-7487, preventing dropping of leash when leash is removed
+ public boolean pluginRemoved = false;
-+ // Spigot start
-+ public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
-+ public final boolean defaultActivationState;
-+ public long activatedTick = Integer.MIN_VALUE;
-+ public void inactiveTick() { }
-+ // Spigot end
+ protected int numCollisions = 0; // Paper - Cap entity collisions
+ public boolean fromNetherPortal; // Paper - Add option to nerf pigmen from nether portals
+ public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
@@ -170,6 +164,7 @@
+ public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
+ public boolean fixedPose = false; // Paper - Expand Pose API
+ private final int despawnTime; // Paper - entity despawn time limit
++ public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges
+
+ public void setOrigin(@javax.annotation.Nonnull org.bukkit.Location location) {
+ this.origin = location.toVector();
@@ -202,20 +197,6 @@
public Entity(EntityType<?> entityType, Level level) {
this.type = entityType;
-@@ -258,6 +_,13 @@
- this.position = Vec3.ZERO;
- this.blockPosition = BlockPos.ZERO;
- this.chunkPosition = ChunkPos.ZERO;
-+ // Spigot start
-+ if (level != null) {
-+ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, level.spigotConfig);
-+ } else {
-+ this.defaultActivationState = false;
-+ }
-+ // Spigot end
- SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this);
- builder.define(DATA_SHARED_FLAGS_ID, (byte)0);
- builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply());
@@ -271,6 +_,7 @@
this.entityData = builder.build();
this.setPos(0.0, 0.0, 0.0);
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
index 6f3c797b1f..6a08fbc658 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
@@ -39,7 +39,7 @@
public abstract class LivingEntity extends Entity implements Attackable {
private static final Logger LOGGER = LogUtils.getLogger();
private static final String TAG_ACTIVE_EFFECTS = "active_effects";
-@@ -266,11 +_,36 @@
+@@ -266,11 +_,29 @@
EquipmentSlot.class
);
protected float appliedScale = 1.0F;
@@ -59,13 +59,6 @@
+ return this.getYHeadRot();
+ }
+ // CraftBukkit end
-+ // Spigot start
-+ public void inactiveTick()
-+ {
-+ super.inactiveTick();
-+ ++this.noActionTime; // Above all the floats
-+ }
-+ // Spigot end
protected LivingEntity(EntityType<? extends LivingEntity> entityType, Level level) {
super(entityType, level);
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch
index 7e9f5a0f27..8700616d07 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch
@@ -51,15 +51,12 @@
f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F;
}
-@@ -184,11 +_,40 @@
+@@ -184,8 +_,14 @@
}
}
- if (!this.level().isClientSide && this.age >= 6000) {
- this.discard();
-- }
-- }
-- }
+ if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate
+ // CraftBukkit start - fire ItemDespawnEvent
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
@@ -68,35 +65,9 @@
+ }
+ // CraftBukkit end
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
-+ }
-+ }
-+ }
-+
-+ // Spigot start - copied from above
-+ @Override
-+ public void inactiveTick() {
-+ if (this.pickupDelay > 0 && this.pickupDelay != 32767) {
-+ --this.pickupDelay;
-+ }
-+ if (this.age != -32768) {
-+ ++this.age;
-+ }
-+
-+ if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate
-+ // CraftBukkit start - fire ItemDespawnEvent
-+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
-+ this.age = 0;
-+ return;
-+ }
-+ // CraftBukkit end
-+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
-+ }
-+ }
-+ // Spigot end
-+
-
- @Override
- public BlockPos getBlockPosBelowThatAffectsMyMovement() {
+ }
+ }
+ }
@@ -210,9 +_,18 @@
private void mergeWithNeighbours() {
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch
index 7c58286a0c..a3b4672db7 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch
@@ -15,24 +15,6 @@
public class Villager extends AbstractVillager implements ReputationEventHandler, VillagerDataHolder {
private static final Logger LOGGER = LogUtils.getLogger();
private static final EntityDataAccessor<VillagerData> DATA_VILLAGER_DATA = SynchedEntityData.defineId(Villager.class, EntityDataSerializers.VILLAGER_DATA);
-@@ -257,6 +_,17 @@
- return this.assignProfessionWhenSpawned;
- }
-
-+ // Spigot Start
-+ @Override
-+ public void inactiveTick() {
-+ // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :(
-+ if (this.level().spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) {
-+ this.customServerAiStep((ServerLevel) this.level());
-+ }
-+ super.inactiveTick();
-+ }
-+ // Spigot End
-+
- @Override
- protected void customServerAiStep(ServerLevel level) {
- ProfilerFiller profilerFiller = Profiler.get();
@@ -275,7 +_,7 @@
this.increaseProfessionLevelOnUpdate = false;
}
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch
index 23dc1ce9bf..cf61cc49d2 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch
@@ -8,7 +8,7 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
-@@ -63,16 +_,26 @@
+@@ -63,16 +_,16 @@
protected int inGroundTime;
public AbstractArrow.Pickup pickup = AbstractArrow.Pickup.DISALLOWED;
public int shakeTime;
@@ -26,16 +26,6 @@
@Nullable
- private ItemStack firedFromWeapon = null;
+ public ItemStack firedFromWeapon = null; // Paper - private -> public
-+
-+ // Spigot Start
-+ @Override
-+ public void inactiveTick() {
-+ if (this.isInGround()) {
-+ this.life += 1;
-+ }
-+ super.inactiveTick();
-+ }
-+ // Spigot End
protected AbstractArrow(EntityType<? extends AbstractArrow> entityType, Level level) {
super(entityType, level);
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch
index fb50fc5183..f0049b5ab4 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch
@@ -8,33 +8,6 @@
public FireworkRocketEntity(EntityType<? extends FireworkRocketEntity> entityType, Level level) {
super(entityType, level);
-@@ -84,6 +_,26 @@
- this.setOwner(shooter);
- }
-
-+ // Spigot Start - copied from tick
-+ @Override
-+ public void inactiveTick() {
-+ this.life += 1;
-+
-+ if (this.life > this.lifetime) {
-+ Level world = this.level();
-+
-+ if (world instanceof ServerLevel serverLevel) {
-+ // CraftBukkit start
-+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) {
-+ this.explode(serverLevel);
-+ }
-+ // CraftBukkit end
-+ }
-+ }
-+ super.inactiveTick();
-+ }
-+ // Spigot End
-+
- @Override
- protected void defineSynchedData(SynchedEntityData.Builder builder) {
- builder.define(DATA_ID_FIREWORKS_ITEM, getDefaultItem());
@@ -158,7 +_,7 @@
}
diff --git a/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java b/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java
new file mode 100644
index 0000000000..cd43845a08
--- /dev/null
+++ b/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java
@@ -0,0 +1,47 @@
+package io.papermc.paper.entity.activation;
+
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.FlyingMob;
+import net.minecraft.world.entity.PathfinderMob;
+import net.minecraft.world.entity.ambient.AmbientCreature;
+import net.minecraft.world.entity.animal.WaterAnimal;
+import net.minecraft.world.entity.monster.Enemy;
+import net.minecraft.world.entity.npc.Villager;
+import net.minecraft.world.entity.raid.Raider;
+import net.minecraft.world.phys.AABB;
+
+public enum ActivationType {
+ WATER,
+ FLYING_MONSTER,
+ VILLAGER,
+ MONSTER,
+ ANIMAL,
+ RAIDER,
+ MISC;
+
+ AABB boundingBox = new AABB(0, 0, 0, 0, 0, 0);
+
+ /**
+ * Returns the activation type for the given entity.
+ *
+ * @param entity entity to get the activation type for
+ * @return activation type
+ */
+ public static ActivationType activationTypeFor(final Entity entity) {
+ if (entity instanceof WaterAnimal) {
+ return ActivationType.WATER;
+ } else if (entity instanceof Villager) {
+ return ActivationType.VILLAGER;
+ } else if (entity instanceof FlyingMob && entity instanceof Enemy) {
+ return ActivationType.FLYING_MONSTER;
+ } else if (entity instanceof Raider) {
+ return ActivationType.RAIDER;
+ } else if (entity instanceof Enemy) {
+ return ActivationType.MONSTER;
+ } else if (entity instanceof PathfinderMob || entity instanceof AmbientCreature) {
+ return ActivationType.ANIMAL;
+ } else {
+ return ActivationType.MISC;
+ }
+ }
+}
diff --git a/paper-server/src/main/java/org/spigotmc/ActivationRange.java b/paper-server/src/main/java/org/spigotmc/ActivationRange.java
deleted file mode 100644
index 554d80ddbf..0000000000
--- a/paper-server/src/main/java/org/spigotmc/ActivationRange.java
+++ /dev/null
@@ -1,387 +0,0 @@
-package org.spigotmc;
-
-import net.minecraft.core.BlockPos;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.level.ServerChunkCache;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.entity.ExperienceOrb;
-import net.minecraft.world.entity.FlyingMob;
-import net.minecraft.world.entity.LightningBolt;
-import net.minecraft.world.entity.LivingEntity;
-import net.minecraft.world.entity.Mob;
-import net.minecraft.world.entity.PathfinderMob;
-import net.minecraft.world.entity.ai.Brain;
-import net.minecraft.world.entity.ambient.AmbientCreature;
-import net.minecraft.world.entity.animal.Animal;
-import net.minecraft.world.entity.animal.Bee;
-import net.minecraft.world.entity.animal.Sheep;
-import net.minecraft.world.entity.animal.WaterAnimal;
-import net.minecraft.world.entity.animal.horse.Llama;
-import net.minecraft.world.entity.boss.EnderDragonPart;
-import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
-import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
-import net.minecraft.world.entity.boss.wither.WitherBoss;
-import net.minecraft.world.entity.item.ItemEntity;
-import net.minecraft.world.entity.item.PrimedTnt;
-import net.minecraft.world.entity.monster.Creeper;
-import net.minecraft.world.entity.monster.Enemy;
-import net.minecraft.world.entity.monster.Pillager;
-import net.minecraft.world.entity.npc.Villager;
-import net.minecraft.world.entity.player.Player;
-import net.minecraft.world.entity.projectile.AbstractArrow;
-import net.minecraft.world.entity.projectile.AbstractHurtingProjectile;
-import net.minecraft.world.entity.projectile.EyeOfEnder;
-import net.minecraft.world.entity.projectile.FireworkRocketEntity;
-import net.minecraft.world.entity.projectile.ThrowableProjectile;
-import net.minecraft.world.entity.projectile.ThrownTrident;
-import net.minecraft.world.entity.raid.Raider;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.phys.AABB;
-
-public final class ActivationRange {
-
- private ActivationRange() {
- }
-
- public enum ActivationType {
- WATER, // Paper
- FLYING_MONSTER, // Paper
- VILLAGER, // Paper
- MONSTER,
- ANIMAL,
- RAIDER,
- MISC;
-
- AABB boundingBox = new AABB(0, 0, 0, 0, 0, 0);
- }
- // Paper start
-
- static net.minecraft.world.entity.schedule.Activity[] VILLAGER_PANIC_IMMUNITIES = {
- net.minecraft.world.entity.schedule.Activity.HIDE,
- net.minecraft.world.entity.schedule.Activity.PRE_RAID,
- net.minecraft.world.entity.schedule.Activity.RAID,
- net.minecraft.world.entity.schedule.Activity.PANIC
- };
-
- private static int checkInactiveWakeup(final Entity entity) {
- final Level world = entity.level();
- final SpigotWorldConfig config = world.spigotConfig;
- final long inactiveFor = MinecraftServer.currentTick - entity.activatedTick;
- if (entity.activationType == ActivationType.VILLAGER) {
- if (inactiveFor > config.wakeUpInactiveVillagersEvery && world.wakeupInactiveRemainingVillagers > 0) {
- world.wakeupInactiveRemainingVillagers--;
- return config.wakeUpInactiveVillagersFor;
- }
- } else if (entity.activationType == ActivationType.ANIMAL) {
- if (inactiveFor > config.wakeUpInactiveAnimalsEvery && world.wakeupInactiveRemainingAnimals > 0) {
- world.wakeupInactiveRemainingAnimals--;
- return config.wakeUpInactiveAnimalsFor;
- }
- } else if (entity.activationType == ActivationType.FLYING_MONSTER) {
- if (inactiveFor > config.wakeUpInactiveFlyingEvery && world.wakeupInactiveRemainingFlying > 0) {
- world.wakeupInactiveRemainingFlying--;
- return config.wakeUpInactiveFlyingFor;
- }
- } else if (entity.activationType == ActivationType.MONSTER || entity.activationType == ActivationType.RAIDER) {
- if (inactiveFor > config.wakeUpInactiveMonstersEvery && world.wakeupInactiveRemainingMonsters > 0) {
- world.wakeupInactiveRemainingMonsters--;
- return config.wakeUpInactiveMonstersFor;
- }
- }
- return -1;
- }
- // Paper end
-
- static AABB maxBB = new AABB(0, 0, 0, 0, 0, 0);
-
- /**
- * Initializes an entities type on construction to specify what group this
- * entity is in for activation ranges.
- *
- * @param entity
- * @return group id
- */
- public static ActivationType initializeEntityActivationType(final Entity entity) {
- if (entity instanceof WaterAnimal) {
- return ActivationType.WATER;
- } // Paper
- else if (entity instanceof Villager) {
- return ActivationType.VILLAGER;
- } // Paper
- else if (entity instanceof FlyingMob && entity instanceof Enemy) {
- return ActivationType.FLYING_MONSTER;
- } // Paper - doing & Monster incase Flying no longer includes monster in future
- if (entity instanceof Raider) {
- return ActivationType.RAIDER;
- } else if (entity instanceof Enemy) { // Paper - correct monster check
- return ActivationType.MONSTER;
- } else if (entity instanceof PathfinderMob || entity instanceof AmbientCreature) {
- return ActivationType.ANIMAL;
- } else {
- return ActivationType.MISC;
- }
- }
-
- /**
- * These entities are excluded from Activation range checks.
- *
- * @param entity
- * @param config
- * @return boolean If it should always tick.
- */
- public static boolean initializeEntityActivationState(final Entity entity, final SpigotWorldConfig config) {
- return (entity.activationType == ActivationType.MISC && config.miscActivationRange == 0)
- || (entity.activationType == ActivationType.RAIDER && config.raiderActivationRange == 0)
- || (entity.activationType == ActivationType.ANIMAL && config.animalActivationRange == 0)
- || (entity.activationType == ActivationType.MONSTER && config.monsterActivationRange == 0)
- || (entity.activationType == ActivationType.VILLAGER && config.villagerActivationRange <= 0) // Paper
- || (entity.activationType == ActivationType.WATER && config.waterActivationRange <= 0) // Paper
- || (entity.activationType == ActivationType.FLYING_MONSTER && config.flyingMonsterActivationRange <= 0) // Paper
- || entity instanceof EyeOfEnder // Paper
- || entity instanceof Player
- || entity instanceof ThrowableProjectile
- || entity instanceof EnderDragon
- || entity instanceof EnderDragonPart
- || entity instanceof WitherBoss
- || entity instanceof AbstractHurtingProjectile
- || entity instanceof LightningBolt
- || entity instanceof PrimedTnt
- || entity instanceof net.minecraft.world.entity.item.FallingBlockEntity // Paper - Always tick falling blocks
- || entity instanceof net.minecraft.world.entity.vehicle.AbstractMinecart // Paper
- || entity instanceof net.minecraft.world.entity.vehicle.AbstractBoat // Paper
- || entity instanceof EndCrystal
- || entity instanceof FireworkRocketEntity
- || entity instanceof ThrownTrident;
- }
-
- /**
- * Find what entities are in range of the players in the world and set
- * active if in range.
- *
- * @param world
- */
- public static void activateEntities(final Level world) {
- final int miscActivationRange = world.spigotConfig.miscActivationRange;
- final int raiderActivationRange = world.spigotConfig.raiderActivationRange;
- final int animalActivationRange = world.spigotConfig.animalActivationRange;
- final int monsterActivationRange = world.spigotConfig.monsterActivationRange;
- // Paper start
- final int waterActivationRange = world.spigotConfig.waterActivationRange;
- final int flyingActivationRange = world.spigotConfig.flyingMonsterActivationRange;
- final int villagerActivationRange = world.spigotConfig.villagerActivationRange;
- world.wakeupInactiveRemainingAnimals = Math.min(world.wakeupInactiveRemainingAnimals + 1, world.spigotConfig.wakeUpInactiveAnimals);
- world.wakeupInactiveRemainingVillagers = Math.min(world.wakeupInactiveRemainingVillagers + 1, world.spigotConfig.wakeUpInactiveVillagers);
- world.wakeupInactiveRemainingMonsters = Math.min(world.wakeupInactiveRemainingMonsters + 1, world.spigotConfig.wakeUpInactiveMonsters);
- world.wakeupInactiveRemainingFlying = Math.min(world.wakeupInactiveRemainingFlying + 1, world.spigotConfig.wakeUpInactiveFlying);
- final ServerChunkCache chunkProvider = (ServerChunkCache) world.getChunkSource();
- // Paper end
-
- int maxRange = Math.max(monsterActivationRange, animalActivationRange);
- maxRange = Math.max(maxRange, raiderActivationRange);
- maxRange = Math.max(maxRange, miscActivationRange);
- // Paper start
- maxRange = Math.max(maxRange, flyingActivationRange);
- maxRange = Math.max(maxRange, waterActivationRange);
- maxRange = Math.max(maxRange, villagerActivationRange);
- // Paper end
- maxRange = Math.min((world.spigotConfig.simulationDistance << 4) - 8, maxRange);
-
- for (final Player player : world.players()) {
- player.activatedTick = MinecraftServer.currentTick;
- if (world.spigotConfig.ignoreSpectatorActivation && player.isSpectator()) {
- continue;
- }
-
- // Paper start
- final int worldHeight = world.getHeight();
- ActivationRange.maxBB = player.getBoundingBox().inflate(maxRange, worldHeight, maxRange);
- ActivationType.MISC.boundingBox = player.getBoundingBox().inflate(miscActivationRange, worldHeight, miscActivationRange);
- ActivationType.RAIDER.boundingBox = player.getBoundingBox().inflate(raiderActivationRange, worldHeight, raiderActivationRange);
- ActivationType.ANIMAL.boundingBox = player.getBoundingBox().inflate(animalActivationRange, worldHeight, animalActivationRange);
- ActivationType.MONSTER.boundingBox = player.getBoundingBox().inflate(monsterActivationRange, worldHeight, monsterActivationRange);
- ActivationType.WATER.boundingBox = player.getBoundingBox().inflate(waterActivationRange, worldHeight, waterActivationRange);
- ActivationType.FLYING_MONSTER.boundingBox = player.getBoundingBox().inflate(flyingActivationRange, worldHeight, flyingActivationRange);
- ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate(villagerActivationRange, worldHeight, villagerActivationRange);
- // Paper end
-
- // Paper start
- final java.util.List<Entity> entities = world.getEntities((Entity) null, ActivationRange.maxBB, null);
- final boolean tickMarkers = world.paperConfig().entities.markers.tick; // Paper - Configurable marker ticking
- for (final Entity entity : entities) {
- // Paper start - Configurable marker ticking
- if (!tickMarkers && entity instanceof net.minecraft.world.entity.Marker) {
- continue;
- }
- // Paper end - Configurable marker ticking
- ActivationRange.activateEntity(entity);
- }
- // Paper end
- }
- }
-
- /**
- * Tries to activate an entity.
- *
- * @param entity
- */
- private static void activateEntity(final Entity entity) {
- if (MinecraftServer.currentTick > entity.activatedTick) {
- if (entity.defaultActivationState) {
- entity.activatedTick = MinecraftServer.currentTick;
- return;
- }
- if (entity.activationType.boundingBox.intersects(entity.getBoundingBox())) {
- entity.activatedTick = MinecraftServer.currentTick;
- }
- }
- }
-
- /**
- * If an entity is not in range, do some more checks to see if we should
- * give it a shot.
- *
- * @param entity
- * @return
- */
- public static int checkEntityImmunities(final Entity entity) { // Paper - return # of ticks to get immunity
- // Paper start
- final SpigotWorldConfig config = entity.level().spigotConfig;
- final int inactiveWakeUpImmunity = checkInactiveWakeup(entity);
- if (inactiveWakeUpImmunity > -1) {
- return inactiveWakeUpImmunity;
- }
- if (entity.getRemainingFireTicks() > 0) {
- return 2;
- }
- if (entity.activatedImmunityTick >= MinecraftServer.currentTick) {
- return 1;
- }
- final long inactiveFor = MinecraftServer.currentTick - entity.activatedTick;
- // Paper end
- // quick checks.
- if ((entity.activationType != ActivationType.WATER && entity.isInWater() && entity.isPushedByFluid())) // Paper
- {
- return 100; // Paper
- }
- // Paper start
- if (!entity.onGround() || entity.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D) {
- return 100;
- }
- // Paper end
- if (!(entity instanceof final AbstractArrow arrow)) {
- if ((!entity.onGround() && !(entity instanceof FlyingMob))) { // Paper - remove passengers logic
- return 10; // Paper
- }
- } else if (!arrow.isInGround()) {
- return 1; // Paper
- }
- // special cases.
- if (entity instanceof final LivingEntity living) {
- if (living.onClimbable() || living.jumping || living.hurtTime > 0 || !living.activeEffects.isEmpty() || living.isFreezing()) { // Paper
- return 1; // Paper
- }
- if (entity instanceof final Mob mob && mob.getTarget() != null) { // Paper
- return 20; // Paper
- }
- // Paper start
- if (entity instanceof final Bee bee) {
- final BlockPos movingTarget = bee.getMovingTarget();
- if (bee.isAngry() ||
- (bee.getHivePos() != null && bee.getHivePos().equals(movingTarget)) ||
- (bee.getSavedFlowerPos() != null && bee.getSavedFlowerPos().equals(movingTarget))
- ) {
- return 20;
- }
- }
- if (entity instanceof final Villager villager) {
- final Brain<Villager> behaviorController = villager.getBrain();
-
- if (config.villagersActiveForPanic) {
- for (final net.minecraft.world.entity.schedule.Activity activity : VILLAGER_PANIC_IMMUNITIES) {
- if (behaviorController.isActive(activity)) {
- return 20 * 5;
- }
- }
- }
-
- if (config.villagersWorkImmunityAfter > 0 && inactiveFor >= config.villagersWorkImmunityAfter) {
- if (behaviorController.isActive(net.minecraft.world.entity.schedule.Activity.WORK)) {
- return config.villagersWorkImmunityFor;
- }
- }
- }
- if (entity instanceof final Llama llama && llama.inCaravan()) {
- return 1;
- }
- // Paper end
- if (entity instanceof final Animal animal) {
- if (animal.isBaby() || animal.isInLove()) {
- return 5; // Paper
- }
- if (entity instanceof final Sheep sheep && sheep.isSheared()) {
- return 1; // Paper
- }
- }
- if (entity instanceof final Creeper creeper && creeper.isIgnited()) { // isExplosive
- return 20; // Paper
- }
- // Paper start
- if (entity instanceof final Mob mob && mob.targetSelector.hasTasks()) {
- return 0;
- }
- if (entity instanceof final Pillager pillager) {
- // TODO:?
- }
- // Paper end
- }
- // SPIGOT-6644: Otherwise the target refresh tick will be missed
- if (entity instanceof ExperienceOrb) {
- return 20; // Paper
- }
- return -1; // Paper
- }
-
- /**
- * Checks if the entity is active for this tick.
- *
- * @param entity
- * @return
- */
- public static boolean checkIfActive(final Entity entity) {
- // Never safe to skip fireworks or item gravity
- if (entity instanceof FireworkRocketEntity || (entity instanceof ItemEntity && (entity.tickCount + entity.getId()) % 4 == 0)) { // Paper - Needed for item gravity, see ItemEntity tick
- return true;
- }
- // Paper start - special case always immunities
- // immunize brand new entities, dead entities, and portal scenarios
- if (entity.defaultActivationState || entity.tickCount < 20 * 10 || !entity.isAlive() || (entity.portalProcess != null && !entity.portalProcess.hasExpired()) || entity.portalCooldown > 0) {
- return true;
- }
- // immunize leashed entities
- if (entity instanceof final Mob mob && mob.getLeashHolder() instanceof Player) {
- return true;
- }
- // Paper end
-
- boolean isActive = entity.activatedTick >= MinecraftServer.currentTick;
- entity.isTemporarilyActive = false; // Paper
-
- // Should this entity tick?
- if (!isActive) {
- if ((MinecraftServer.currentTick - entity.activatedTick - 1) % 20 == 0) {
- // Check immunities every 20 ticks.
- // Paper start
- final int immunity = checkEntityImmunities(entity);
- if (immunity >= 0) {
- entity.activatedTick = MinecraftServer.currentTick + immunity;
- } else {
- entity.isTemporarilyActive = true;
- }
- // Paper end
- isActive = true;
- }
- }
- // Paper - remove dumb tick skipping for active entities
- return isActive;
- }
-}
diff --git a/paper-server/src/main/java/org/spigotmc/TrackingRange.java b/paper-server/src/main/java/org/spigotmc/TrackingRange.java
index 039f8abeb5..4835431493 100644
--- a/paper-server/src/main/java/org/spigotmc/TrackingRange.java
+++ b/paper-server/src/main/java/org/spigotmc/TrackingRange.java
@@ -1,5 +1,6 @@
package org.spigotmc;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Display;
import net.minecraft.world.entity.Entity;
@@ -25,11 +26,12 @@ public final class TrackingRange {
if (defaultRange == 0) {
return defaultRange;
}
+
final SpigotWorldConfig config = entity.level().spigotConfig;
if (entity instanceof ServerPlayer) {
return config.playerTrackingRange;
- // Paper start - Simplify and set water mobs to animal tracking range
}
+
switch (entity.activationType) {
case RAIDER:
case MONSTER:
@@ -41,14 +43,15 @@ public final class TrackingRange {
return config.animalTrackingRange;
case MISC:
}
+
if (entity instanceof ItemFrame || entity instanceof Painting || entity instanceof ItemEntity || entity instanceof ExperienceOrb) {
- // Paper end
return config.miscTrackingRange;
} else if (entity instanceof Display) {
return config.displayTrackingRange;
} else {
if (entity instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon) {
- return ((net.minecraft.server.level.ServerLevel) (entity.getCommandSenderWorld())).getChunkSource().chunkMap.serverViewDistance; // Paper - enderdragon is exempt
+ // Exempt ender dragon
+ return ((ServerLevel) entity.getCommandSenderWorld()).getChunkSource().chunkMap.serverViewDistance;
}
return config.otherTrackingRange;
}