Move Aikar's EAR 1 into EAR 2 patch

This commit is contained in:
Nassim Jahnke
2024-12-16 14:08:25 +01:00
parent 47c06357f7
commit f8cb014d20
13 changed files with 666 additions and 645 deletions

View File

@@ -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();

View File

@@ -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 @@
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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() {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 @@
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}