mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-26 22:40:21 +01:00
net.minecraft.world.entity.decoration
This commit is contained in:
parent
363d5bcf57
commit
5deb3e9671
9 changed files with 667 additions and 892 deletions
|
@ -0,0 +1,376 @@
|
|||
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -86,9 +_,17 @@
|
||||
public Rotations rightArmPose = DEFAULT_RIGHT_ARM_POSE;
|
||||
public Rotations leftLegPose = DEFAULT_LEFT_LEG_POSE;
|
||||
public Rotations rightLegPose = DEFAULT_RIGHT_LEG_POSE;
|
||||
+ 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> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
+ if (level != null) this.canTick = level.paperConfig().entities.armorStands.tick; // Paper - Allow ArmorStands not to tick
|
||||
}
|
||||
|
||||
public ArmorStand(Level level, double x, double y, double z) {
|
||||
@@ -100,6 +_,13 @@
|
||||
return createLivingAttributes().add(Attributes.STEP_HEIGHT, 0.0);
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - SPIGOT-3607, SPIGOT-3637
|
||||
+ @Override
|
||||
+ public float getBukkitYaw() {
|
||||
+ return this.getYRot();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Override
|
||||
public void refreshDimensions() {
|
||||
double x = this.getX();
|
||||
@@ -159,14 +_,22 @@
|
||||
|
||||
@Override
|
||||
public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
|
||||
+ // CraftBukkit start
|
||||
+ this.setItemSlot(slot, stack, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItemSlot(net.minecraft.world.entity.EquipmentSlot slot, ItemStack stack, boolean silent) {
|
||||
+ // CraftBukkit end
|
||||
this.verifyEquippedItem(stack);
|
||||
switch (slot.getType()) {
|
||||
case HAND:
|
||||
- this.onEquipItem(slot, this.handItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(slot, this.handItems.set(slot.getIndex(), stack), stack, silent); // CraftBukkit
|
||||
break;
|
||||
case HUMANOID_ARMOR:
|
||||
- this.onEquipItem(slot, this.armorItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(slot, this.armorItems.set(slot.getIndex(), stack), stack, silent); // CraftBukkit
|
||||
}
|
||||
+ this.noTickEquipmentDirty = true; // Paper - Allow ArmorStands not to tick; Still update equipment
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,6 +_,7 @@
|
||||
}
|
||||
|
||||
compound.put("Pose", this.writePose());
|
||||
+ if (this.canTickSetByAPI) compound.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,6 +_,12 @@
|
||||
this.setNoBasePlate(compound.getBoolean("NoBasePlate"));
|
||||
this.setMarker(compound.getBoolean("Marker"));
|
||||
this.noPhysics = !this.hasPhysics();
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ if (compound.contains("Paper.CanTickOverride")) {
|
||||
+ this.canTick = compound.getBoolean("Paper.CanTickOverride");
|
||||
+ this.canTickSetByAPI = true;
|
||||
+ }
|
||||
+ // Paper end - Allow ArmorStands not to tick
|
||||
CompoundTag compound2 = compound.getCompound("Pose");
|
||||
this.readPose(compound2);
|
||||
}
|
||||
@@ -275,7 +_,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -285,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
protected void pushEntities() {
|
||||
+ if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper - Option to prevent armor stands from doing entity lookups
|
||||
for (Entity entity : this.level().getEntities(this, this.getBoundingBox(), RIDABLE_MINECARTS)) {
|
||||
if (this.distanceToSqr(entity) <= 0.2) {
|
||||
entity.push(this);
|
||||
@@ -357,7 +_,25 @@
|
||||
return false;
|
||||
} else if (itemBySlot.isEmpty() && (this.disabledSlots & 1 << slot.getFilterBit(16)) != 0) {
|
||||
return false;
|
||||
- } else if (player.hasInfiniteMaterials() && itemBySlot.isEmpty() && !stack.isEmpty()) {
|
||||
+ // CraftBukkit start
|
||||
+ } else {
|
||||
+ org.bukkit.inventory.ItemStack armorStandItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemBySlot);
|
||||
+ org.bukkit.inventory.ItemStack playerHeldItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack);
|
||||
+
|
||||
+ org.bukkit.entity.Player player1 = (org.bukkit.entity.Player) player.getBukkitEntity();
|
||||
+ org.bukkit.entity.ArmorStand self = (org.bukkit.entity.ArmorStand) this.getBukkitEntity();
|
||||
+
|
||||
+ org.bukkit.inventory.EquipmentSlot slot1 = org.bukkit.craftbukkit.CraftEquipmentSlot.getSlot(slot);
|
||||
+ org.bukkit.inventory.EquipmentSlot hand1 = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand);
|
||||
+ org.bukkit.event.player.PlayerArmorStandManipulateEvent armorStandManipulateEvent = new org.bukkit.event.player.PlayerArmorStandManipulateEvent(player1, self, playerHeldItem, armorStandItem, slot1, hand1);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(armorStandManipulateEvent);
|
||||
+
|
||||
+ if (armorStandManipulateEvent.isCancelled()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (player.hasInfiniteMaterials() && itemBySlot.isEmpty() && !stack.isEmpty()) {
|
||||
+ // CraftBukkit end
|
||||
this.setItemSlot(slot, stack.copyWithCount(1));
|
||||
return true;
|
||||
} else if (stack.isEmpty() || stack.getCount() <= 1) {
|
||||
@@ -370,6 +_,7 @@
|
||||
this.setItemSlot(slot, stack.split(1));
|
||||
return true;
|
||||
}
|
||||
+ } // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -379,15 +_,32 @@
|
||||
} else if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && damageSource.getEntity() instanceof Mob) {
|
||||
return false;
|
||||
} else if (damageSource.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
|
||||
- this.kill(level);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ this.kill(level, damageSource); // CraftBukkit
|
||||
+ // CraftBukkit end
|
||||
return false;
|
||||
- } else if (this.isInvulnerableTo(level, damageSource) || this.invisible || this.isMarker()) {
|
||||
+ } else if (this.isInvulnerableTo(level, damageSource) /*|| this.invisible*/ || this.isMarker()) { // CraftBukkit
|
||||
return false;
|
||||
} else if (damageSource.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
- this.brokenByAnything(level, damageSource);
|
||||
- this.kill(level);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount, true, this.invisible)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(level, damageSource);
|
||||
+ if (!event.isCancelled()) this.kill(damageSource, false); // CraftBukkit
|
||||
+ // Paper end
|
||||
return false;
|
||||
} else if (damageSource.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount, true, this.invisible)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (this.isOnFire()) {
|
||||
this.causeDamage(level, damageSource, 0.15F);
|
||||
} else {
|
||||
@@ -396,9 +_,19 @@
|
||||
|
||||
return false;
|
||||
} else if (damageSource.is(DamageTypeTags.BURNS_ARMOR_STANDS) && this.getHealth() > 0.5F) {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount, true, this.invisible)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.causeDamage(level, damageSource, 4.0F);
|
||||
return false;
|
||||
} else {
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount, true, this.invisible)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
boolean isCanBreakArmorStand = damageSource.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND);
|
||||
boolean isAlwaysKillsArmorStands = damageSource.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS);
|
||||
if (!isCanBreakArmorStand && !isAlwaysKillsArmorStands) {
|
||||
@@ -408,7 +_,7 @@
|
||||
} else if (damageSource.isCreativePlayer()) {
|
||||
this.playBrokenSound();
|
||||
this.showBreakingParticles();
|
||||
- this.kill(level);
|
||||
+ this.kill(level, damageSource); // CraftBukkit
|
||||
return true;
|
||||
} else {
|
||||
long gameTime = level.getGameTime();
|
||||
@@ -417,9 +_,9 @@
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
|
||||
this.lastHit = gameTime;
|
||||
} else {
|
||||
- this.brokenByPlayer(level, damageSource);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(level, damageSource); // Paper
|
||||
this.showBreakingParticles();
|
||||
- this.kill(level);
|
||||
+ if (!event.isCancelled()) this.kill(damageSource, false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...)
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -472,28 +_,31 @@
|
||||
health -= damageAmount;
|
||||
if (health <= 0.5F) {
|
||||
this.brokenByAnything(level, damageSource);
|
||||
- this.kill(level);
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(level, damageSource);
|
||||
+ if (!event.isCancelled()) this.kill(damageSource, false); // CraftBukkit
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.setHealth(health);
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
- private void brokenByPlayer(ServerLevel level, DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(ServerLevel level, DamageSource damageSource) { // Paper
|
||||
ItemStack itemStack = new ItemStack(Items.ARMOR_STAND);
|
||||
itemStack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
|
||||
- Block.popResource(this.level(), this.blockPosition(), itemStack);
|
||||
- this.brokenByAnything(level, damageSource);
|
||||
+ this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
|
||||
+ return this.brokenByAnything(level, damageSource); // Paper
|
||||
}
|
||||
|
||||
- private void brokenByAnything(ServerLevel level, DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByAnything(ServerLevel level, DamageSource damageSource) { // Paper
|
||||
this.playBrokenSound();
|
||||
- this.dropAllDeathLoot(level, damageSource);
|
||||
+ // this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved down
|
||||
|
||||
for (int i = 0; i < this.handItems.size(); i++) {
|
||||
ItemStack itemStack = this.handItems.get(i);
|
||||
if (!itemStack.isEmpty()) {
|
||||
- Block.popResource(this.level(), this.blockPosition().above(), itemStack);
|
||||
+ this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
this.handItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
@@ -501,10 +_,11 @@
|
||||
for (int ix = 0; ix < this.armorItems.size(); ix++) {
|
||||
ItemStack itemStack = this.armorItems.get(ix);
|
||||
if (!itemStack.isEmpty()) {
|
||||
- Block.popResource(this.level(), this.blockPosition().above(), itemStack);
|
||||
+ this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
this.armorItems.set(ix, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
+ return this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved from above // Paper
|
||||
}
|
||||
|
||||
private void playBrokenSound() {
|
||||
@@ -539,7 +_,28 @@
|
||||
|
||||
@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
|
||||
+ this.updatePose();
|
||||
+ }
|
||||
+
|
||||
+ public void updatePose() {
|
||||
+ // Paper end - Allow ArmorStands not to tick
|
||||
Rotations rotations = this.entityData.get(DATA_HEAD_POSE);
|
||||
if (!this.headPose.equals(rotations)) {
|
||||
this.setHeadPose(rotations);
|
||||
@@ -587,9 +_,31 @@
|
||||
return this.isSmall();
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ @Override
|
||||
+ public boolean shouldDropExperience() {
|
||||
+ return true; // MC-157395, SPIGOT-5193 even baby (small) armor stands should drop
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Override
|
||||
public void kill(ServerLevel level) {
|
||||
- this.remove(Entity.RemovalReason.KILLED);
|
||||
+ // CraftBukkit start - pass DamageSource for kill
|
||||
+ this.kill(level, null);
|
||||
+ }
|
||||
+
|
||||
+ public void kill(ServerLevel level, @Nullable DamageSource damageSource) {
|
||||
+ // Paper start - make cancellable
|
||||
+ this.kill(damageSource, true);
|
||||
+ }
|
||||
+ public void kill(@Nullable DamageSource damageSource, boolean callEvent) {
|
||||
+ if (callEvent) {
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event
|
||||
+ if (event.isCancelled()) return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
|
||||
+ // CraftBukkit end
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
}
|
||||
|
||||
@@ -653,31 +_,37 @@
|
||||
public void setHeadPose(Rotations headPose) {
|
||||
this.headPose = headPose;
|
||||
this.entityData.set(DATA_HEAD_POSE, headPose);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setBodyPose(Rotations bodyPose) {
|
||||
this.bodyPose = bodyPose;
|
||||
this.entityData.set(DATA_BODY_POSE, bodyPose);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftArmPose(Rotations leftArmPose) {
|
||||
this.leftArmPose = leftArmPose;
|
||||
this.entityData.set(DATA_LEFT_ARM_POSE, leftArmPose);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightArmPose(Rotations rightArmPose) {
|
||||
this.rightArmPose = rightArmPose;
|
||||
this.entityData.set(DATA_RIGHT_ARM_POSE, rightArmPose);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftLegPose(Rotations leftLegPose) {
|
||||
this.leftLegPose = leftLegPose;
|
||||
this.entityData.set(DATA_LEFT_LEG_POSE, leftLegPose);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightLegPose(Rotations rightLegPose) {
|
||||
this.rightLegPose = rightLegPose;
|
||||
this.entityData.set(DATA_RIGHT_LEG_POSE, rightLegPose);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public Rotations getHeadPose() {
|
||||
@@ -809,4 +_,13 @@
|
||||
public boolean canBeSeenByAnyone() {
|
||||
return !this.isInvisible() && !this.isMarker();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void move(net.minecraft.world.entity.MoverType type, Vec3 movement) {
|
||||
+ if (this.canMove) {
|
||||
+ super.move(type, movement);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
--- a/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
|
||||
+++ b/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
|
||||
@@ -20,7 +_,7 @@
|
||||
|
||||
public abstract class BlockAttachedEntity extends Entity {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
- private int checkInterval;
|
||||
+ private int checkInterval; { this.checkInterval = this.getId() % this.level().spigotConfig.hangingTickFrequency; } // Paper - Perf: offset item frame ticking
|
||||
protected BlockPos pos;
|
||||
|
||||
protected BlockAttachedEntity(EntityType<? extends BlockAttachedEntity> entityType, Level level) {
|
||||
@@ -38,10 +_,29 @@
|
||||
public void tick() {
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
this.checkBelowWorld();
|
||||
- if (this.checkInterval++ == 100) {
|
||||
+ if (this.checkInterval++ == this.level().spigotConfig.hangingTickFrequency) { // Spigot
|
||||
this.checkInterval = 0;
|
||||
if (!this.isRemoved() && !this.survives()) {
|
||||
- this.discard();
|
||||
+ // this.discard();
|
||||
+ // CraftBukkit start - fire break events
|
||||
+ net.minecraft.world.level.block.state.BlockState material = this.level().getBlockState(this.blockPosition());
|
||||
+ org.bukkit.event.hanging.HangingBreakEvent.RemoveCause cause;
|
||||
+
|
||||
+ if (!material.isAir()) {
|
||||
+ // TODO: This feels insufficient to catch 100% of suffocation cases
|
||||
+ cause = org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.OBSTRUCTION;
|
||||
+ } else {
|
||||
+ cause = org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.PHYSICS;
|
||||
+ }
|
||||
+
|
||||
+ org.bukkit.event.hanging.HangingBreakEvent event = new org.bukkit.event.hanging.HangingBreakEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), cause);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (this.isRemoved() || event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
this.dropItem(serverLevel, null);
|
||||
}
|
||||
}
|
||||
@@ -74,6 +_,21 @@
|
||||
return false;
|
||||
} else {
|
||||
if (!this.isRemoved()) {
|
||||
+ // CraftBukkit start - fire break events
|
||||
+ Entity damager = (!damageSource.isDirect() && damageSource.getEntity() != null) ? damageSource.getEntity() : damageSource.getDirectEntity(); // Paper - fix DamageSource API
|
||||
+ org.bukkit.event.hanging.HangingBreakEvent event;
|
||||
+ if (damager != null) {
|
||||
+ event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), damager.getBukkitEntity(), damageSource.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION) ? org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.EXPLOSION : org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.ENTITY);
|
||||
+ } else {
|
||||
+ event = new org.bukkit.event.hanging.HangingBreakEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), damageSource.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION) ? org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.EXPLOSION : org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.DEFAULT);
|
||||
+ }
|
||||
+
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (this.isRemoved() || event.isCancelled()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.kill(level);
|
||||
this.markHurt();
|
||||
this.dropItem(level, damageSource.getEntity());
|
||||
@@ -91,18 +_,36 @@
|
||||
@Override
|
||||
public void move(MoverType type, Vec3 movement) {
|
||||
if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && movement.lengthSqr() > 0.0) {
|
||||
- this.kill(serverLevel);
|
||||
- this.dropItem(serverLevel, null);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void push(double x, double y, double z) {
|
||||
- if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && x * x + y * y + z * z > 0.0) {
|
||||
- this.kill(serverLevel);
|
||||
- this.dropItem(serverLevel, null);
|
||||
- }
|
||||
- }
|
||||
+ // CraftBukkit start - fire break events
|
||||
+ // TODO - Does this need its own cause? Seems to only be triggered by pistons
|
||||
+ org.bukkit.event.hanging.HangingBreakEvent event = new org.bukkit.event.hanging.HangingBreakEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.PHYSICS);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (this.isRemoved() || event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.kill(serverLevel);
|
||||
+ this.dropItem(serverLevel, null);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void push(double x, double y, double z, @Nullable Entity pushingEntity) { // Paper - override correct overload
|
||||
+ if (false && this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && x * x + y * y + z * z > 0.0) { // CraftBukkit - not needed
|
||||
+ this.kill(serverLevel);
|
||||
+ this.dropItem(serverLevel, null);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start - selectively save tile position
|
||||
+ @Override
|
||||
+ public void addAdditionalSaveData(CompoundTag nbt, boolean includeAll) {
|
||||
+ if (includeAll) {
|
||||
+ this.addAdditionalSaveData(nbt);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag tag) {
|
|
@ -0,0 +1,127 @@
|
|||
--- a/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
+++ b/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
@@ -49,6 +_,7 @@
|
||||
private static final float HEIGHT = 0.75F;
|
||||
public float dropChance = 1.0F;
|
||||
public boolean fixed;
|
||||
+ public @Nullable MapId cachedMapId; // Paper - Perf: Cache map ids on item frames
|
||||
|
||||
public ItemFrame(EntityType<? extends ItemFrame> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@@ -88,6 +_,12 @@
|
||||
|
||||
@Override
|
||||
protected AABB calculateBoundingBox(BlockPos pos, Direction direction) {
|
||||
+ // CraftBukkit start - break out BB calc into own method
|
||||
+ return ItemFrame.calculateBoundingBoxStatic(pos, direction);
|
||||
+ }
|
||||
+
|
||||
+ public static AABB calculateBoundingBoxStatic(BlockPos pos, Direction direction) {
|
||||
+ // CraftBukkit end
|
||||
float f = 0.46875F;
|
||||
Vec3 vec3 = Vec3.atCenterOf(pos).relative(direction, -0.46875);
|
||||
Direction.Axis axis = direction.getAxis();
|
||||
@@ -118,9 +_,9 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double x, double y, double z) {
|
||||
+ public void push(double x, double y, double z, @Nullable Entity pushingEntity) { // Paper - add push source entity param
|
||||
if (!this.fixed) {
|
||||
- super.push(x, y, z);
|
||||
+ super.push(x, y, z, pushingEntity); // Paper - add push source entity param
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +_,18 @@
|
||||
if (this.isInvulnerableToBase(damageSource)) {
|
||||
return false;
|
||||
} else if (this.shouldDamageDropItem(damageSource)) {
|
||||
+ // CraftBukkit start - fire EntityDamageEvent
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount, false) || this.isRemoved()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - Add PlayerItemFrameChangeEvent
|
||||
+ if (damageSource.getEntity() instanceof Player player) {
|
||||
+ var event = new io.papermc.paper.event.player.PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), io.papermc.paper.event.player.PlayerItemFrameChangeEvent.ItemFrameChangeAction.REMOVE);
|
||||
+ if (!event.callEvent()) return true; // return true here because you aren't cancelling the damage, just the change
|
||||
+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerItemFrameChangeEvent
|
||||
this.dropItem(level, damageSource.getEntity(), false);
|
||||
this.gameEvent(GameEvent.BLOCK_CHANGE, damageSource.getEntity());
|
||||
this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F);
|
||||
@@ -234,6 +_,14 @@
|
||||
return this.getEntityData().get(DATA_ITEM);
|
||||
}
|
||||
|
||||
+ // Paper start - Fix MC-123848 (spawn item frame drops above block)
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ServerLevel serverLevel, ItemStack stack) {
|
||||
+ return this.spawnAtLocation(serverLevel, stack, this.getDirection() == Direction.DOWN ? -0.6F : 0.0F);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
public MapId getFramedMapId(ItemStack stack) {
|
||||
return stack.get(DataComponents.MAP_ID);
|
||||
@@ -248,13 +_,19 @@
|
||||
}
|
||||
|
||||
public void setItem(ItemStack stack, boolean updateNeighbours) {
|
||||
+ // CraftBukkit start
|
||||
+ this.setItem(stack, updateNeighbours, true);
|
||||
+ }
|
||||
+
|
||||
+ public void setItem(ItemStack stack, boolean updateNeighbours, boolean playSound) {
|
||||
+ // CraftBukkit end
|
||||
if (!stack.isEmpty()) {
|
||||
stack = stack.copyWithCount(1);
|
||||
}
|
||||
|
||||
this.onItemChanged(stack);
|
||||
this.getEntityData().set(DATA_ITEM, stack);
|
||||
- if (!stack.isEmpty()) {
|
||||
+ if (!stack.isEmpty() && updateNeighbours && playSound) { // CraftBukkit // Paper - only play sound when update flag is set
|
||||
this.playSound(this.getAddItemSound(), 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
@@ -280,6 +_,7 @@
|
||||
}
|
||||
|
||||
private void onItemChanged(ItemStack item) {
|
||||
+ this.cachedMapId = item.getComponents().get(net.minecraft.core.component.DataComponents.MAP_ID); // Paper - Perf: Cache map ids on item frames
|
||||
if (!item.isEmpty() && item.getFrame() != this) {
|
||||
item.setEntityRepresentation(this);
|
||||
}
|
||||
@@ -359,7 +_,13 @@
|
||||
if (savedData != null && savedData.isTrackedCountOverLimit(256)) {
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
- this.setItem(itemInHand);
|
||||
+ // Paper start - Add PlayerItemFrameChangeEvent
|
||||
+ io.papermc.paper.event.player.PlayerItemFrameChangeEvent event = new io.papermc.paper.event.player.PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), itemInHand.asBukkitCopy(), io.papermc.paper.event.player.PlayerItemFrameChangeEvent.ItemFrameChangeAction.PLACE);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()));
|
||||
+ // Paper end - Add PlayerItemFrameChangeEvent
|
||||
this.gameEvent(GameEvent.BLOCK_CHANGE, player);
|
||||
itemInHand.consume(1, player);
|
||||
return InteractionResult.SUCCESS;
|
||||
@@ -368,6 +_,13 @@
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
} else {
|
||||
+ // Paper start - Add PlayerItemFrameChangeEvent
|
||||
+ io.papermc.paper.event.player.PlayerItemFrameChangeEvent event = new io.papermc.paper.event.player.PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), io.papermc.paper.event.player.PlayerItemFrameChangeEvent.ItemFrameChangeAction.ROTATE);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false, false);
|
||||
+ // Paper end - Add PlayerItemFrameChangeEvent
|
||||
this.playSound(this.getRotateItemSound(), 1.0F, 1.0F);
|
||||
this.setRotation(this.getRotation() + 1);
|
||||
this.gameEvent(GameEvent.BLOCK_CHANGE, player);
|
|
@ -1,35 +1,13 @@
|
|||
--- a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
|
||||
+++ b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
|
||||
@@ -8,9 +8,11 @@
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
|
||||
+import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerEntity;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
@@ -26,6 +28,9 @@
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class LeashFenceKnotEntity extends BlockAttachedEntity {
|
||||
|
||||
@@ -85,6 +90,15 @@
|
||||
Leashable leashable = (Leashable) iterator.next();
|
||||
@@ -81,6 +_,15 @@
|
||||
|
||||
for (Leashable leashable : list) {
|
||||
if (leashable.getLeashHolder() == player) {
|
||||
+ // CraftBukkit start
|
||||
+ if (leashable instanceof Entity leashed) {
|
||||
+ if (CraftEventFactory.callPlayerLeashEntityEvent(leashed, this, player, hand).isCancelled()) {
|
||||
+ ((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket(leashed, leashable.getLeashHolder()));
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, this, player, hand).isCancelled()) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(leashed, leashable.getLeashHolder()));
|
||||
+ flag = true; // Also set true when the event is cancelled otherwise it tries to unleash the entities
|
||||
+ continue;
|
||||
+ }
|
||||
|
@ -38,9 +16,9 @@
|
|||
leashable.setLeashedTo(this, true);
|
||||
flag = true;
|
||||
}
|
||||
@@ -93,18 +107,43 @@
|
||||
boolean flag1 = false;
|
||||
@@ -88,14 +_,39 @@
|
||||
|
||||
boolean flag1 = false;
|
||||
if (!flag) {
|
||||
- this.discard();
|
||||
- if (player.getAbilities().instabuild) {
|
||||
|
@ -49,18 +27,14 @@
|
|||
+ boolean die = true;
|
||||
+ // CraftBukkit end
|
||||
+ if (true || player.getAbilities().instabuild) { // CraftBukkit - Process for non-creative as well
|
||||
Iterator iterator1 = list.iterator();
|
||||
|
||||
while (iterator1.hasNext()) {
|
||||
Leashable leashable1 = (Leashable) iterator1.next();
|
||||
|
||||
for (Leashable leashable1 : list) {
|
||||
if (leashable1.isLeashed() && leashable1.getLeashHolder() == this) {
|
||||
- leashable1.removeLeash();
|
||||
+ // CraftBukkit start
|
||||
+ boolean dropLeash = !player.hasInfiniteMaterials();
|
||||
+ if (leashable1 instanceof Entity leashed) {
|
||||
+ // Paper start - Expand EntityUnleashEvent
|
||||
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(leashed, player, hand, dropLeash);
|
||||
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(leashed, player, hand, dropLeash);
|
||||
+ dropLeash = event.isDropLeash();
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Paper end - Expand EntityUnleashEvent
|
||||
|
@ -79,7 +53,7 @@
|
|||
}
|
||||
+ // CraftBukkit start
|
||||
+ if (die) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
--- a/net/minecraft/world/entity/decoration/Painting.java
|
||||
+++ b/net/minecraft/world/entity/decoration/Painting.java
|
||||
@@ -129,21 +_,31 @@
|
||||
|
||||
@Override
|
||||
protected AABB calculateBoundingBox(BlockPos pos, Direction direction) {
|
||||
+ // CraftBukkit start
|
||||
+ PaintingVariant variant = (PaintingVariant) this.getVariant().value();
|
||||
+ return Painting.calculateBoundingBoxStatic(pos, direction, variant.width(), variant.height());
|
||||
+ }
|
||||
+
|
||||
+ public static AABB calculateBoundingBoxStatic(BlockPos pos, Direction direction, int width, int height) {
|
||||
+ // CraftBukkit end
|
||||
float f = 0.46875F;
|
||||
Vec3 vec3 = Vec3.atCenterOf(pos).relative(direction, -0.46875);
|
||||
- PaintingVariant paintingVariant = this.getVariant().value();
|
||||
- double d = this.offsetForPaintingSize(paintingVariant.width());
|
||||
- double d1 = this.offsetForPaintingSize(paintingVariant.height());
|
||||
+ // CraftBukkit start
|
||||
+ double d = Painting.offsetForPaintingSize(width);
|
||||
+ double d1 = Painting.offsetForPaintingSize(height);
|
||||
+ // CraftBukkit end
|
||||
Direction counterClockWise = direction.getCounterClockWise();
|
||||
Vec3 vec31 = vec3.relative(counterClockWise, d).relative(Direction.UP, d1);
|
||||
Direction.Axis axis = direction.getAxis();
|
||||
- double d2 = axis == Direction.Axis.X ? 0.0625 : paintingVariant.width();
|
||||
- double d3 = paintingVariant.height();
|
||||
- double d4 = axis == Direction.Axis.Z ? 0.0625 : paintingVariant.width();
|
||||
+ // CraftBukkit start
|
||||
+ double d2 = axis == Direction.Axis.X ? 0.0625 : width;
|
||||
+ double d3 = height;
|
||||
+ double d4 = axis == Direction.Axis.Z ? 0.0625 : width;
|
||||
+ // CraftBukkit end
|
||||
return AABB.ofSize(vec31, d2, d3, d4);
|
||||
}
|
||||
|
||||
- private double offsetForPaintingSize(int size) {
|
||||
+ private static double offsetForPaintingSize(int size) { // CraftBukkit - static
|
||||
return size % 2 == 0 ? 0.5 : 0.0;
|
||||
}
|
||||
|
|
@ -1,513 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -25,7 +25,6 @@
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
-import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
@@ -33,7 +32,6 @@
|
||||
import net.minecraft.world.entity.Pose;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
-import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
@@ -47,6 +45,14 @@
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.inventory.EquipmentSlot;
|
||||
+import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public class ArmorStand extends LivingEntity {
|
||||
|
||||
@@ -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);
|
||||
+ 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);
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - SPIGOT-3607, SPIGOT-3637
|
||||
@Override
|
||||
+ public float getBukkitYaw() {
|
||||
+ return this.getYRot();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ @Override
|
||||
public void refreshDimensions() {
|
||||
double d0 = this.getX();
|
||||
double d1 = this.getY();
|
||||
@@ -165,7 +186,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public ItemStack getItemBySlot(EquipmentSlot slot) {
|
||||
+ public ItemStack getItemBySlot(net.minecraft.world.entity.EquipmentSlot slot) {
|
||||
switch (slot.getType()) {
|
||||
case HAND:
|
||||
return (ItemStack) this.handItems.get(slot.getIndex());
|
||||
@@ -177,21 +198,29 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean canUseSlot(EquipmentSlot slot) {
|
||||
- return slot != EquipmentSlot.BODY && !this.isDisabled(slot);
|
||||
+ public boolean canUseSlot(net.minecraft.world.entity.EquipmentSlot slot) {
|
||||
+ return slot != net.minecraft.world.entity.EquipmentSlot.BODY && !this.isDisabled(slot);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItemSlot(net.minecraft.world.entity.EquipmentSlot slot, ItemStack stack) {
|
||||
+ // CraftBukkit start
|
||||
+ this.setItemSlot(slot, stack, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
|
||||
- this.verifyEquippedItem(stack);
|
||||
- switch (slot.getType()) {
|
||||
+ public void setItemSlot(net.minecraft.world.entity.EquipmentSlot enumitemslot, ItemStack itemstack, boolean silent) {
|
||||
+ // CraftBukkit end
|
||||
+ this.verifyEquippedItem(itemstack);
|
||||
+ switch (enumitemslot.getType()) {
|
||||
case HAND:
|
||||
- this.onEquipItem(slot, (ItemStack) this.handItems.set(slot.getIndex(), stack), stack);
|
||||
+ this.onEquipItem(enumitemslot, (ItemStack) this.handItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit
|
||||
break;
|
||||
case HUMANOID_ARMOR:
|
||||
- this.onEquipItem(slot, (ItemStack) this.armorItems.set(slot.getIndex(), stack), stack);
|
||||
+ 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
|
||||
}
|
||||
|
||||
@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);
|
||||
@@ -318,7 +354,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean isPushable() {
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -327,6 +363,7 @@
|
||||
|
||||
@Override
|
||||
protected void pushEntities() {
|
||||
+ if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper - Option to prevent armor stands from doing entity lookups
|
||||
List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
@@ -341,7 +378,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public InteractionResult interactAt(Player player, Vec3 hitPos, InteractionHand hand) {
|
||||
+ public InteractionResult interactAt(net.minecraft.world.entity.player.Player player, Vec3 hitPos, InteractionHand hand) {
|
||||
ItemStack itemstack = player.getItemInHand(hand);
|
||||
|
||||
if (!this.isMarker() && !itemstack.is(Items.NAME_TAG)) {
|
||||
@@ -350,11 +387,11 @@
|
||||
} else if (player.level().isClientSide) {
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
} else {
|
||||
- EquipmentSlot enumitemslot = this.getEquipmentSlotForItem(itemstack);
|
||||
+ net.minecraft.world.entity.EquipmentSlot enumitemslot = this.getEquipmentSlotForItem(itemstack);
|
||||
|
||||
if (itemstack.isEmpty()) {
|
||||
- EquipmentSlot enumitemslot1 = this.getClickedSlot(hitPos);
|
||||
- EquipmentSlot enumitemslot2 = this.isDisabled(enumitemslot1) ? enumitemslot : enumitemslot1;
|
||||
+ net.minecraft.world.entity.EquipmentSlot enumitemslot1 = this.getClickedSlot(hitPos);
|
||||
+ net.minecraft.world.entity.EquipmentSlot enumitemslot2 = this.isDisabled(enumitemslot1) ? enumitemslot : enumitemslot1;
|
||||
|
||||
if (this.hasItemInSlot(enumitemslot2) && this.swapItem(player, enumitemslot2, itemstack, hand)) {
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
@@ -364,7 +401,7 @@
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
- if (enumitemslot.getType() == EquipmentSlot.Type.HAND && !this.showArms()) {
|
||||
+ if (enumitemslot.getType() == net.minecraft.world.entity.EquipmentSlot.Type.HAND && !this.showArms()) {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
@@ -380,39 +417,57 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private EquipmentSlot getClickedSlot(Vec3 hitPos) {
|
||||
- EquipmentSlot enumitemslot = EquipmentSlot.MAINHAND;
|
||||
+ private net.minecraft.world.entity.EquipmentSlot getClickedSlot(Vec3 hitPos) {
|
||||
+ net.minecraft.world.entity.EquipmentSlot enumitemslot = net.minecraft.world.entity.EquipmentSlot.MAINHAND;
|
||||
boolean flag = this.isSmall();
|
||||
double d0 = hitPos.y / (double) (this.getScale() * this.getAgeScale());
|
||||
- EquipmentSlot enumitemslot1 = EquipmentSlot.FEET;
|
||||
+ net.minecraft.world.entity.EquipmentSlot enumitemslot1 = net.minecraft.world.entity.EquipmentSlot.FEET;
|
||||
|
||||
if (d0 >= 0.1D && d0 < 0.1D + (flag ? 0.8D : 0.45D) && this.hasItemInSlot(enumitemslot1)) {
|
||||
- enumitemslot = EquipmentSlot.FEET;
|
||||
- } else if (d0 >= 0.9D + (flag ? 0.3D : 0.0D) && d0 < 0.9D + (flag ? 1.0D : 0.7D) && this.hasItemInSlot(EquipmentSlot.CHEST)) {
|
||||
- enumitemslot = EquipmentSlot.CHEST;
|
||||
- } else if (d0 >= 0.4D && d0 < 0.4D + (flag ? 1.0D : 0.8D) && this.hasItemInSlot(EquipmentSlot.LEGS)) {
|
||||
- enumitemslot = EquipmentSlot.LEGS;
|
||||
- } else if (d0 >= 1.6D && this.hasItemInSlot(EquipmentSlot.HEAD)) {
|
||||
- enumitemslot = EquipmentSlot.HEAD;
|
||||
- } else if (!this.hasItemInSlot(EquipmentSlot.MAINHAND) && this.hasItemInSlot(EquipmentSlot.OFFHAND)) {
|
||||
- enumitemslot = EquipmentSlot.OFFHAND;
|
||||
+ enumitemslot = net.minecraft.world.entity.EquipmentSlot.FEET;
|
||||
+ } else if (d0 >= 0.9D + (flag ? 0.3D : 0.0D) && d0 < 0.9D + (flag ? 1.0D : 0.7D) && this.hasItemInSlot(net.minecraft.world.entity.EquipmentSlot.CHEST)) {
|
||||
+ enumitemslot = net.minecraft.world.entity.EquipmentSlot.CHEST;
|
||||
+ } else if (d0 >= 0.4D && d0 < 0.4D + (flag ? 1.0D : 0.8D) && this.hasItemInSlot(net.minecraft.world.entity.EquipmentSlot.LEGS)) {
|
||||
+ enumitemslot = net.minecraft.world.entity.EquipmentSlot.LEGS;
|
||||
+ } else if (d0 >= 1.6D && this.hasItemInSlot(net.minecraft.world.entity.EquipmentSlot.HEAD)) {
|
||||
+ enumitemslot = net.minecraft.world.entity.EquipmentSlot.HEAD;
|
||||
+ } else if (!this.hasItemInSlot(net.minecraft.world.entity.EquipmentSlot.MAINHAND) && this.hasItemInSlot(net.minecraft.world.entity.EquipmentSlot.OFFHAND)) {
|
||||
+ enumitemslot = net.minecraft.world.entity.EquipmentSlot.OFFHAND;
|
||||
}
|
||||
|
||||
return enumitemslot;
|
||||
}
|
||||
|
||||
- public boolean isDisabled(EquipmentSlot slot) {
|
||||
- return (this.disabledSlots & 1 << slot.getFilterBit(0)) != 0 || slot.getType() == EquipmentSlot.Type.HAND && !this.showArms();
|
||||
+ public boolean isDisabled(net.minecraft.world.entity.EquipmentSlot slot) {
|
||||
+ return (this.disabledSlots & 1 << slot.getFilterBit(0)) != 0 || slot.getType() == net.minecraft.world.entity.EquipmentSlot.Type.HAND && !this.showArms();
|
||||
}
|
||||
|
||||
- private boolean swapItem(Player player, EquipmentSlot slot, ItemStack stack, InteractionHand hand) {
|
||||
+ private boolean swapItem(net.minecraft.world.entity.player.Player player, net.minecraft.world.entity.EquipmentSlot slot, ItemStack stack, InteractionHand hand) {
|
||||
ItemStack itemstack1 = this.getItemBySlot(slot);
|
||||
|
||||
if (!itemstack1.isEmpty() && (this.disabledSlots & 1 << slot.getFilterBit(8)) != 0) {
|
||||
return false;
|
||||
} else if (itemstack1.isEmpty() && (this.disabledSlots & 1 << slot.getFilterBit(16)) != 0) {
|
||||
return false;
|
||||
- } else if (player.hasInfiniteMaterials() && itemstack1.isEmpty() && !stack.isEmpty()) {
|
||||
+ // CraftBukkit start
|
||||
+ } else {
|
||||
+ org.bukkit.inventory.ItemStack armorStandItem = CraftItemStack.asCraftMirror(itemstack1);
|
||||
+ org.bukkit.inventory.ItemStack playerHeldItem = CraftItemStack.asCraftMirror(stack);
|
||||
+
|
||||
+ Player player1 = (Player) player.getBukkitEntity();
|
||||
+ org.bukkit.entity.ArmorStand self = (org.bukkit.entity.ArmorStand) this.getBukkitEntity();
|
||||
+
|
||||
+ EquipmentSlot slot1 = CraftEquipmentSlot.getSlot(slot);
|
||||
+ EquipmentSlot hand1 = CraftEquipmentSlot.getHand(hand);
|
||||
+ PlayerArmorStandManipulateEvent armorStandManipulateEvent = new PlayerArmorStandManipulateEvent(player1, self, playerHeldItem, armorStandItem, slot1, hand1);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(armorStandManipulateEvent);
|
||||
+
|
||||
+ if (armorStandManipulateEvent.isCancelled()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (player.hasInfiniteMaterials() && itemstack1.isEmpty() && !stack.isEmpty()) {
|
||||
+ // CraftBukkit end
|
||||
this.setItemSlot(slot, stack.copyWithCount(1));
|
||||
return true;
|
||||
} else if (!stack.isEmpty() && stack.getCount() > 1) {
|
||||
@@ -427,6 +482,7 @@
|
||||
player.setItemInHand(hand, itemstack1);
|
||||
return true;
|
||||
}
|
||||
+ } // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -436,12 +492,24 @@
|
||||
} else if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && source.getEntity() instanceof Mob) {
|
||||
return false;
|
||||
} else if (source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
|
||||
- this.kill(world);
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ this.kill(world, source); // CraftBukkit
|
||||
+ // CraftBukkit end
|
||||
return false;
|
||||
- } else if (!this.isInvulnerableTo(world, source) && !this.invisible && !this.isMarker()) {
|
||||
+ } else if (!this.isInvulnerableTo(world, source) && (true || !this.invisible) && !this.isMarker()) { // CraftBukkit
|
||||
+ // CraftBukkit start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount, true, this.invisible)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (source.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
- this.brokenByAnything(world, source);
|
||||
- this.kill(world);
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(world, source);
|
||||
+ if (!event.isCancelled()) this.kill(source, false); // CraftBukkit
|
||||
+ // Paper end
|
||||
return false;
|
||||
} else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
|
||||
if (this.isOnFire()) {
|
||||
@@ -463,8 +531,8 @@
|
||||
} else {
|
||||
Entity entity = source.getEntity();
|
||||
|
||||
- if (entity instanceof Player) {
|
||||
- Player entityhuman = (Player) entity;
|
||||
+ if (entity instanceof net.minecraft.world.entity.player.Player) {
|
||||
+ net.minecraft.world.entity.player.Player entityhuman = (net.minecraft.world.entity.player.Player) entity;
|
||||
|
||||
if (!entityhuman.getAbilities().mayBuild) {
|
||||
return false;
|
||||
@@ -474,7 +542,7 @@
|
||||
if (source.isCreativePlayer()) {
|
||||
this.playBrokenSound();
|
||||
this.showBreakingParticles();
|
||||
- this.kill(world);
|
||||
+ this.kill(world, source); // CraftBukkit
|
||||
return true;
|
||||
} else {
|
||||
long i = world.getGameTime();
|
||||
@@ -484,9 +552,9 @@
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity());
|
||||
this.lastHit = i;
|
||||
} else {
|
||||
- this.brokenByPlayer(world, source);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(world, source); // Paper
|
||||
this.showBreakingParticles();
|
||||
- this.kill(world);
|
||||
+ if (!event.isCancelled()) this.kill(source, false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...)
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -536,7 +604,10 @@
|
||||
f1 -= amount;
|
||||
if (f1 <= 0.5F) {
|
||||
this.brokenByAnything(world, damageSource);
|
||||
- this.kill(world);
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(world, damageSource);
|
||||
+ if (!event.isCancelled()) this.kill(damageSource, false); // CraftBukkit
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.setHealth(f1);
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
|
||||
@@ -544,17 +615,17 @@
|
||||
|
||||
}
|
||||
|
||||
- private void brokenByPlayer(ServerLevel world, DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(ServerLevel world, DamageSource damageSource) { // Paper
|
||||
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
|
||||
|
||||
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
|
||||
- Block.popResource(this.level(), this.blockPosition(), itemstack);
|
||||
- this.brokenByAnything(world, damageSource);
|
||||
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
|
||||
+ return this.brokenByAnything(world, damageSource); // Paper
|
||||
}
|
||||
|
||||
- private void brokenByAnything(ServerLevel world, DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByAnything(ServerLevel world, DamageSource damageSource) { // Paper
|
||||
this.playBrokenSound();
|
||||
- this.dropAllDeathLoot(world, damageSource);
|
||||
+ // this.dropAllDeathLoot(worldserver, damagesource); // CraftBukkit - moved down
|
||||
|
||||
ItemStack itemstack;
|
||||
int i;
|
||||
@@ -562,7 +633,7 @@
|
||||
for (i = 0; i < this.handItems.size(); ++i) {
|
||||
itemstack = (ItemStack) this.handItems.get(i);
|
||||
if (!itemstack.isEmpty()) {
|
||||
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
|
||||
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
this.handItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
@@ -570,15 +641,16 @@
|
||||
for (i = 0; i < this.armorItems.size(); ++i) {
|
||||
itemstack = (ItemStack) this.armorItems.get(i);
|
||||
if (!itemstack.isEmpty()) {
|
||||
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
|
||||
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||
this.armorItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
+ return this.dropAllDeathLoot(world, damageSource); // CraftBukkit - moved from above // Paper
|
||||
|
||||
}
|
||||
|
||||
private void playBrokenSound() {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.ARMOR_STAND_BREAK, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ this.level().playSound((net.minecraft.world.entity.player.Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.ARMOR_STAND_BREAK, this.getSoundSource(), 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -609,7 +681,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 +758,31 @@
|
||||
return this.isSmall();
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
@Override
|
||||
+ public boolean shouldDropExperience() {
|
||||
+ return true; // MC-157395, SPIGOT-5193 even baby (small) armor stands should drop
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ @Override
|
||||
public void kill(ServerLevel world) {
|
||||
- this.remove(Entity.RemovalReason.KILLED);
|
||||
+ // CraftBukkit start - pass DamageSource for kill
|
||||
+ this.kill(world, null);
|
||||
+ }
|
||||
+
|
||||
+ public void kill(ServerLevel worldserver, DamageSource damageSource) {
|
||||
+ // Paper start - make cancellable
|
||||
+ this.kill(damageSource, true);
|
||||
+ }
|
||||
+ public void kill(DamageSource damageSource, boolean callEvent) {
|
||||
+ if (callEvent) {
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event
|
||||
+ if (event.isCancelled()) return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
|
||||
+ // CraftBukkit end
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
}
|
||||
|
||||
@@ -730,31 +846,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 +910,7 @@
|
||||
|
||||
@Override
|
||||
public boolean skipAttackInteraction(Entity attacker) {
|
||||
- return attacker instanceof Player && !this.level().mayInteract((Player) attacker, this.blockPosition());
|
||||
+ return attacker instanceof net.minecraft.world.entity.player.Player && !this.level().mayInteract((net.minecraft.world.entity.player.Player) attacker, this.blockPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -882,4 +1004,13 @@
|
||||
public boolean canBeSeenByAnyone() {
|
||||
return !this.isInvisible() && !this.isMarker();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void move(net.minecraft.world.entity.MoverType type, Vec3 movement) {
|
||||
+ if (this.canMove) {
|
||||
+ super.move(type, movement);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
|
||||
+++ b/net/minecraft/world/entity/decoration/BlockAttachedEntity.java
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import javax.annotation.Nullable;
|
||||
-import net.minecraft.core.BlockPos;
|
||||
-import net.minecraft.nbt.CompoundTag;
|
||||
-import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
@@ -15,13 +12,24 @@
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.slf4j.Logger;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+// CraftBukkit start
|
||||
+import net.minecraft.tags.DamageTypeTags;
|
||||
+import org.bukkit.entity.Hanging;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
+import org.bukkit.event.hanging.HangingBreakEvent;
|
||||
+// CraftBukkit end
|
||||
|
||||
public abstract class BlockAttachedEntity extends Entity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
- private int checkInterval;
|
||||
+ private int checkInterval; { this.checkInterval = this.getId() % this.level().spigotConfig.hangingTickFrequency; } // Paper - Perf: offset item frame ticking
|
||||
protected BlockPos pos;
|
||||
|
||||
protected BlockAttachedEntity(EntityType<? extends BlockAttachedEntity> type, Level world) {
|
||||
@@ -41,10 +49,28 @@
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
this.checkBelowWorld();
|
||||
- if (this.checkInterval++ == 100) {
|
||||
+ if (this.checkInterval++ == this.level().spigotConfig.hangingTickFrequency) { // Spigot
|
||||
this.checkInterval = 0;
|
||||
if (!this.isRemoved() && !this.survives()) {
|
||||
- this.discard();
|
||||
+ // CraftBukkit start - fire break events
|
||||
+ BlockState material = this.level().getBlockState(this.blockPosition());
|
||||
+ HangingBreakEvent.RemoveCause cause;
|
||||
+
|
||||
+ if (!material.isAir()) {
|
||||
+ // TODO: This feels insufficient to catch 100% of suffocation cases
|
||||
+ cause = HangingBreakEvent.RemoveCause.OBSTRUCTION;
|
||||
+ } else {
|
||||
+ cause = HangingBreakEvent.RemoveCause.PHYSICS;
|
||||
+ }
|
||||
+
|
||||
+ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), cause);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (this.isRemoved() || event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
this.dropItem(worldserver, (Entity) null);
|
||||
}
|
||||
}
|
||||
@@ -81,6 +107,22 @@
|
||||
return false;
|
||||
} else {
|
||||
if (!this.isRemoved()) {
|
||||
+ // CraftBukkit start - fire break events
|
||||
+ Entity damager = (!source.isDirect() && source.getEntity() != null) ? source.getEntity() : source.getDirectEntity(); // Paper - fix DamageSource API
|
||||
+ HangingBreakEvent event;
|
||||
+ if (damager != null) {
|
||||
+ event = new HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damager.getBukkitEntity(), source.is(DamageTypeTags.IS_EXPLOSION) ? HangingBreakEvent.RemoveCause.EXPLOSION : HangingBreakEvent.RemoveCause.ENTITY);
|
||||
+ } else {
|
||||
+ event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), source.is(DamageTypeTags.IS_EXPLOSION) ? HangingBreakEvent.RemoveCause.EXPLOSION : HangingBreakEvent.RemoveCause.DEFAULT);
|
||||
+ }
|
||||
+
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (this.isRemoved() || event.isCancelled()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
this.kill(world);
|
||||
this.markHurt();
|
||||
this.dropItem(world, source.getEntity());
|
||||
@@ -101,6 +143,16 @@
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
if (!this.isRemoved() && movement.lengthSqr() > 0.0D) {
|
||||
+ // CraftBukkit start - fire break events
|
||||
+ // TODO - Does this need its own cause? Seems to only be triggered by pistons
|
||||
+ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (this.isRemoved() || event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
this.kill(worldserver);
|
||||
this.dropItem(worldserver, (Entity) null);
|
||||
}
|
||||
@@ -109,11 +161,11 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double deltaX, double deltaY, double deltaZ) {
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - override correct overload
|
||||
Level world = this.level();
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
- if (!this.isRemoved() && deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ > 0.0D) {
|
||||
+ if (false && !this.isRemoved() && deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ > 0.0D) { // CraftBukkit - not needed
|
||||
this.kill(worldserver);
|
||||
this.dropItem(worldserver, (Entity) null);
|
||||
}
|
||||
@@ -121,7 +173,16 @@
|
||||
|
||||
}
|
||||
|
||||
+ // CraftBukkit start - selectively save tile position
|
||||
@Override
|
||||
+ public void addAdditionalSaveData(CompoundTag nbttagcompound, boolean includeAll) {
|
||||
+ if (includeAll) {
|
||||
+ this.addAdditionalSaveData(nbttagcompound);
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ @Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
BlockPos blockposition = this.getPos();
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
+++ b/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.minecraft.world.entity.decoration;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
+import io.papermc.paper.event.player.PlayerItemFrameChangeEvent; // Paper - Add PlayerItemFrameChangeEvent
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
@@ -50,6 +51,7 @@
|
||||
private static final float HEIGHT = 0.75F;
|
||||
public float dropChance;
|
||||
public boolean fixed;
|
||||
+ public @Nullable MapId cachedMapId; // Paper - Perf: Cache map ids on item frames
|
||||
|
||||
public ItemFrame(EntityType<? extends ItemFrame> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -91,9 +93,15 @@
|
||||
|
||||
@Override
|
||||
protected AABB calculateBoundingBox(BlockPos pos, Direction side) {
|
||||
+ // CraftBukkit start - break out BB calc into own method
|
||||
+ return ItemFrame.calculateBoundingBoxStatic(pos, side);
|
||||
+ }
|
||||
+
|
||||
+ public static AABB calculateBoundingBoxStatic(BlockPos blockposition, Direction enumdirection) {
|
||||
+ // CraftBukkit end
|
||||
float f = 0.46875F;
|
||||
- Vec3 vec3d = Vec3.atCenterOf(pos).relative(side, -0.46875D);
|
||||
- Direction.Axis enumdirection_enumaxis = side.getAxis();
|
||||
+ Vec3 vec3d = Vec3.atCenterOf(blockposition).relative(enumdirection, -0.46875D);
|
||||
+ Direction.Axis enumdirection_enumaxis = enumdirection.getAxis();
|
||||
double d0 = enumdirection_enumaxis == Direction.Axis.X ? 0.0625D : 0.75D;
|
||||
double d1 = enumdirection_enumaxis == Direction.Axis.Y ? 0.0625D : 0.75D;
|
||||
double d2 = enumdirection_enumaxis == Direction.Axis.Z ? 0.0625D : 0.75D;
|
||||
@@ -123,9 +131,9 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double deltaX, double deltaY, double deltaZ) {
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @Nullable Entity pushingEntity) { // Paper - add push source entity param
|
||||
if (!this.fixed) {
|
||||
- super.push(deltaX, deltaY, deltaZ);
|
||||
+ super.push(deltaX, deltaY, deltaZ, pushingEntity); // Paper - add push source entity param
|
||||
}
|
||||
|
||||
}
|
||||
@@ -155,6 +163,18 @@
|
||||
if (this.isInvulnerableToBase(source)) {
|
||||
return false;
|
||||
} else if (this.shouldDamageDropItem(source)) {
|
||||
+ // CraftBukkit start - fire EntityDamageEvent
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount, false) || this.isRemoved()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ // Paper start - Add PlayerItemFrameChangeEvent
|
||||
+ if (source.getEntity() instanceof Player player) {
|
||||
+ var event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.REMOVE);
|
||||
+ if (!event.callEvent()) return true; // return true here because you aren't cancelling the damage, just the change
|
||||
+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerItemFrameChangeEvent
|
||||
this.dropItem(world, source.getEntity(), false);
|
||||
this.gameEvent(GameEvent.BLOCK_CHANGE, source.getEntity());
|
||||
this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F);
|
||||
@@ -251,7 +271,15 @@
|
||||
|
||||
public ItemStack getItem() {
|
||||
return (ItemStack) this.getEntityData().get(ItemFrame.DATA_ITEM);
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Fix MC-123848 (spawn item frame drops above block)
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ServerLevel serverLevel, ItemStack stack) {
|
||||
+ return this.spawnAtLocation(serverLevel, stack, this.getDirection() == Direction.DOWN ? -0.6F : 0.0F);
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Nullable
|
||||
public MapId getFramedMapId(ItemStack stack) {
|
||||
@@ -267,17 +295,23 @@
|
||||
}
|
||||
|
||||
public void setItem(ItemStack value, boolean update) {
|
||||
- if (!value.isEmpty()) {
|
||||
- value = value.copyWithCount(1);
|
||||
+ // CraftBukkit start
|
||||
+ this.setItem(value, update, true);
|
||||
+ }
|
||||
+
|
||||
+ public void setItem(ItemStack itemstack, boolean flag, boolean playSound) {
|
||||
+ // CraftBukkit end
|
||||
+ if (!itemstack.isEmpty()) {
|
||||
+ itemstack = itemstack.copyWithCount(1);
|
||||
}
|
||||
|
||||
- this.onItemChanged(value);
|
||||
- this.getEntityData().set(ItemFrame.DATA_ITEM, value);
|
||||
- if (!value.isEmpty()) {
|
||||
+ this.onItemChanged(itemstack);
|
||||
+ this.getEntityData().set(ItemFrame.DATA_ITEM, itemstack);
|
||||
+ if (!itemstack.isEmpty() && flag && playSound) { // CraftBukkit // Paper - only play sound when update flag is set
|
||||
this.playSound(this.getAddItemSound(), 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
- if (update && this.pos != null) {
|
||||
+ if (flag && this.pos != null) {
|
||||
this.level().updateNeighbourForOutputSignal(this.pos, Blocks.AIR);
|
||||
}
|
||||
|
||||
@@ -301,6 +335,7 @@
|
||||
}
|
||||
|
||||
private void onItemChanged(ItemStack stack) {
|
||||
+ this.cachedMapId = stack.getComponents().get(net.minecraft.core.component.DataComponents.MAP_ID); // Paper - Perf: Cache map ids on item frames
|
||||
if (!stack.isEmpty() && stack.getFrame() != this) {
|
||||
stack.setEntityRepresentation(this);
|
||||
}
|
||||
@@ -386,7 +421,13 @@
|
||||
if (worldmap != null && worldmap.isTrackedCountOverLimit(256)) {
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
- this.setItem(itemstack);
|
||||
+ // Paper start - Add PlayerItemFrameChangeEvent
|
||||
+ PlayerItemFrameChangeEvent event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), itemstack.asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.PLACE);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()));
|
||||
+ // Paper end - Add PlayerItemFrameChangeEvent
|
||||
this.gameEvent(GameEvent.BLOCK_CHANGE, player);
|
||||
itemstack.consume(1, player);
|
||||
return InteractionResult.SUCCESS;
|
||||
@@ -395,6 +436,13 @@
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
} else {
|
||||
+ // Paper start - Add PlayerItemFrameChangeEvent
|
||||
+ PlayerItemFrameChangeEvent event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.ROTATE);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false, false);
|
||||
+ // Paper end - Add PlayerItemFrameChangeEvent
|
||||
this.playSound(this.getRotateItemSound(), 1.0F, 1.0F);
|
||||
this.setRotation(this.getRotation() + 1);
|
||||
this.gameEvent(GameEvent.BLOCK_CHANGE, player);
|
|
@ -1,54 +0,0 @@
|
|||
--- a/net/minecraft/world/entity/decoration/Painting.java
|
||||
+++ b/net/minecraft/world/entity/decoration/Painting.java
|
||||
@@ -72,7 +72,7 @@
|
||||
public static Optional<Painting> create(Level world, BlockPos pos, Direction facing) {
|
||||
Painting entitypainting = new Painting(world, pos);
|
||||
List<Holder<PaintingVariant>> list = new ArrayList();
|
||||
- Iterable iterable = world.registryAccess().lookupOrThrow(Registries.PAINTING_VARIANT).getTagOrEmpty(PaintingVariantTags.PLACEABLE);
|
||||
+ Iterable<Holder<PaintingVariant>> iterable = world.registryAccess().lookupOrThrow(Registries.PAINTING_VARIANT).getTagOrEmpty(PaintingVariantTags.PLACEABLE); // CraftBukkit - decompile error
|
||||
|
||||
Objects.requireNonNull(list);
|
||||
iterable.forEach(list::add);
|
||||
@@ -138,22 +138,32 @@
|
||||
|
||||
@Override
|
||||
protected AABB calculateBoundingBox(BlockPos pos, Direction side) {
|
||||
- float f = 0.46875F;
|
||||
- Vec3 vec3d = Vec3.atCenterOf(pos).relative(side, -0.46875D);
|
||||
+ // CraftBukkit start
|
||||
PaintingVariant paintingvariant = (PaintingVariant) this.getVariant().value();
|
||||
- double d0 = this.offsetForPaintingSize(paintingvariant.width());
|
||||
- double d1 = this.offsetForPaintingSize(paintingvariant.height());
|
||||
- Direction enumdirection1 = side.getCounterClockWise();
|
||||
+ return Painting.calculateBoundingBoxStatic(pos, side, paintingvariant.width(), paintingvariant.height());
|
||||
+ }
|
||||
+
|
||||
+ public static AABB calculateBoundingBoxStatic(BlockPos blockposition, Direction enumdirection, int width, int height) {
|
||||
+ // CraftBukkit end
|
||||
+ float f = 0.46875F;
|
||||
+ Vec3 vec3d = Vec3.atCenterOf(blockposition).relative(enumdirection, -0.46875D);
|
||||
+ // CraftBukkit start
|
||||
+ double d0 = Painting.offsetForPaintingSize(width);
|
||||
+ double d1 = Painting.offsetForPaintingSize(height);
|
||||
+ // CraftBukkit end
|
||||
+ Direction enumdirection1 = enumdirection.getCounterClockWise();
|
||||
Vec3 vec3d1 = vec3d.relative(enumdirection1, d0).relative(Direction.UP, d1);
|
||||
- Direction.Axis enumdirection_enumaxis = side.getAxis();
|
||||
- double d2 = enumdirection_enumaxis == Direction.Axis.X ? 0.0625D : (double) paintingvariant.width();
|
||||
- double d3 = (double) paintingvariant.height();
|
||||
- double d4 = enumdirection_enumaxis == Direction.Axis.Z ? 0.0625D : (double) paintingvariant.width();
|
||||
+ Direction.Axis enumdirection_enumaxis = enumdirection.getAxis();
|
||||
+ // CraftBukkit start
|
||||
+ double d2 = enumdirection_enumaxis == Direction.Axis.X ? 0.0625D : (double) width;
|
||||
+ double d3 = (double) height;
|
||||
+ double d4 = enumdirection_enumaxis == Direction.Axis.Z ? 0.0625D : (double) width;
|
||||
+ // CraftBukkit end
|
||||
|
||||
return AABB.ofSize(vec3d1, d2, d3, d4);
|
||||
}
|
||||
|
||||
- private double offsetForPaintingSize(int length) {
|
||||
+ private static double offsetForPaintingSize(int length) { // CraftBukkit - static
|
||||
return length % 2 == 0 ? 0.5D : 0.0D;
|
||||
}
|
||||
|
Loading…
Reference in a new issue