Allow disabling armor stand ticking

This commit is contained in:
Riley Park 2018-08-15 01:26:09 -07:00
parent 510b8187c7
commit c0a3a0d12c
2 changed files with 138 additions and 26 deletions

View file

@ -31,15 +31,25 @@
public class ArmorStand extends LivingEntity {
@@ -101,6 +107,7 @@
@@ -101,9 +107,17 @@
public Rotations rightArmPose;
public Rotations leftLegPose;
public Rotations rightLegPose;
+ public boolean canMove = true; // Paper
+ // Paper start - Allow ArmorStands not to tick
+ public boolean canTick = true;
+ public boolean canTickSetByAPI = false;
+ private boolean noTickPoseDirty = false;
+ private boolean noTickEquipmentDirty = false;
+ // Paper end - Allow ArmorStands not to tick
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
super(type, world);
@@ -123,7 +130,14 @@
+ if (world != null) this.canTick = world.paperConfig().entities.armorStands.tick; // Paper - Allow ArmorStands not to tick
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
@@ -123,7 +137,14 @@
return createLivingAttributes().add(Attributes.STEP_HEIGHT, 0.0D);
}
@ -54,7 +64,7 @@
public void refreshDimensions() {
double d0 = this.getX();
double d1 = this.getY();
@@ -165,7 +179,7 @@
@@ -165,7 +186,7 @@
}
@Override
@ -63,7 +73,7 @@
switch (slot.getType()) {
case HAND:
return (ItemStack) this.handItems.get(slot.getIndex());
@@ -177,19 +191,26 @@
@@ -177,21 +198,29 @@
}
@Override
@ -96,8 +106,32 @@
+ this.onEquipItem(enumitemslot, (ItemStack) this.armorItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit
}
+ this.noTickEquipmentDirty = true; // Paper - Allow ArmorStands not to tick; Still update equipment
}
@@ -327,6 +348,7 @@
@Override
@@ -227,6 +256,7 @@
}
nbt.put("Pose", this.writePose());
+ if (this.canTickSetByAPI) nbt.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick
}
@Override
@@ -261,6 +291,12 @@
this.setNoBasePlate(nbt.getBoolean("NoBasePlate"));
this.setMarker(nbt.getBoolean("Marker"));
this.noPhysics = !this.hasPhysics();
+ // Paper start - Allow ArmorStands not to tick
+ if (nbt.contains("Paper.CanTickOverride")) {
+ this.canTick = nbt.getBoolean("Paper.CanTickOverride");
+ this.canTickSetByAPI = true;
+ }
+ // Paper end - Allow ArmorStands not to tick
CompoundTag nbttagcompound2 = nbt.getCompound("Pose");
this.readPose(nbttagcompound2);
@@ -327,6 +363,7 @@
@Override
protected void pushEntities() {
@ -105,7 +139,7 @@
List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
Iterator iterator = list.iterator();
@@ -341,7 +363,7 @@
@@ -341,7 +378,7 @@
}
@Override
@ -114,7 +148,7 @@
ItemStack itemstack = player.getItemInHand(hand);
if (!this.isMarker() && !itemstack.is(Items.NAME_TAG)) {
@@ -350,11 +372,11 @@
@@ -350,11 +387,11 @@
} else if (player.level().isClientSide) {
return InteractionResult.SUCCESS_SERVER;
} else {
@ -129,7 +163,7 @@
if (this.hasItemInSlot(enumitemslot2) && this.swapItem(player, enumitemslot2, itemstack, hand)) {
return InteractionResult.SUCCESS_SERVER;
@@ -364,7 +386,7 @@
@@ -364,7 +401,7 @@
return InteractionResult.FAIL;
}
@ -138,7 +172,7 @@
return InteractionResult.FAIL;
}
@@ -380,39 +402,57 @@
@@ -380,39 +417,57 @@
}
}
@ -212,7 +246,7 @@
this.setItemSlot(slot, stack.copyWithCount(1));
return true;
} else if (!stack.isEmpty() && stack.getCount() > 1) {
@@ -427,6 +467,7 @@
@@ -427,6 +482,7 @@
player.setItemInHand(hand, itemstack1);
return true;
}
@ -220,7 +254,7 @@
}
@Override
@@ -436,12 +477,22 @@
@@ -436,12 +492,22 @@
} else if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && source.getEntity() instanceof Mob) {
return false;
} else if (source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
@ -246,7 +280,7 @@
return false;
} else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
if (this.isOnFire()) {
@@ -463,8 +514,8 @@
@@ -463,8 +529,8 @@
} else {
Entity entity = source.getEntity();
@ -257,7 +291,7 @@
if (!entityhuman.getAbilities().mayBuild) {
return false;
@@ -474,7 +525,7 @@
@@ -474,7 +540,7 @@
if (source.isCreativePlayer()) {
this.playBrokenSound();
this.showBreakingParticles();
@ -266,7 +300,7 @@
return true;
} else {
long i = world.getGameTime();
@@ -486,7 +537,7 @@
@@ -486,7 +552,7 @@
} else {
this.brokenByPlayer(world, source);
this.showBreakingParticles();
@ -275,7 +309,7 @@
}
return true;
@@ -536,7 +587,7 @@
@@ -536,7 +602,7 @@
f1 -= amount;
if (f1 <= 0.5F) {
this.brokenByAnything(world, damageSource);
@ -284,7 +318,7 @@
} else {
this.setHealth(f1);
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
@@ -548,13 +599,13 @@
@@ -548,13 +614,13 @@
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
@ -300,7 +334,7 @@
ItemStack itemstack;
int i;
@@ -562,7 +613,7 @@
@@ -562,7 +628,7 @@
for (i = 0; i < this.handItems.size(); ++i) {
itemstack = (ItemStack) this.handItems.get(i);
if (!itemstack.isEmpty()) {
@ -309,7 +343,7 @@
this.handItems.set(i, ItemStack.EMPTY);
}
}
@@ -570,15 +621,16 @@
@@ -570,15 +636,16 @@
for (i = 0; i < this.armorItems.size(); ++i) {
itemstack = (ItemStack) this.armorItems.get(i);
if (!itemstack.isEmpty()) {
@ -328,19 +362,48 @@
}
@Override
@@ -663,10 +715,24 @@
public boolean isBaby() {
@@ -609,7 +676,29 @@
@Override
public void tick() {
+ // Paper start - Allow ArmorStands not to tick
+ if (!this.canTick) {
+ if (this.noTickPoseDirty) {
+ this.noTickPoseDirty = false;
+ this.updatePose();
+ }
+
+ if (this.noTickEquipmentDirty) {
+ this.noTickEquipmentDirty = false;
+ this.detectEquipmentUpdatesPublic();
+ }
+
+ return;
+ }
+ // Paper end - Allow ArmorStands not to tick
+
super.tick();
+ // Paper start - Allow ArmorStands not to tick
+ updatePose();
+ }
+
+ public void updatePose() {
+ // Paper end - Allow ArmorStands not to tick
Rotations vector3f = (Rotations) this.entityData.get(ArmorStand.DATA_HEAD_POSE);
if (!this.headPose.equals(vector3f)) {
@@ -664,9 +753,23 @@
return this.isSmall();
}
+
+ // CraftBukkit start
+ @Override
@Override
+ public boolean shouldDropExperience() {
+ return true; // MC-157395, SPIGOT-5193 even baby (small) armor stands should drop
+ }
+ // CraftBukkit end
@Override
+
+ @Override
public void kill(ServerLevel world) {
- this.remove(Entity.RemovalReason.KILLED);
+ // CraftBukkit start - pass DamageSource for kill
@ -354,7 +417,45 @@
this.gameEvent(GameEvent.ENTITY_DIE);
}
@@ -788,7 +854,7 @@
@@ -730,31 +833,37 @@
public void setHeadPose(Rotations angle) {
this.headPose = angle;
this.entityData.set(ArmorStand.DATA_HEAD_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setBodyPose(Rotations angle) {
this.bodyPose = angle;
this.entityData.set(ArmorStand.DATA_BODY_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftArmPose(Rotations angle) {
this.leftArmPose = angle;
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightArmPose(Rotations angle) {
this.rightArmPose = angle;
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftLegPose(Rotations angle) {
this.leftLegPose = angle;
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightLegPose(Rotations angle) {
this.rightLegPose = angle;
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public Rotations getHeadPose() {
@@ -788,7 +897,7 @@
@Override
public boolean skipAttackInteraction(Entity attacker) {
@ -363,7 +464,7 @@
}
@Override
@@ -882,4 +948,13 @@
@@ -882,4 +991,13 @@
public boolean canBeSeenByAnyone() {
return !this.isInvisible() && !this.isMarker();
}

View file

@ -232,5 +232,16 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
public void setCanMove(boolean move) {
getHandle().canMove = move;
}
@Override
public boolean canTick() {
return this.getHandle().canTick;
}
@Override
public void setCanTick(final boolean tick) {
this.getHandle().canTick = tick;
this.getHandle().canTickSetByAPI = true;
}
// Paper end
}