788 lines
39 KiB
Diff
788 lines
39 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/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index ef492fe260ef1d00f83b2f298a4fab4fd71ea4b5..2935c23d3cac78a8b5fbd33024d9bbf0de565ac2 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -192,6 +192,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
|
|
public final boolean defaultActivationState;
|
|
public long activatedTick = Integer.MIN_VALUE;
|
|
+ public boolean isTemporarilyActive = false; // Paper
|
|
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
|
|
protected int numCollisions = 0; // Paper
|
|
public void inactiveTick() { }
|
|
@@ -575,6 +576,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
this.recalcPosition();
|
|
} else {
|
|
if (enummovetype == EnumMoveType.PISTON) {
|
|
+ this.activatedTick = MinecraftServer.currentTick + 20; // Paper
|
|
vec3d = this.a(vec3d);
|
|
if (vec3d.equals(Vec3D.a)) {
|
|
return;
|
|
@@ -587,6 +589,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
this.x = Vec3D.a;
|
|
this.setMot(Vec3D.a);
|
|
}
|
|
+ // Paper start - ignore movement changes while inactive.
|
|
+ if (isTemporarilyActive && !(this instanceof EntityItem || this instanceof EntityMinecartAbstract) && vec3d == getMot() && enummovetype == EnumMoveType.SELF) {
|
|
+ setMot(Vec3D.a);
|
|
+ this.world.getMethodProfiler().exit();
|
|
+ return;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
vec3d = this.a(vec3d, enummovetype);
|
|
Vec3D vec3d1 = this.f(vec3d);
|
|
@@ -2694,6 +2703,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
return this.al;
|
|
}
|
|
|
|
+ public boolean isPushedByWater() { return this.bU(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
|
|
public boolean bU() {
|
|
// Paper start
|
|
return this.pushedByWater();
|
|
diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java
|
|
index c94197a50269622e8995685119bac984c45e6833..11d384729326af693a9a679195acbd594227466a 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityCreature.java
|
|
@@ -7,6 +7,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
|
|
public abstract class EntityCreature extends EntityInsentient {
|
|
|
|
public org.bukkit.craftbukkit.entity.CraftCreature getBukkitCreature() { return (org.bukkit.craftbukkit.entity.CraftCreature) super.getBukkitEntity(); } // Paper
|
|
+ public BlockPosition movingTarget = null; public BlockPosition getMovingTarget() { return movingTarget; } // Paper
|
|
|
|
protected EntityCreature(EntityTypes<? extends EntityCreature> entitytypes, World world) {
|
|
super(entitytypes, world);
|
|
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
index 513c987a56e8d2bda0bda8771285c7c8d5ca88e1..f638b21a3b457323600baeecab4a04ca76d0e813 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
@@ -47,7 +47,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
public MinecraftKey lootTableKey;
|
|
public long lootTableSeed;
|
|
@Nullable
|
|
- private Entity leashHolder;
|
|
+ public Entity leashHolder; // Paper - private -> public
|
|
private int bE;
|
|
@Nullable
|
|
private NBTTagCompound bF;
|
|
@@ -128,6 +128,17 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
return this.lookController;
|
|
}
|
|
|
|
+ // Paper start
|
|
+ @Override
|
|
+ public void inactiveTick() {
|
|
+ super.inactiveTick();
|
|
+ this.goalSelector.inactiveTick();
|
|
+ if (this.targetSelector.inactiveTick()) {
|
|
+ this.targetSelector.doTick();
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
public ControllerMove getControllerMove() {
|
|
if (this.isPassenger() && this.getVehicle() instanceof EntityInsentient) {
|
|
EntityInsentient entityinsentient = (EntityInsentient) this.getVehicle();
|
|
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
index b213a13c18ad483472808f4fe9743f74821a25cd..66bca610fbb8afc6f5b4430318c66d29af55fc19 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
@@ -97,7 +97,7 @@ public abstract class EntityLiving extends Entity {
|
|
protected float aU;
|
|
protected int aV; protected int getKillCount() { return this.aV; } // Paper - OBFHELPER
|
|
public float lastDamage;
|
|
- protected boolean jumping;
|
|
+ public boolean jumping; // Paper protected -> public
|
|
public float aY;
|
|
public float aZ;
|
|
public float ba;
|
|
diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
|
|
index 7ce3421696fbfc5a445f879dfd55a3055502a933..4fe769c761949c40bbb923cde5dfe1709843921f 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityLlama.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityLlama.java
|
|
@@ -404,6 +404,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
|
return this.bJ != null;
|
|
}
|
|
|
|
+ public final boolean inCaravan() { return this.fD(); } // Paper - OBFHELPER
|
|
public boolean fD() {
|
|
return this.bI != null;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
|
|
index a23c8d54a30a1ed1a3ed4d158da08229f59ca4c5..8d3811ead268635c4b728f5c9b8dd6c9b8ec6124 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityVillager.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
|
|
@@ -144,18 +144,29 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
@Override
|
|
public void inactiveTick() {
|
|
// SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :(
|
|
- if (world.spigotConfig.tickInactiveVillagers && this.doAITick()) {
|
|
- this.mobTick();
|
|
+ // Paper start
|
|
+ if (this.getUnhappy() > 0) {
|
|
+ this.setUnhappy(this.getUnhappy() - 1);
|
|
}
|
|
+ if (this.doAITick()) {
|
|
+ if (world.spigotConfig.tickInactiveVillagers) {
|
|
+ this.mobTick();
|
|
+ } else {
|
|
+ this.mobTick(true);
|
|
+ }
|
|
+ }
|
|
+ doReputationTick();
|
|
+ // Paper end
|
|
+
|
|
super.inactiveTick();
|
|
}
|
|
// Spigot End
|
|
|
|
@Override
|
|
- protected void mobTick() {
|
|
+ protected void mobTick() { mobTick(false); }
|
|
+ protected void mobTick(boolean inactive) {
|
|
this.world.getMethodProfiler().enter("villagerBrain");
|
|
- this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error
|
|
- this.world.getMethodProfiler().exit();
|
|
+ if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper
|
|
if (this.bM) {
|
|
this.bM = false;
|
|
}
|
|
@@ -178,7 +189,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
this.bC = null;
|
|
}
|
|
|
|
- if (!this.isNoAI() && this.random.nextInt(100) == 0) {
|
|
+ if (!inactive && !this.isNoAI() && this.random.nextInt(100) == 0) { // Paper
|
|
Raid raid = ((WorldServer) this.world).c_(this.getChunkCoordinates());
|
|
|
|
if (raid != null && raid.v() && !raid.a()) {
|
|
@@ -189,6 +200,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.eO()) {
|
|
this.eT();
|
|
}
|
|
+ if (inactive) return; // Paper
|
|
|
|
super.mobTick();
|
|
}
|
|
@@ -820,6 +832,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
}
|
|
}
|
|
|
|
+ private void doReputationTick() { fv(); } // Paper - OBFHELPER
|
|
private void fv() {
|
|
long i = this.world.getTime();
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
|
|
index b2ea467f26f78d3239062c6c3b9741b87489713e..81823b5d5ef17479583fda0121c95091175fdf1e 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
|
|
@@ -45,10 +45,12 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP
|
|
return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound);
|
|
}
|
|
|
|
+ public final int getUnhappy() { return eL(); } // Paper - OBFHELPER
|
|
public int eL() {
|
|
return (Integer) this.datawatcher.get(EntityVillagerAbstract.bw);
|
|
}
|
|
|
|
+ public final void setUnhappy(int i) { s(i); } // Paper - OBFHELPER
|
|
public void s(int i) {
|
|
this.datawatcher.set(EntityVillagerAbstract.bw, i);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
|
index d9454448119a3c1590b7f9ef141dccf10d4742cc..384300894d19ff70556c23b130c01b2e49aa3f20 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoal.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
|
@@ -20,7 +20,10 @@ public abstract class PathfinderGoal {
|
|
|
|
public void c() {}
|
|
|
|
- public void d() {}
|
|
+ public void d() {
|
|
+ onTaskReset(); // Paper
|
|
+ }
|
|
+ public void onTaskReset() {} // Paper
|
|
|
|
public void e() {}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
|
|
index b0e17a5764ae4668ef45c4b5e8fe7280b3f5bfdf..3e26c32d0c886c6bd70aa4823d8738cdde7a6b24 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java
|
|
@@ -4,12 +4,12 @@ import java.util.EnumSet;
|
|
|
|
public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
|
|
|
- protected final EntityCreature a;
|
|
+ protected final EntityCreature a;public EntityCreature getEntity() { return a; } // Paper - OBFHELPER
|
|
public final double b;
|
|
protected int c;
|
|
protected int d;
|
|
private int g;
|
|
- protected BlockPosition e;
|
|
+ protected BlockPosition e; public BlockPosition getTarget() { return e; } public void setTarget(BlockPosition pos) { this.e = pos; getEntity().movingTarget = pos != BlockPosition.ZERO ? pos : null; } // Paper - OBFHELPER
|
|
private boolean h;
|
|
private final int i;
|
|
private final int j;
|
|
@@ -18,6 +18,13 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
|
public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i) {
|
|
this(entitycreature, d0, i, 1);
|
|
}
|
|
+ // Paper start - activation range improvements
|
|
+ @Override
|
|
+ public void onTaskReset() {
|
|
+ super.onTaskReset();
|
|
+ setTarget(BlockPosition.ZERO);
|
|
+ }
|
|
+ // Paper end
|
|
|
|
public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i, int j) {
|
|
this.e = BlockPosition.ZERO;
|
|
@@ -100,6 +107,7 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
|
blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, i1, k - 1, j1);
|
|
if (this.a.a((BlockPosition) blockposition_mutableblockposition) && this.a(this.a.world, blockposition_mutableblockposition)) {
|
|
this.e = blockposition_mutableblockposition;
|
|
+ setTarget(blockposition_mutableblockposition.immutableCopy()); // Paper
|
|
return true;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
|
index 482ce2cd8123252110508e8e03aa65afdd533e0a..b18e53220d8dbd50723c4201231091cbe4f4119a 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
|
@@ -25,10 +25,11 @@ public class PathfinderGoalSelector {
|
|
}
|
|
};
|
|
private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class);
|
|
- private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();
|
|
+ private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
|
|
private final Supplier<GameProfilerFiller> e;
|
|
private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class);
|
|
- private int g = 3;
|
|
+ private int g = 3;private int getTickRate() { return g; } // Paper - OBFHELPER
|
|
+ private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO
|
|
|
|
public PathfinderGoalSelector(Supplier<GameProfilerFiller> supplier) {
|
|
this.e = supplier;
|
|
@@ -38,6 +39,25 @@ public class PathfinderGoalSelector {
|
|
this.d.add(new PathfinderGoalWrapped(i, pathfindergoal));
|
|
}
|
|
|
|
+ // Paper start
|
|
+ public boolean inactiveTick() {
|
|
+ if (getCurRate() % getTickRate() != 0) {
|
|
+ incRate();
|
|
+ return false;
|
|
+ } else {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ public boolean hasTasks() {
|
|
+ for (PathfinderGoalWrapped task : getTasks()) {
|
|
+ if (task.isRunning()) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
public void a(PathfinderGoal pathfindergoal) {
|
|
this.d.stream().filter((pathfindergoalwrapped) -> {
|
|
return pathfindergoalwrapped.j() == pathfindergoal;
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
|
|
index 50487dbf0ac162d7608b67b4fb50fa7f8bfba69d..04b28555b1bb68536e40bb652613678775337b31 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
|
|
@@ -64,6 +64,7 @@ public class PathfinderGoalWrapped extends PathfinderGoal {
|
|
return this.a.i();
|
|
}
|
|
|
|
+ public boolean isRunning() { return this.g(); } // Paper - OBFHELPER
|
|
public boolean g() {
|
|
return this.c;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 4317c901419d13ed6f5737543399d4e340e30bc4..97840c0a673402f258e172873fd6756bc23f298b 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -82,6 +82,12 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
public long ticksPerWaterSpawns;
|
|
public long ticksPerWaterAmbientSpawns;
|
|
public long ticksPerAmbientSpawns;
|
|
+ // 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
|
|
|
|
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
|
index b73af0a5fb2d08c2f3a52c699ef0d8ed34c83f77..5dcc1ba547db7cc53a08426a7ad119ae88690136 100644
|
|
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
|
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
|
@@ -2,24 +2,34 @@ package org.spigotmc;
|
|
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
+
|
|
+import net.minecraft.server.Activity;
|
|
import net.minecraft.server.AxisAlignedBB;
|
|
+import net.minecraft.server.BehaviorController;
|
|
+import net.minecraft.server.BlockPosition;
|
|
import net.minecraft.server.Chunk;
|
|
+import net.minecraft.server.ChunkProviderServer; // Paper
|
|
import net.minecraft.server.Entity;
|
|
import net.minecraft.server.EntityAmbient;
|
|
import net.minecraft.server.EntityAnimal;
|
|
import net.minecraft.server.EntityArrow;
|
|
+import net.minecraft.server.EntityBee;
|
|
import net.minecraft.server.EntityComplexPart;
|
|
import net.minecraft.server.EntityCreature;
|
|
import net.minecraft.server.EntityCreeper;
|
|
import net.minecraft.server.EntityEnderCrystal;
|
|
import net.minecraft.server.EntityEnderDragon;
|
|
+import net.minecraft.server.EntityEnderSignal;
|
|
import net.minecraft.server.EntityFallingBlock; // Paper
|
|
import net.minecraft.server.EntityFireball;
|
|
import net.minecraft.server.EntityFireworks;
|
|
+import net.minecraft.server.EntityFlying;
|
|
import net.minecraft.server.EntityHuman;
|
|
import net.minecraft.server.EntityLightning;
|
|
import net.minecraft.server.EntityLiving;
|
|
import net.minecraft.server.EntityMonster;
|
|
+import net.minecraft.server.EntityPillager;
|
|
+import net.minecraft.server.EntityPlayer;
|
|
import net.minecraft.server.EntityProjectile;
|
|
import net.minecraft.server.EntityRaider;
|
|
import net.minecraft.server.EntitySheep;
|
|
@@ -29,16 +39,26 @@ import net.minecraft.server.EntityTNTPrimed;
|
|
import net.minecraft.server.EntityThrownTrident;
|
|
import net.minecraft.server.EntityVillager;
|
|
import net.minecraft.server.EntityWither;
|
|
+import net.minecraft.server.IMonster;
|
|
import net.minecraft.server.MathHelper;
|
|
+import net.minecraft.server.MemoryModuleType;
|
|
import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.server.World;
|
|
import co.aikar.timings.MinecraftTimings;
|
|
+// Paper start
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.EntityLlama;
|
|
+import net.minecraft.server.EntityWaterAnimal;
|
|
+// Paper end
|
|
|
|
public class ActivationRange
|
|
{
|
|
|
|
public enum ActivationType
|
|
{
|
|
+ WATER, // Paper
|
|
+ FLYING_MONSTER, // Paper
|
|
+ VILLAGER, // Paper
|
|
MONSTER,
|
|
ANIMAL,
|
|
RAIDER,
|
|
@@ -46,6 +66,43 @@ public class ActivationRange
|
|
|
|
AxisAlignedBB boundingBox = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
|
|
}
|
|
+ // Paper start
|
|
+
|
|
+ static Activity[] VILLAGER_PANIC_IMMUNITIES = {
|
|
+ Activity.HIDE,
|
|
+ Activity.PRE_RAID,
|
|
+ Activity.RAID,
|
|
+ Activity.PANIC
|
|
+ };
|
|
+
|
|
+ private static int checkInactiveWakeup(Entity entity) {
|
|
+ World world = entity.world;
|
|
+ SpigotWorldConfig config = world.spigotConfig;
|
|
+ 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 AxisAlignedBB maxBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
|
|
|
|
@@ -58,10 +115,13 @@ public class ActivationRange
|
|
*/
|
|
public static ActivationType initializeEntityActivationType(Entity entity)
|
|
{
|
|
+ if (entity instanceof EntityWaterAnimal) { return ActivationType.WATER; } // Paper
|
|
+ else if (entity instanceof EntityVillager) { return ActivationType.VILLAGER; } // Paper
|
|
+ else if (entity instanceof EntityFlying && entity instanceof IMonster) { return ActivationType.FLYING_MONSTER; } // Paper - doing & Monster incase Flying no longer includes monster in future
|
|
if ( entity instanceof EntityRaider )
|
|
{
|
|
return ActivationType.RAIDER;
|
|
- } else if ( entity instanceof EntityMonster || entity instanceof EntitySlime )
|
|
+ } else if ( entity instanceof IMonster ) // Paper - correct monster check
|
|
{
|
|
return ActivationType.MONSTER;
|
|
} else if ( entity instanceof EntityCreature || entity instanceof EntityAmbient )
|
|
@@ -82,10 +142,14 @@ public class ActivationRange
|
|
*/
|
|
public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config)
|
|
{
|
|
- if ( ( 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 )
|
|
+ if ( ( 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 EntityEnderSignal // Paper
|
|
|| entity instanceof EntityHuman
|
|
|| entity instanceof EntityProjectile
|
|
|| entity instanceof EntityEnderDragon
|
|
@@ -118,10 +182,25 @@ public class ActivationRange
|
|
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 ChunkProviderServer chunkProvider = (ChunkProviderServer) world.getChunkProvider();
|
|
+ // 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.viewDistance << 4 ) - 8, maxRange );
|
|
|
|
for ( EntityHuman player : world.getPlayers() )
|
|
@@ -133,6 +212,11 @@ public class ActivationRange
|
|
ActivationType.RAIDER.boundingBox = player.getBoundingBox().grow( raiderActivationRange, 256, raiderActivationRange );
|
|
ActivationType.ANIMAL.boundingBox = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange );
|
|
ActivationType.MONSTER.boundingBox = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange );
|
|
+ // Paper start
|
|
+ ActivationType.WATER.boundingBox = player.getBoundingBox().grow( waterActivationRange, 256, waterActivationRange );
|
|
+ ActivationType.FLYING_MONSTER.boundingBox = player.getBoundingBox().grow( flyingActivationRange, 256, flyingActivationRange );
|
|
+ ActivationType.VILLAGER.boundingBox = player.getBoundingBox().grow( villagerActivationRange, 256, waterActivationRange );
|
|
+ // Paper end
|
|
|
|
int i = MathHelper.floor( maxBB.minX / 16.0D );
|
|
int j = MathHelper.floor( maxBB.maxX / 16.0D );
|
|
@@ -143,7 +227,7 @@ public class ActivationRange
|
|
{
|
|
for ( int j1 = k; j1 <= l; ++j1 )
|
|
{
|
|
- Chunk chunk = (Chunk) world.getChunkIfLoadedImmediately( i1, j1 );
|
|
+ Chunk chunk = chunkProvider.getChunkAtIfLoadedMainThreadNoCache( i1, j1 ); // Paper
|
|
if ( chunk != null )
|
|
{
|
|
activateChunkEntities( chunk );
|
|
@@ -161,19 +245,15 @@ public class ActivationRange
|
|
*/
|
|
private static void activateChunkEntities(Chunk chunk)
|
|
{
|
|
- for ( List<Entity> slice : chunk.entitySlices )
|
|
- {
|
|
- for ( Entity entity : (Collection<Entity>) slice )
|
|
+ // Paper start
|
|
+ Entity[] rawData = chunk.entities.getRawData();
|
|
+ for (int i = 0; i < chunk.entities.size(); i++) {
|
|
+ Entity entity = rawData[i];
|
|
+ //for ( Entity entity : (Collection<Entity>) slice )
|
|
+ // Paper end
|
|
{
|
|
- if ( MinecraftServer.currentTick > entity.activatedTick )
|
|
- {
|
|
- if ( entity.defaultActivationState )
|
|
- {
|
|
- entity.activatedTick = MinecraftServer.currentTick;
|
|
- continue;
|
|
- }
|
|
- if ( entity.activationType.boundingBox.c( entity.getBoundingBox() ) )
|
|
- {
|
|
+ if (MinecraftServer.currentTick > entity.activatedTick) {
|
|
+ if (entity.defaultActivationState || entity.activationType.boundingBox.c(entity.getBoundingBox())) { // Paper
|
|
entity.activatedTick = MinecraftServer.currentTick;
|
|
}
|
|
}
|
|
@@ -188,56 +268,105 @@ public class ActivationRange
|
|
* @param entity
|
|
* @return
|
|
*/
|
|
- public static boolean checkEntityImmunities(Entity entity)
|
|
+ public static int checkEntityImmunities(Entity entity) // Paper - return # of ticks to get immunity
|
|
{
|
|
+ // Paper start
|
|
+ SpigotWorldConfig config = entity.world.spigotConfig;
|
|
+ int inactiveWakeUpImmunity = checkInactiveWakeup(entity);
|
|
+ if (inactiveWakeUpImmunity > -1) {
|
|
+ return inactiveWakeUpImmunity;
|
|
+ }
|
|
+ if (entity.fireTicks > 0) {
|
|
+ return 2;
|
|
+ }
|
|
+ long inactiveFor = MinecraftServer.currentTick - entity.activatedTick;
|
|
+ // Paper end
|
|
// quick checks.
|
|
- if ( entity.inWater || entity.fireTicks > 0 )
|
|
+ if ( (entity.activationType != ActivationType.WATER && entity.inWater && entity.isPushedByWater()) ) // Paper
|
|
{
|
|
- return true;
|
|
+ return 100; // Paper
|
|
}
|
|
if ( !( entity instanceof EntityArrow ) )
|
|
{
|
|
- if ( !entity.isOnGround() || !entity.passengers.isEmpty() || entity.isPassenger() )
|
|
+ if ( (!entity.isOnGround() && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() )
|
|
{
|
|
- return true;
|
|
+ return 10; // Paper
|
|
}
|
|
} else if ( !( (EntityArrow) entity ).inGround )
|
|
{
|
|
- return true;
|
|
+ return 1; // Paper
|
|
}
|
|
// special cases.
|
|
if ( entity instanceof EntityLiving )
|
|
{
|
|
EntityLiving living = (EntityLiving) entity;
|
|
- if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTicks > 0 || living.effects.size() > 0 )
|
|
+ if ( living.isClimbing() || living.jumping || living.hurtTicks > 0 || living.effects.size() > 0 ) // Paper
|
|
{
|
|
- return true;
|
|
+ return 1; // Paper
|
|
}
|
|
- if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).getGoalTarget() != null )
|
|
+ if ( entity instanceof EntityInsentient && ((EntityInsentient) entity ).getGoalTarget() != null) // Paper
|
|
{
|
|
- return true;
|
|
+ return 20; // Paper
|
|
}
|
|
- if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).canBreed() )
|
|
+ // Paper start
|
|
+ if (entity instanceof EntityBee) {
|
|
+ EntityBee bee = (EntityBee)entity;
|
|
+ BlockPosition movingTarget = bee.getMovingTarget();
|
|
+ if (bee.isAngry() ||
|
|
+ (bee.getHivePos() != null && bee.getHivePos().equals(movingTarget)) ||
|
|
+ (bee.getFlowerPos() != null && bee.getFlowerPos().equals(movingTarget))
|
|
+ ) {
|
|
+ return 20;
|
|
+ }
|
|
+ }
|
|
+ if ( entity instanceof EntityVillager ) {
|
|
+ BehaviorController<EntityVillager> behaviorController = ((EntityVillager) entity).getBehaviorController();
|
|
+
|
|
+ if (config.villagersActiveForPanic) {
|
|
+ for (Activity activity : VILLAGER_PANIC_IMMUNITIES) {
|
|
+ if (behaviorController.c(activity)) {
|
|
+ return 20*5;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (config.villagersWorkImmunityAfter > 0 && inactiveFor >= config.villagersWorkImmunityAfter) {
|
|
+ if (behaviorController.c(Activity.WORK)) {
|
|
+ return config.villagersWorkImmunityFor;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if ( entity instanceof EntityLlama && ( (EntityLlama ) entity ).inCaravan() )
|
|
{
|
|
- return true;
|
|
+ return 1;
|
|
}
|
|
+ // Paper end
|
|
if ( entity instanceof EntityAnimal )
|
|
{
|
|
EntityAnimal animal = (EntityAnimal) entity;
|
|
if ( animal.isBaby() || animal.isInLove() )
|
|
{
|
|
- return true;
|
|
+ return 5; // Paper
|
|
}
|
|
if ( entity instanceof EntitySheep && ( (EntitySheep) entity ).isSheared() )
|
|
{
|
|
- return true;
|
|
+ return 1; // Paper
|
|
}
|
|
}
|
|
if (entity instanceof EntityCreeper && ((EntityCreeper) entity).isIgnited()) { // isExplosive
|
|
- return true;
|
|
+ return 20; // Paper
|
|
}
|
|
+ // Paper start
|
|
+ if (entity instanceof EntityInsentient && ((EntityInsentient) entity).targetSelector.hasTasks() ) {
|
|
+ return 0;
|
|
+ }
|
|
+ if (entity instanceof EntityPillager) {
|
|
+ EntityPillager pillager = (EntityPillager) entity;
|
|
+ // TODO:?
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
- return false;
|
|
+ return -1; // Paper
|
|
}
|
|
|
|
/**
|
|
@@ -252,8 +381,19 @@ public class ActivationRange
|
|
if ( !entity.inChunk || entity instanceof EntityFireworks ) {
|
|
return true;
|
|
}
|
|
+ // Paper start - special case always immunities
|
|
+ // immunize brand new entities, dead entities, and portal scenarios
|
|
+ if (entity.defaultActivationState || entity.ticksLived < 20*10 || !entity.isAlive() || entity.inPortal() || entity.portalCooldown > 0) {
|
|
+ return true;
|
|
+ }
|
|
+ // immunize leashed entities
|
|
+ if (entity instanceof EntityInsentient && ((EntityInsentient)entity).leashHolder instanceof EntityHuman) {
|
|
+ return true;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
- boolean isActive = entity.activatedTick >= MinecraftServer.currentTick || entity.defaultActivationState;
|
|
+ boolean isActive = entity.activatedTick >= MinecraftServer.currentTick;
|
|
+ entity.isTemporarilyActive = false; // Paper
|
|
|
|
// Should this entity tick?
|
|
if ( !isActive )
|
|
@@ -261,15 +401,19 @@ public class ActivationRange
|
|
if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 )
|
|
{
|
|
// Check immunities every 20 ticks.
|
|
- if ( checkEntityImmunities( entity ) )
|
|
- {
|
|
- // Triggered some sort of immunity, give 20 full ticks before we check again.
|
|
- entity.activatedTick = MinecraftServer.currentTick + 20;
|
|
+ // Paper start
|
|
+ int immunity = checkEntityImmunities(entity);
|
|
+ if (immunity >= 0) {
|
|
+ entity.activatedTick = MinecraftServer.currentTick + immunity;
|
|
+ } else {
|
|
+ entity.isTemporarilyActive = true;
|
|
}
|
|
+ // Paper end
|
|
isActive = true;
|
|
+
|
|
}
|
|
// Add a little performance juice to active entities. Skip 1/4 if not immune.
|
|
- } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !checkEntityImmunities( entity ) )
|
|
+ } else if (entity.ticksLived % 4 == 0 && checkEntityImmunities( entity) < 0 ) // Paper
|
|
{
|
|
isActive = false;
|
|
}
|
|
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
index f0ad5fa235adfd165b8e56be7352568a3b3ae54a..9859e0c964e4d1e7dc7689cb97f40643a8e5cdd7 100644
|
|
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
|
@@ -180,13 +180,59 @@ public class SpigotWorldConfig
|
|
public int monsterActivationRange = 32;
|
|
public int raiderActivationRange = 48;
|
|
public int miscActivationRange = 16;
|
|
+ // Paper start
|
|
+ public int flyingMonsterActivationRange = 32;
|
|
+ public int waterActivationRange = 16;
|
|
+ public int villagerActivationRange = 32;
|
|
+ public int wakeUpInactiveAnimals = 4;
|
|
+ public int wakeUpInactiveAnimalsEvery = 60*20;
|
|
+ public int wakeUpInactiveAnimalsFor = 5*20;
|
|
+ public int wakeUpInactiveMonsters = 8;
|
|
+ public int wakeUpInactiveMonstersEvery = 20*20;
|
|
+ public int wakeUpInactiveMonstersFor = 5*20;
|
|
+ public int wakeUpInactiveVillagers = 4;
|
|
+ public int wakeUpInactiveVillagersEvery = 30*20;
|
|
+ public int wakeUpInactiveVillagersFor = 5*20;
|
|
+ public int wakeUpInactiveFlying = 8;
|
|
+ public int wakeUpInactiveFlyingEvery = 10*20;
|
|
+ public int wakeUpInactiveFlyingFor = 5*20;
|
|
+ public int villagersWorkImmunityAfter = 5*20;
|
|
+ public int villagersWorkImmunityFor = 20;
|
|
+ public boolean villagersActiveForPanic = true;
|
|
+ // Paper end
|
|
public boolean tickInactiveVillagers = true;
|
|
private void activationRange()
|
|
{
|
|
+ boolean hasAnimalsConfig = config.getInt("entity-activation-range.animals", animalActivationRange) != animalActivationRange; // Paper
|
|
animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange );
|
|
monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange );
|
|
raiderActivationRange = getInt( "entity-activation-range.raiders", raiderActivationRange );
|
|
miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange );
|
|
+ // Paper start
|
|
+ waterActivationRange = getInt( "entity-activation-range.water", waterActivationRange );
|
|
+ villagerActivationRange = getInt( "entity-activation-range.villagers", hasAnimalsConfig ? animalActivationRange : villagerActivationRange );
|
|
+ flyingMonsterActivationRange = getInt( "entity-activation-range.flying-monsters", flyingMonsterActivationRange );
|
|
+
|
|
+ wakeUpInactiveAnimals = getInt("entity-activation-range.wake-up-inactive.animals-max-per-tick", wakeUpInactiveAnimals);
|
|
+ wakeUpInactiveAnimalsEvery = getInt("entity-activation-range.wake-up-inactive.animals-every", wakeUpInactiveAnimalsEvery);
|
|
+ wakeUpInactiveAnimalsFor = getInt("entity-activation-range.wake-up-inactive.animals-for", wakeUpInactiveAnimalsFor);
|
|
+
|
|
+ wakeUpInactiveMonsters = getInt("entity-activation-range.wake-up-inactive.monsters-max-per-tick", wakeUpInactiveMonsters);
|
|
+ wakeUpInactiveMonstersEvery = getInt("entity-activation-range.wake-up-inactive.monsters-every", wakeUpInactiveMonstersEvery);
|
|
+ wakeUpInactiveMonstersFor = getInt("entity-activation-range.wake-up-inactive.monsters-for", wakeUpInactiveMonstersFor);
|
|
+
|
|
+ wakeUpInactiveVillagers = getInt("entity-activation-range.wake-up-inactive.villagers-max-per-tick", wakeUpInactiveVillagers);
|
|
+ wakeUpInactiveVillagersEvery = getInt("entity-activation-range.wake-up-inactive.villagers-every", wakeUpInactiveVillagersEvery);
|
|
+ wakeUpInactiveVillagersFor = getInt("entity-activation-range.wake-up-inactive.villagers-for", wakeUpInactiveVillagersFor);
|
|
+
|
|
+ wakeUpInactiveFlying = getInt("entity-activation-range.wake-up-inactive.flying-monsters-max-per-tick", wakeUpInactiveFlying);
|
|
+ wakeUpInactiveFlyingEvery = getInt("entity-activation-range.wake-up-inactive.flying-monsters-every", wakeUpInactiveFlyingEvery);
|
|
+ wakeUpInactiveFlyingFor = getInt("entity-activation-range.wake-up-inactive.flying-monsters-for", wakeUpInactiveFlyingFor);
|
|
+
|
|
+ villagersWorkImmunityAfter = getInt( "entity-activation-range.villagers-work-immunity-after", villagersWorkImmunityAfter );
|
|
+ villagersWorkImmunityFor = getInt( "entity-activation-range.villagers-work-immunity-for", villagersWorkImmunityFor );
|
|
+ villagersActiveForPanic = getBoolean( "entity-activation-range.villagers-active-for-panic", villagersActiveForPanic );
|
|
+ // Paper end
|
|
tickInactiveVillagers = getBoolean( "entity-activation-range.tick-inactive-villagers", tickInactiveVillagers );
|
|
log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Ra " + raiderActivationRange + " / Mi " + miscActivationRange + " / Tiv " + tickInactiveVillagers );
|
|
}
|