From 40c679a084928c09e974747d29b572bab11290c7 Mon Sep 17 00:00:00 2001 From: kashike Date: Wed, 15 Aug 2018 01:26:09 -0700 Subject: [PATCH] Allow disabling armour stand ticking diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java index a2656abaf..95fc2d8ed 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -493,4 +493,10 @@ public class PaperWorldConfig { break; } } + + public boolean armorStandTick = true; + private void armorStandTick() { + this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); + log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); + } } diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java index 7647311df..8167fe5c9 100644 --- a/src/main/java/net/minecraft/server/EntityArmorStand.java +++ b/src/main/java/net/minecraft/server/EntityArmorStand.java @@ -45,6 +45,11 @@ public class EntityArmorStand extends EntityLiving { public Vector3f leftLegPose; public Vector3f rightLegPose; public boolean canMove = true; // Paper + // Paper start - Allow ArmorStands not to tick + public boolean canTick = true; + private boolean noTickPoseDirty = false; + private boolean noTickEquipmentDirty = false; + // Paper end public EntityArmorStand(World world) { super(EntityTypes.ARMOR_STAND, world); @@ -57,6 +62,7 @@ public class EntityArmorStand extends EntityLiving { this.leftLegPose = EntityArmorStand.bB; this.rightLegPose = EntityArmorStand.bC; this.noclip = this.isNoGravity(); + if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking this.setSize(0.5F, 1.975F); this.Q = 0.0F; } @@ -131,6 +137,7 @@ public class EntityArmorStand extends EntityLiving { this.bF.set(enumitemslot.b(), itemstack); } + this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled } public boolean c(int i, ItemStack itemstack) { @@ -202,6 +209,7 @@ public class EntityArmorStand extends EntityLiving { } nbttagcompound.set("Pose", this.z()); + nbttagcompound.setBoolean("Paper.CanTick", this.canTick); // Paper - persist no tick setting } public void a(NBTTagCompound nbttagcompound) { @@ -233,6 +241,11 @@ public class EntityArmorStand extends EntityLiving { this.setMarker(nbttagcompound.getBoolean("Marker")); this.bI = !this.isMarker(); this.noclip = this.isNoGravity(); + // Paper start - persist no tick + if (nbttagcompound.hasKey("Paper.CanTick")) { + this.canTick = nbttagcompound.getBoolean("Paper.CanTick"); + } + // Paper end NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Pose"); this.g(nbttagcompound1); @@ -556,7 +569,30 @@ public class EntityArmorStand extends EntityLiving { } public void tick() { + // Paper start + if (!this.canTick) { + if (this.noTickPoseDirty) { + this.noTickPoseDirty = false; + this.updatePose(); + } + + if (this.noTickEquipmentDirty) { + this.noTickEquipmentDirty = false; + this.updateEntityEquipment(); + } + + return; + } + // Paper end + super.tick(); + + // Paper start - Split into separate method + updatePose(); + } + + public void updatePose() { + // Paper end Vector3f vector3f = (Vector3f) this.datawatcher.get(EntityArmorStand.b); if (!this.headPose.equals(vector3f)) { @@ -685,31 +721,37 @@ public class EntityArmorStand extends EntityLiving { public void setHeadPose(Vector3f vector3f) { this.headPose = vector3f; this.datawatcher.set(EntityArmorStand.b, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setBodyPose(Vector3f vector3f) { this.bodyPose = vector3f; this.datawatcher.set(EntityArmorStand.c, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setLeftArmPose(Vector3f vector3f) { this.leftArmPose = vector3f; this.datawatcher.set(EntityArmorStand.d, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setRightArmPose(Vector3f vector3f) { this.rightArmPose = vector3f; this.datawatcher.set(EntityArmorStand.e, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setLeftLegPose(Vector3f vector3f) { this.leftLegPose = vector3f; this.datawatcher.set(EntityArmorStand.f, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setRightLegPose(Vector3f vector3f) { this.rightLegPose = vector3f; this.datawatcher.set(EntityArmorStand.g, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public Vector3f r() { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index a8103ff68..21d32178c 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -2082,55 +2082,7 @@ public abstract class EntityLiving extends Entity { } } - EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); - int j = aenumitemslot.length; - - for (int k = 0; k < j; ++k) { - EnumItemSlot enumitemslot = aenumitemslot[k]; - ItemStack itemstack; - - switch (enumitemslot.a()) { - case HAND: - itemstack = (ItemStack) this.bB.get(enumitemslot.b()); - break; - - case ARMOR: - itemstack = (ItemStack) this.bC.get(enumitemslot.b()); - break; - - default: - continue; - } - - ItemStack itemstack1 = this.getEquipment(enumitemslot); - - if (!ItemStack.matches(itemstack1, itemstack)) { - // Paper start - PlayerArmorChangeEvent - if (this instanceof EntityPlayer && enumitemslot.getType() == EnumItemSlot.Function.ARMOR && !itemstack.getItem().equals(itemstack1.getItem())) { - final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack); - final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); - new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); - } - // Paper end - ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1))); - if (!itemstack.isEmpty()) { - this.getAttributeMap().a(itemstack.a(enumitemslot)); - } - - if (!itemstack1.isEmpty()) { - this.getAttributeMap().b(itemstack1.a(enumitemslot)); - } - - switch (enumitemslot.a()) { - case HAND: - this.bB.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); - break; - - case ARMOR: - this.bC.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); - } - } - } + updateEntityEquipment(); // Paper - split into own method if (this.ticksLived % 20 == 0) { this.getCombatTracker().g(); @@ -2223,6 +2175,56 @@ public abstract class EntityLiving extends Entity { } } + // Paper start - split into own method from above + public void updateEntityEquipment() { + for (EnumItemSlot enumitemslot : EnumItemSlot.values()) { + ItemStack itemstack; + + switch (enumitemslot.a()) { + case HAND: + itemstack = (ItemStack) this.bB.get(enumitemslot.b()); + break; + + case ARMOR: + itemstack = (ItemStack) this.bC.get(enumitemslot.b()); + break; + + default: + continue; + } + + ItemStack itemstack1 = this.getEquipment(enumitemslot); + + if (!ItemStack.matches(itemstack1, itemstack)) { + // Paper start - PlayerArmorChangeEvent + if (this instanceof EntityPlayer && enumitemslot.getType() == EnumItemSlot.Function.ARMOR && !itemstack.getItem().equals(itemstack1.getItem())) { + final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack); + final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); + new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); + } + // Paper end + ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1))); + if (!itemstack.isEmpty()) { + this.getAttributeMap().a(itemstack.a(enumitemslot)); + } + + if (!itemstack1.isEmpty()) { + this.getAttributeMap().b(itemstack1.a(enumitemslot)); + } + + switch (enumitemslot.a()) { + case HAND: + this.bB.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); + break; + + case ARMOR: + this.bC.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); + } + } + } + } + // Paper end + protected float e(float f, float f1) { float f2 = MathHelper.g(f - this.aQ); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index 9f5c3b92e..07ce93f17 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -297,5 +297,15 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) { return getHandle().isSlotDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); } + + @Override + public boolean canTick() { + return this.getHandle().canTick; + } + + @Override + public void setCanTick(final boolean tick) { + this.getHandle().canTick = tick; + } // Paper end } -- 2.19.1