net.minecraft.world.entity.decoration
This commit is contained in:
@@ -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);
|
||||
@@ -0,0 +1,61 @@
|
||||
--- a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
|
||||
+++ b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
|
||||
@@ -81,6 +_,15 @@
|
||||
|
||||
for (Leashable leashable : list) {
|
||||
if (leashable.getLeashHolder() == player) {
|
||||
+ // CraftBukkit start
|
||||
+ if (leashable instanceof Entity leashed) {
|
||||
+ 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;
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
leashable.setLeashedTo(this, true);
|
||||
flag = true;
|
||||
}
|
||||
@@ -88,14 +_,39 @@
|
||||
|
||||
boolean flag1 = false;
|
||||
if (!flag) {
|
||||
- this.discard();
|
||||
- if (player.getAbilities().instabuild) {
|
||||
+ // CraftBukkit start - Move below
|
||||
+ // this.discard();
|
||||
+ boolean die = true;
|
||||
+ // CraftBukkit end
|
||||
+ if (true || player.getAbilities().instabuild) { // CraftBukkit - Process for non-creative as well
|
||||
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 = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(leashed, player, hand, dropLeash);
|
||||
+ dropLeash = event.isDropLeash();
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Paper end - Expand EntityUnleashEvent
|
||||
+ die = false;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!dropLeash) { // Paper - Expand EntityUnleashEvent
|
||||
+ leashable1.removeLeash();
|
||||
+ } else {
|
||||
+ leashable1.dropLeash();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
+ // CraftBukkit start
|
||||
+ if (die) {
|
||||
+ 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user