mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-15 07:01:36 +08:00
eaa76a3115
Stuff like restocking trades and reputation changes can happen when a Villager is out of Activation Range now.
801 lines
40 KiB
Diff
801 lines
40 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/BehaviorController.java b/src/main/java/net/minecraft/server/BehaviorController.java
|
|
index a1883eba63e0da420a3cf57b8da6ebdb2afbad80..7c6e687707cdf32638eee41e549818a494cd45ab 100644
|
|
--- a/src/main/java/net/minecraft/server/BehaviorController.java
|
|
+++ b/src/main/java/net/minecraft/server/BehaviorController.java
|
|
@@ -161,6 +161,7 @@ public class BehaviorController<E extends EntityLiving> implements MinecraftSeri
|
|
});
|
|
}
|
|
|
|
+ public boolean hasActivity(Activity activity) { return c(activity); } // Paper - OBFHELPER
|
|
public boolean c(Activity activity) {
|
|
return this.g.contains(activity);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index fbec89c6d827463ea28036617acaa573c8e11d02..a1245c1f551cbce84b0f3dd3a7349e8585631a82 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() { }
|
|
@@ -553,6 +554,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;
|
|
@@ -565,6 +567,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
this.y = 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.e(vec3d);
|
|
@@ -2769,6 +2778,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
return this.am;
|
|
}
|
|
|
|
+ public boolean isPushedByWater() { return this.bM(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
|
|
public boolean bM() {
|
|
// 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 b40c8d2f83a80bcb8925632a1e7d6bb4cc0caebf..4eda130750ff4903c3dc7d2afae09b8b77ff62b9 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 6d53254f8381f3a957673930c7fdf42d4b9d2f36..5aca7a9131787415fb2edba1ebec9601e8a56d3a 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
@@ -46,7 +46,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
public MinecraftKey lootTableKey;
|
|
public long lootTableSeed;
|
|
@Nullable
|
|
- private Entity leashHolder;
|
|
+ public Entity leashHolder; // Paper
|
|
private int bF;
|
|
@Nullable
|
|
private NBTTagCompound bG;
|
|
@@ -114,6 +114,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 252b3c59294a75618622950286969f5e656da85a..38f666bb115d7d29da8eac1f4848ba23ef29ba43 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
|
@@ -91,7 +91,7 @@ public abstract class EntityLiving extends Entity {
|
|
protected float aV;
|
|
protected int aW; protected int getKillCount() { return this.aW; } // Paper - OBFHELPER
|
|
public float lastDamage;
|
|
- protected boolean jumping;
|
|
+ public boolean jumping; // Paper
|
|
public float aZ;
|
|
public float ba;
|
|
public float bb;
|
|
diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
|
|
index 6d4d41c88c206ad63f3733b5c8b3f23eb40dde52..193dbfc5f684bfe46f69cb2ab2c52dbb44707792 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityLlama.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityLlama.java
|
|
@@ -382,6 +382,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
|
return this.bK != null;
|
|
}
|
|
|
|
+ public boolean inCaravan() { return this.fd(); } // Paper - OBFHELPER
|
|
public boolean fd() {
|
|
return this.bJ != null;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
|
|
index 6e0020ae0b4d2f2597843129b83fff0d194de337..b3462576469f67dca618c54bb35fd53454afcd1f 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityVillager.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
|
|
@@ -135,17 +135,30 @@ 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() {
|
|
+ @Override // Paper start - tick trades while inactive
|
|
+ protected void mobTick() { mobTick(false); }
|
|
+ protected void mobTick(boolean inactive) {
|
|
+ // Paper end
|
|
this.world.getMethodProfiler().enter("brain");
|
|
- this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error
|
|
+ if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper
|
|
this.world.getMethodProfiler().exit();
|
|
if (!this.et() && this.bB > 0) {
|
|
--this.bB;
|
|
@@ -165,7 +178,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
this.bD = 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_(new BlockPosition(this));
|
|
|
|
if (raid != null && raid.v() && !raid.a()) {
|
|
@@ -176,6 +189,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.et()) {
|
|
this.ey();
|
|
}
|
|
+ if (inactive) return; // Paper
|
|
|
|
super.mobTick();
|
|
}
|
|
@@ -819,6 +833,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
|
}
|
|
}
|
|
|
|
+ private void doReputationTick() { fa(); } // Paper - OBFHELPER
|
|
private void fa() {
|
|
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 9b75c67c72bc2837cf12bf7ef8172031831deb6e..463528532026e9757431a90cc2540af0f7903faf 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
|
|
@@ -43,10 +43,12 @@ public abstract class EntityVillagerAbstract extends EntityAgeable implements NP
|
|
return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound);
|
|
}
|
|
|
|
+ public final int getUnhappy() { return eq(); } // Paper - OBFHELPER
|
|
public int eq() {
|
|
return (Integer) this.datawatcher.get(EntityVillagerAbstract.bx);
|
|
}
|
|
|
|
+ public final void setUnhappy(int i) { s(i); } // Paper - OBFHELPER
|
|
public void s(int i) {
|
|
this.datawatcher.set(EntityVillagerAbstract.bx, i);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
|
index f22f12eeb0b10d038fcd74cc4b19e888b134c3c7..bdb90a346639db37d3c72359c28b72d021d1b389 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 41fb166ce0ab29148ebd40e147fef98d1a2e9609..e93129f0b281e242383e36c99d19f6b0577a0b6b 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.g(blockposition).e(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 44bb18c5945b69f09b3a6e6272f2c3a5477780c7..935136771e776fe498f608a159a41393340adc4e 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
|
@@ -24,10 +24,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 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(GameProfilerFiller gameprofilerfiller) {
|
|
this.e = gameprofilerfiller;
|
|
@@ -37,6 +38,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 5a8c60ad909394413427851db8068ba79c058b63..29657fed75184aee0c89e56f5e642a5d68eda444 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 6b6612de65081895825858f52d0f1c6f23c8edb6..3742be65afebcf4c61a9efbd1c207f968e5f7473 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -76,6 +76,12 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
public long ticksPerMonsterSpawns;
|
|
public long ticksPerWaterSpawns;
|
|
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 92601c581cffac471872226abeb93ef9aa24f079..d873b8cf3aec01b791565c33b252889f99f181f9 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.onGround || !entity.passengers.isEmpty() || entity.isPassenger() )
|
|
+ if ( (!entity.onGround && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() ) // Paper
|
|
{
|
|
- 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.hasActivity(activity)) {
|
|
+ return 20*5;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (config.villagersWorkImmunityAfter > 0 && inactiveFor >= config.villagersWorkImmunityAfter) {
|
|
+ if (behaviorController.hasActivity(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 37ef07338e0e7ebb778b4446c8e7a630f597c7be..69454bc3c51c0d7c6f1b6d1fbcba93322205bab6 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 );
|
|
}
|