From 9258faff3f2e976202c4cbc653c94d3477b7c7fe Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 11 Feb 2013 19:32:14 +1100 Subject: [PATCH] Apply entity activation range, the most over hyped commit ever. --- CraftBukkit-Patches/0002-Spigot-changes.patch | 8 +- ...n-Range-This-feature-gives-3-new-con.patch | 340 ++++++++++++++++++ 2 files changed, 344 insertions(+), 4 deletions(-) create mode 100644 CraftBukkit-Patches/0027-Entity-Activation-Range-This-feature-gives-3-new-con.patch diff --git a/CraftBukkit-Patches/0002-Spigot-changes.patch b/CraftBukkit-Patches/0002-Spigot-changes.patch index 207ff2823b..230a33fcb2 100644 --- a/CraftBukkit-Patches/0002-Spigot-changes.patch +++ b/CraftBukkit-Patches/0002-Spigot-changes.patch @@ -1,4 +1,4 @@ -From 80afd7d84a7d9092281b41183190bff1bc84480e Mon Sep 17 00:00:00 2001 +From dcdcd6631d28acb723e1086a142210b3e77001fd Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 3 Feb 2013 12:21:52 +1100 Subject: [PATCH] Spigot changes. @@ -448,7 +448,7 @@ index fac9ea5..43a24f5 100644 } } diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index b0bb672..b650f55 100644 +index e857612..d13fa19 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -253,7 +253,7 @@ public abstract class PlayerList { @@ -460,7 +460,7 @@ index b0bb672..b650f55 100644 } else { String s2 = socketaddress.toString(); -@@ -921,7 +921,13 @@ public abstract class PlayerList { +@@ -924,7 +924,13 @@ public abstract class PlayerList { public void r() { while (!this.players.isEmpty()) { @@ -1417,7 +1417,7 @@ index 0000000..fba4b4a +} \ No newline at end of file diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b0c23a0..747a88e 100644 +index f8dbbee..c79f352 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -212,10 +212,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/CraftBukkit-Patches/0027-Entity-Activation-Range-This-feature-gives-3-new-con.patch b/CraftBukkit-Patches/0027-Entity-Activation-Range-This-feature-gives-3-new-con.patch new file mode 100644 index 0000000000..4472b2ec60 --- /dev/null +++ b/CraftBukkit-Patches/0027-Entity-Activation-Range-This-feature-gives-3-new-con.patch @@ -0,0 +1,340 @@ +From fee453c7c632f95685e96ff767e28d6f2b9efae9 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 3 Feb 2013 05:10:21 -0500 +Subject: [PATCH] Entity Activation Range# This feature gives 3 new + configurable ranges that if an entity of the matching type is outside of this + radius of any player, will tick at 5% of its normal rate. + +This will drastically cut down on tick timings for entities that are not in range of a user to actually be "used". +This change can have dramatic impact on gameplay if configured too low. Balance according to your servers desired gameplay. +--- + src/main/java/net/minecraft/server/Entity.java | 8 ++ + .../java/net/minecraft/server/EntityArrow.java | 2 +- + src/main/java/net/minecraft/server/World.java | 10 +- + .../java/org/bukkit/craftbukkit/CraftWorld.java | 13 ++ + src/main/java/org/bukkit/craftbukkit/Spigot.java | 148 +++++++++++++++++++++ + .../java/org/bukkit/event/WorldTimingsHandler.java | 2 + + src/main/resources/configurations/bukkit.yml | 3 + + 7 files changed, 184 insertions(+), 2 deletions(-) + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index d0a58f8..9da5035 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -111,6 +111,13 @@ public abstract class Entity { + public UUID uniqueId = UUID.randomUUID(); // CraftBukkit + public boolean valid = false; // CraftBukkit + ++ // Spigot start ++ public boolean inWater = false; ++ public final byte activationType = org.bukkit.craftbukkit.Spigot.initializeEntityActivationType(this); ++ public final boolean defaultActivationState = org.bukkit.craftbukkit.Spigot.initializeEntityActivationState(this); ++ public boolean isActivated = defaultActivationState; ++ // Spigot end ++ + public Entity(World world) { + this.id = entityCount++; + this.l = 1.0D; +@@ -862,6 +869,7 @@ public abstract class Entity { + this.ad = false; + } + ++ this.inWater = this.ad; // Spigot + return this.ad; + } + +diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java +index 916b9dc..bdd18f6 100644 +--- a/src/main/java/net/minecraft/server/EntityArrow.java ++++ b/src/main/java/net/minecraft/server/EntityArrow.java +@@ -16,7 +16,7 @@ public class EntityArrow extends Entity implements IProjectile { + private int f = -1; + private int g = 0; + private int h = 0; +- private boolean inGround = false; ++ public boolean inGround = false; // Spigot - private -> public + public int fromPlayer = 0; + public int shake = 0; + public Entity shooter; +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index cd7ad64..53834a9 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1241,6 +1241,7 @@ public abstract class World implements IBlockAccess { + this.methodProfiler.c("regular"); + timings.entityBaseTick.stopTiming(); // Spigot + ++ org.bukkit.craftbukkit.Spigot.activateEntities(this); // Spigot + timings.entityTick.startTiming(); // Spigot + for (i = 0; i < this.entityList.size(); ++i) { + entity = (Entity) this.entityList.get(i); +@@ -1405,6 +1406,13 @@ public abstract class World implements IBlockAccess { + if (entity == null) { + return; + } ++ if (!entity.isActivated && !org.bukkit.craftbukkit.Spigot.checkIfActive(entity)) { ++ if (entity.vehicle == null) { ++ entity.ticksLived++; ++ } ++ return; ++ } ++ entity.isActivated = entity.defaultActivationState; + try { + tickEntity(entity, flag); + } catch (Exception e) { +@@ -1434,7 +1442,7 @@ public abstract class World implements IBlockAccess { + int j = MathHelper.floor(entity.locZ); + byte b0 = 32; + +- if (!flag || this.d(i - b0, 0, j - b0, i + b0, 0, j + b0)) { ++ if (entity instanceof EntityFireworks || !flag || this.d(i - b0, 0, j - b0, i + b0, 0, j + b0)) { // Spigot - Not safe to skip a firework. + entity.T = entity.locX; + entity.U = entity.locY; + entity.V = entity.locZ; +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 21bd64a..a083ae4 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -100,6 +100,10 @@ public class CraftWorld implements World { + treeGrowthModifier = configuration.getInt("world-settings.default.tree-growth-modifier", treeGrowthModifier); + mushroomGrowthModifier = configuration.getInt("world-settings.default.mushroom-growth-modifier", mushroomGrowthModifier); + ++ miscEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-misc", miscEntityActivationRange); ++ animalEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-animals", animalEntityActivationRange); ++ monsterEntityActivationRange = configuration.getInt("world-settings.default.entity-activation-range-monsters", monsterEntityActivationRange); ++ + //override defaults with world specific, if they exist + growthPerTick = configuration.getInt("world-settings." + name + ".growth-chunks-per-tick", growthPerTick); + itemMergeRadius = configuration.getDouble("world-settings." + name + ".item-merge-radius", itemMergeRadius); +@@ -121,6 +125,10 @@ public class CraftWorld implements World { + + obfuscated = !world.getServer().orebfuscatorDisabledWorlds.contains(name); + ++ miscEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-misc", miscEntityActivationRange); ++ animalEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-animals", animalEntityActivationRange); ++ monsterEntityActivationRange = configuration.getInt("world-settings." + name + ".entity-activation-range-monsters", monsterEntityActivationRange); ++ + server.getLogger().info("-------------- Spigot ----------------"); + server.getLogger().info("-------- World Settings For [" + name + "] --------"); + server.getLogger().info("Growth Per Chunk: " + growthPerTick); +@@ -138,6 +146,7 @@ public class CraftWorld implements World { + server.getLogger().info("Mushroom Growth Modifier: " + mushroomGrowthModifier); + server.getLogger().info("View distance: " + viewDistance); + server.getLogger().info("Oreobfuscator: " + obfuscated); ++ server.getLogger().info("Entity Activation Range: An " + animalEntityActivationRange + " / Mo " + monsterEntityActivationRange + " / Mi " + miscEntityActivationRange); + server.getLogger().info("-------------------------------------------------"); + // Spigot end + } +@@ -158,6 +167,10 @@ public class CraftWorld implements World { + public int sugarGrowthModifier = 100; + public int treeGrowthModifier = 100; + public int mushroomGrowthModifier = 100; ++ ++ public int miscEntityActivationRange = 0; ++ public int animalEntityActivationRange = 0; ++ public int monsterEntityActivationRange = 0; + // Spigot end + + public Block getBlockAt(int x, int y, int z) { +diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java +index 83988c3..be77320 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Spigot.java ++++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java +@@ -1,7 +1,9 @@ + package org.bukkit.craftbukkit; + ++import net.minecraft.server.*; + import org.bukkit.command.SimpleCommandMap; + import org.bukkit.configuration.file.YamlConfiguration; ++import java.util.List; + + public class Spigot { + public static void initialize(CraftServer server, SimpleCommandMap commandMap, YamlConfiguration configuration) { +@@ -32,5 +34,151 @@ public class Spigot { + server.getLogger().severe("[Spigot] You should not disable chunk-gc. Resetting period-in-ticks to 600 ticks."); + server.chunkGCPeriod = 600; + } ++ ++ } ++ ++ /** ++ * Initializes an entities type on construction to specify what group this ++ * entity is in for activation ranges. ++ * ++ * @param entity ++ * @return group id ++ */ ++ public static byte initializeEntityActivationType(Entity entity) { ++ if (entity instanceof EntityMonster || entity instanceof EntitySlime) { ++ return 1; // Monster ++ } else if (entity instanceof EntityCreature || entity instanceof EntityAmbient) { ++ return 2; // Animal ++ } else { ++ return 3; // Misc ++ } ++ } ++ ++ /** ++ * These entities are excluded from Activation range checks. ++ * ++ * @param entity ++ * @return boolean If it should always tick. ++ */ ++ public static boolean initializeEntityActivationState(Entity entity) { ++ if (entity instanceof EntityHuman ++ || entity instanceof EntityArrow ++ || entity instanceof EntityProjectile ++ || entity instanceof EntityEnderDragon ++ || entity instanceof EntityComplexPart ++ || entity instanceof EntityWither ++ || entity instanceof EntityFireball ++ || entity instanceof EntityWeather ++ || entity instanceof EntityTNTPrimed ++ || entity instanceof EntityEnderCrystal ++ || entity instanceof EntityFireworks) { ++ return true; ++ } ++ return false; ++ } ++ ++ /** ++ * Utility method to grow an AABB without creating a new AABB or touching ++ * the pool, so we can re-use ones we have. ++ * ++ * @param target ++ * @param source ++ * @param x ++ * @param y ++ * @param z ++ */ ++ public static void growBB(AxisAlignedBB target, AxisAlignedBB source, int x, int y, int z) { ++ target.a = source.a - x; ++ target.b = source.b - y; ++ target.c = source.c - z; ++ target.d = source.d + x; ++ target.e = source.e + y; ++ target.f = source.f + z; ++ } ++ ++ /** ++ * Find what entities are in range of the players in the world and set ++ * active if in range. ++ * ++ * @param world ++ */ ++ public static void activateEntities(World world) { ++ final int miscActivationRange = world.getWorld().miscEntityActivationRange; ++ final int animalActivationRange = world.getWorld().animalEntityActivationRange; ++ final int monsterActivationRange = world.getWorld().monsterEntityActivationRange; ++ ++ ++ world.timings.activationCheck.startTiming(); ++ int maxRange = Math.max(monsterActivationRange, animalActivationRange); ++ maxRange = Math.max(maxRange, miscActivationRange); ++ if (miscActivationRange == 0 || animalActivationRange == 0 || monsterActivationRange == 0) { ++ // One of them is disabled, set to view-distance ++ maxRange = world.getWorld().viewDistance << 4; ++ } else { ++ maxRange = Math.min(world.getWorld().viewDistance << 4, maxRange); // Do not tick on edge of unloaded chunks - vanilla behavior. ++ } ++ ++ AxisAlignedBB maxBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); ++ AxisAlignedBB miscBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); ++ AxisAlignedBB animalBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); ++ AxisAlignedBB monsterBB = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); ++ ++ for (Entity player : (List) world.players) { ++ growBB(maxBB, player.boundingBox, maxRange, 256, maxRange); ++ growBB(miscBB, player.boundingBox, miscActivationRange, 256, miscActivationRange); ++ growBB(animalBB, player.boundingBox, animalActivationRange, 256, animalActivationRange); ++ growBB(monsterBB, player.boundingBox, monsterActivationRange, 256, monsterActivationRange); ++ ++ final List list = world.getEntities(player, maxBB); ++ for (Entity entity : list) { ++ if (!entity.defaultActivationState) { ++ boolean isInRange = false; ++ switch (entity.activationType) { ++ case 1: ++ if (monsterActivationRange == 0 || monsterBB.a(entity.boundingBox)) { ++ isInRange = true; ++ } ++ break; ++ case 2: ++ if (animalActivationRange == 0 || animalBB.a(entity.boundingBox)) { ++ isInRange = true; ++ } ++ break; ++ case 3: ++ default: ++ if (miscActivationRange == 0 || miscBB.a(entity.boundingBox)) { ++ isInRange = true; ++ } ++ } ++ ++ entity.isActivated = isInRange; ++ } ++ } ++ } ++ world.timings.activationCheck.stopTiming(); ++ } ++ ++ /** ++ * 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 boolean checkIfActive(Entity entity) { ++ // quick checks. ++ if (entity.ticksLived % 20 == 0 || !entity.onGround || entity.inWater || entity.passenger != null || entity.vehicle != null) { ++ return true; ++ } ++ // special cases. ++ if (entity instanceof EntityAnimal) { ++ EntityAnimal animal = (EntityAnimal) entity; ++ if (animal.isBaby() || animal.r() /*love*/) { ++ return true; ++ } ++ return (entity instanceof EntitySheep && ((EntitySheep) entity).isSheared()); ++ } ++ return (entity instanceof EntityArrow && !((EntityArrow) entity).inGround); ++ + } + } +diff --git a/src/main/java/org/bukkit/event/WorldTimingsHandler.java b/src/main/java/org/bukkit/event/WorldTimingsHandler.java +index bb0c191..6a4a05e 100644 +--- a/src/main/java/org/bukkit/event/WorldTimingsHandler.java ++++ b/src/main/java/org/bukkit/event/WorldTimingsHandler.java +@@ -8,6 +8,7 @@ public class WorldTimingsHandler { + public CustomTimingsHandler entityBaseTick; + public CustomTimingsHandler entityTick; + public CustomTimingsHandler tileEntityTick; ++ public CustomTimingsHandler activationCheck; + public WorldTimingsHandler(World server) { + String name = server.worldData.getName() +" - "; + +@@ -16,5 +17,6 @@ public class WorldTimingsHandler { + entityBaseTick = new CustomTimingsHandler(name + "entityBaseTick"); + entityTick = new CustomTimingsHandler(name + "entityTick"); + tileEntityTick = new CustomTimingsHandler(name + "tileEntityTick"); ++ activationCheck = new CustomTimingsHandler("** " + name + "activateEntities"); + } + } +diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml +index 6931712..06ac168 100644 +--- a/src/main/resources/configurations/bukkit.yml ++++ b/src/main/resources/configurations/bukkit.yml +@@ -49,6 +49,9 @@ world-settings: + sugar-growth-modifier: 100 + tree-growth-modifier: 100 + mushroom-growth-modifier: 100 ++ entity-activation-range-animals: 48 ++ entity-activation-range-monsters: 48 ++ entity-activation-range-misc: 16 + world: + growth-chunks-per-tick: 1000 + world_nether: +-- +1.8.1-rc2 +