PaperMC/feature-patches/1043-Entity-Activation-Range-2.0.patch
2024-12-16 13:03:53 +01:00

302 lines
15 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 13 May 2016 01:38:06 -0400
Subject: [PATCH] Entity Activation Range 2.0
Optimizes performance of Activation Range
Adds many new configurations and a new wake up inactive system
Fixes and adds new Immunities to improve gameplay behavior
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/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 1d7e9492a474c99dff372d6b57f1f195e42d5114..aa5eed48871b5ab67d18213e532271241aae9182 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
profilerFiller.incrementCounter("tickNonPassenger");
// Spigot start
final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2
- if (isActive) {
+ 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()) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 0aed1e455dec32c3d53d8fb2f1047e1bf177f171..8c2441a6c7abc3a80426923c1ea42000283ee167 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
} else {
this.wasOnFire = this.isOnFire();
if (type == MoverType.PISTON) {
+ this.activatedTick = Math.max(this.activatedTick, MinecraftServer.currentTick + 20); // Paper - EAR 2
+ this.activatedImmunityTick = Math.max(this.activatedImmunityTick, MinecraftServer.currentTick + 20); // Paper - EAR 2
movement = this.limitPistonMovement(movement);
if (movement.equals(Vec3.ZERO)) {
return;
@@ -972,6 +976,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();
+ return;
+ }
+ // Paper end
movement = this.maybeBackOffFromEdge(movement, type);
Vec3 vec3 = this.collide(movement);
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
+++ b/net/minecraft/world/entity/Mob.java
@@ -215,6 +215,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
return this.lookControl;
}
+ // Paper start
+ @Override
+ public void inactiveTick() {
+ super.inactiveTick();
+ if (this.goalSelector.inactiveTick()) {
+ this.goalSelector.tick();
+ }
+ if (this.targetSelector.inactiveTick()) {
+ this.targetSelector.tick();
+ }
+ }
+ // Paper end
+
public MoveControl getMoveControl() {
return this.getControlledVehicle() instanceof Mob mob ? mob.getMoveControl() : this.moveControl;
}
diff --git a/net/minecraft/world/entity/PathfinderMob.java b/net/minecraft/world/entity/PathfinderMob.java
index 0caf50ec50f056b83a20bbc6a2fe0144593aef39..af59a700755654eb68d6bf57d0712c4a2ac6c09b 100644
--- a/net/minecraft/world/entity/PathfinderMob.java
+++ b/net/minecraft/world/entity/PathfinderMob.java
@@ -17,6 +17,8 @@ public abstract class PathfinderMob extends Mob {
super(entityType, level);
}
+ public BlockPos movingTarget; public BlockPos getMovingTarget() { return movingTarget; } // Paper
+
public float getWalkTargetValue(BlockPos pos) {
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
--- 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
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
-
public void addGoal(int priority, Goal goal) {
this.availableGoals.add(new WrappedGoal(priority, goal));
}
@@ -37,6 +37,22 @@ public class GoalSelector {
this.availableGoals.removeIf(wrappedGoal -> filter.test(wrappedGoal.getGoal()));
}
+ // Paper start - EAR 2
+ public boolean inactiveTick() {
+ this.curRate++;
+ return this.curRate % 3 == 0; // TODO newGoalRate was already unused in 1.20.4, check if this is correct
+ }
+
+ public boolean hasTasks() {
+ for (WrappedGoal task : this.availableGoals) {
+ if (task.isRunning()) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // Paper end - EAR 2
+
public void removeGoal(Goal goal) {
for (WrappedGoal wrappedGoal : this.availableGoals) {
if (wrappedGoal.getGoal() == goal && wrappedGoal.isRunning()) {
diff --git a/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20ce822608 100644
--- a/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java
@@ -23,6 +23,14 @@ public abstract class MoveToBlockGoal extends Goal {
public MoveToBlockGoal(PathfinderMob mob, double speedModifier, int searchRange) {
this(mob, speedModifier, searchRange, 1);
}
+ // Paper start - activation range improvements
+ @Override
+ public void stop() {
+ super.stop();
+ this.blockPos = BlockPos.ZERO;
+ this.mob.movingTarget = null;
+ }
+ // Paper end
public MoveToBlockGoal(PathfinderMob mob, double speedModifier, int searchRange, int verticalSearchRange) {
this.mob = mob;
@@ -113,6 +121,7 @@ public abstract class MoveToBlockGoal extends Goal {
mutableBlockPos.setWithOffset(blockPos, i4, i2 - 1, i5);
if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) {
this.blockPos = mutableBlockPos;
+ this.mob.movingTarget = mutableBlockPos == BlockPos.ZERO ? null : mutableBlockPos.immutable(); // Paper
return true;
}
}
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
index 81a6d31d90dc139e4d99c2b8e609032e8b100b2d..0b73ad491eb6992e1d8fdd7e75264c9ce712a462 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
+ if (this.getUnhappyCounter() > 0) {
+ this.setUnhappyCounter(this.getUnhappyCounter() - 1);
}
+ if (this.isEffectiveAi()) {
+ if (this.level().spigotConfig.tickInactiveVillagers) {
+ this.customServerAiStep(this.level().getMinecraftWorld());
+ } else {
+ this.customServerAiStep(this.level().getMinecraftWorld(), true);
+ }
+ }
+ maybeDecayGossip();
+ // Paper end
super.inactiveTick();
}
// Spigot End
@Override
protected void customServerAiStep(ServerLevel level) {
+ // Paper start - EAR 2
+ this.customServerAiStep(level, false);
+ }
+ protected void customServerAiStep(ServerLevel level, final boolean inactive) {
+ // Paper end - EAR 2
ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("villagerBrain");
- this.getBrain().tick(level, this);
+ if (!inactive) this.getBrain().tick(level, this); // Paper - EAR 2
profilerFiller.pop();
if (this.assignProfessionWhenSpawned) {
this.assignProfessionWhenSpawned = false;
@@ -304,7 +319,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
this.lastTradedPlayer = null;
}
- if (!this.isNoAi() && this.random.nextInt(100) == 0) {
+ if (!inactive && !this.isNoAi() && this.random.nextInt(100) == 0) { // Paper - EAR 2
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
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.isTrading()) {
this.stopTrading();
}
+ if (inactive) return; // Paper - EAR 2
super.customServerAiStep(level);
}
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
+++ b/net/minecraft/world/entity/vehicle/MinecartHopper.java
@@ -47,6 +47,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
if (flag != this.isEnabled()) {
this.setEnabled(flag);
}
+ this.immunize(); // Paper
}
public boolean isEnabled() {
@@ -100,11 +101,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
public boolean suckInItems() {
if (HopperBlockEntity.suckInItems(this.level(), this)) {
+ this.immunize(); // Paper
return true;
} else {
for (ItemEntity itemEntity : this.level()
.getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(0.25, 0.0, 0.25), EntitySelector.ENTITY_STILL_ALIVE)) {
if (HopperBlockEntity.addItem(this, itemEntity)) {
+ this.immunize(); // Paper
return true;
}
}
@@ -139,4 +142,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper
public AbstractContainerMenu createMenu(int id, Inventory playerInventory) {
return new HopperMenu(id, playerInventory, this);
}
+
+ // Paper start
+ public void immunize() {
+ this.activatedImmunityTick = Math.max(this.activatedImmunityTick, net.minecraft.server.MinecraftServer.currentTick + 20);
+ }
+ // Paper end
+
}
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index e0239091729f6be138c037951fd5c138497ee358..051a86e8a723aeb86ffa06e3cd5fab102a808cde 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -153,6 +153,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
public List<net.minecraft.world.entity.item.ItemEntity> captureDrops;
public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
+ // Paper start
+ public int wakeupInactiveRemainingAnimals;
+ public int wakeupInactiveRemainingFlying;
+ public int wakeupInactiveRemainingMonsters;
+ public int wakeupInactiveRemainingVillagers;
+ // Paper end
public boolean populating;
public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
// Paper start - add paper world config
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 754cfdcd5a28287aa3545aaffdce1e391cbefc1e..1e6e940fca9d96ef410c7bf05524bd9b24db4a79 100644
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -149,6 +149,10 @@ public class PistonMovingBlockEntity extends BlockEntity {
}
entity.setDeltaMovement(d1, d2, d3);
+ // Paper - EAR items stuck in slime pushed by a piston
+ entity.activatedTick = Math.max(entity.activatedTick, net.minecraft.server.MinecraftServer.currentTick + 10);
+ entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, net.minecraft.server.MinecraftServer.currentTick + 10);
+ // Paper end
break;
}
}