Skip to content

Commit 2527b3e

Browse files
committed
Cushion is not hanging... we need events for that
1 parent af24f42 commit 2527b3e

5 files changed

Lines changed: 153 additions & 34 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.papermc.paper.event.entity;
2+
3+
import org.bukkit.damage.DamageSource;
4+
import org.bukkit.entity.Entity;
5+
import org.jetbrains.annotations.ApiStatus;
6+
import org.jspecify.annotations.NullMarked;
7+
8+
@NullMarked
9+
public class EntityBreakByEntityEvent extends EntityBreakEvent {
10+
11+
private final Entity remover;
12+
private final DamageSource damageSource;
13+
14+
@ApiStatus.Internal
15+
public EntityBreakByEntityEvent(final Entity entity, final Entity remover, final DamageSource damageSource) {
16+
this(entity, remover, damageSource, RemoveCause.ENTITY);
17+
}
18+
19+
public EntityBreakByEntityEvent(final Entity entity, final Entity remover, final DamageSource damageSource, final RemoveCause cause) {
20+
super(entity, cause);
21+
this.remover = remover;
22+
this.damageSource = damageSource;
23+
}
24+
25+
/**
26+
* Gets the entity that removed the entity.
27+
*
28+
* @return the entity that removed the entity
29+
*/
30+
public Entity getRemover() {
31+
return this.remover;
32+
}
33+
34+
/**
35+
* Gets the {@link DamageSource} that caused the entity to be removed.
36+
*
37+
* @return the damage source
38+
*/
39+
public DamageSource getDamageSource() {
40+
return this.damageSource;
41+
}
42+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package io.papermc.paper.event.entity;
2+
3+
import org.bukkit.entity.Entity;
4+
import org.bukkit.event.Cancellable;
5+
import org.bukkit.event.HandlerList;
6+
import org.bukkit.event.entity.EntityEvent;
7+
import org.jetbrains.annotations.ApiStatus;
8+
import org.jspecify.annotations.NullMarked;
9+
10+
@NullMarked
11+
public class EntityBreakEvent extends EntityEvent implements Cancellable {
12+
13+
private static final HandlerList HANDLER_LIST = new HandlerList();
14+
15+
private final RemoveCause cause;
16+
private boolean cancelled;
17+
18+
@ApiStatus.Internal
19+
public EntityBreakEvent(final Entity entity, final RemoveCause cause) {
20+
super(entity);
21+
this.cause = cause;
22+
}
23+
24+
/**
25+
* Gets the cause for the entity's removal
26+
*
27+
* @return the RemoveCause for the entity's removal
28+
*/
29+
public RemoveCause getCause() {
30+
return this.cause;
31+
}
32+
33+
@Override
34+
public boolean isCancelled() {
35+
return this.cancelled;
36+
}
37+
38+
@Override
39+
public void setCancelled(final boolean cancel) {
40+
this.cancelled = cancel;
41+
}
42+
43+
@Override
44+
public HandlerList getHandlers() {
45+
return HANDLER_LIST;
46+
}
47+
48+
public static HandlerList getHandlerList() {
49+
return HANDLER_LIST;
50+
}
51+
52+
/**
53+
* An enum to specify the cause of the removal
54+
*/
55+
public enum RemoveCause {
56+
/**
57+
* Removed by an entity
58+
*/
59+
ENTITY,
60+
/**
61+
* Removed by an explosion
62+
*/
63+
EXPLOSION,
64+
/**
65+
* Removed by placing a block on it
66+
*/
67+
OBSTRUCTION,
68+
/**
69+
* Removed by destroying the block behind it, etc
70+
*/
71+
PHYSICS,
72+
/**
73+
* Removed by an uncategorised cause
74+
*/
75+
DEFAULT,
76+
}
77+
}

‎paper-api/src/main/java/org/bukkit/entity/Cushion.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
* Represents a Cushion entity
88
*/
99
@NullMarked
10-
public interface Cushion extends Colorable, Hanging {
10+
public interface Cushion extends Colorable, Entity {
1111

1212
}

‎paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch‎

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
protected BlockPos pos;
1010

1111
protected BlockAttachedEntity(final EntityType<? extends BlockAttachedEntity> type, final Level level) {
12-
@@ -42,11 +_,27 @@
12+
@@ -42,11 +_,32 @@
1313
public void tick() {
1414
if (this.level() instanceof ServerLevel level) {
1515
this.checkBelowWorld();
@@ -20,41 +20,58 @@
2020
if (!this.isRemoved() && !this.survives()) {
2121
- this.discard();
2222
+ // CraftBukkit start - fire break events
23-
+ final org.bukkit.event.hanging.HangingBreakEvent.RemoveCause cause;
24-
+ if (!this.level().getBlockState(this.blockPosition()).isAir()) {
25-
+ // TODO: This feels insufficient to catch 100% of suffocation cases
26-
+ cause = org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.OBSTRUCTION;
23+
+ boolean cancelled;
24+
+ final io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause cause;
25+
+ if (!this.level().getBlockState(this.blockPosition()).isSuffocating(this.level(), this.blockPosition())) {
26+
+ cause = io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause.OBSTRUCTION;
2727
+ } else {
28-
+ cause = org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.PHYSICS;
28+
+ cause = io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause.PHYSICS;
2929
+ }
3030
+
31-
+ org.bukkit.event.hanging.HangingBreakEvent event = new org.bukkit.event.hanging.HangingBreakEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), cause);
32-
+ this.level().getCraftServer().getPluginManager().callEvent(event);
31+
+ final io.papermc.paper.event.entity.EntityBreakEvent event = new io.papermc.paper.event.entity.EntityBreakEvent(this.getBukkitEntity(), cause);
32+
+ cancelled = !event.callEvent();
33+
+ if (this.getBukkitEntity() instanceof org.bukkit.entity.Hanging hanging) {
34+
+ final org.bukkit.event.hanging.HangingBreakEvent bukkitEvent = new org.bukkit.event.hanging.HangingBreakEvent(hanging, org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.valueOf(cause.toString()));
35+
+ bukkitEvent.setCancelled(cancelled);
36+
+ cancelled = !bukkitEvent.callEvent();
37+
+ }
3338
+
34-
+ if (this.isRemoved() || event.isCancelled()) {
39+
+ if (this.isRemoved() || cancelled) {
3540
+ return;
3641
+ }
3742
+ // CraftBukkit end
3843
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
3944
this.dropItem(level, null);
4045
}
4146
}
42-
@@ -99,6 +_,21 @@
47+
@@ -99,6 +_,33 @@
4348
}
4449

4550
if (!this.isRemoved()) {
4651
+ // CraftBukkit start - fire break events
47-
+ Entity damager = source.getDirectEntity();
48-
+ final org.bukkit.event.hanging.HangingBreakEvent event;
52+
+ boolean cancelled;
53+
+ final Entity damager = source.getDirectEntity();
54+
+ final org.bukkit.damage.DamageSource craftDamageSource = new org.bukkit.craftbukkit.damage.CraftDamageSource(source);
55+
+ final io.papermc.paper.event.entity.EntityBreakEvent event;
4956
+ if (damager != null) {
50-
+ event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), damager.getBukkitEntity(), new org.bukkit.craftbukkit.damage.CraftDamageSource(source), source.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION) ? org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.EXPLOSION : org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.ENTITY);
57+
+ event = new io.papermc.paper.event.entity.EntityBreakByEntityEvent(this.getBukkitEntity(), damager.getBukkitEntity(), craftDamageSource, source.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION) ? io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause.EXPLOSION : io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause.ENTITY);
5158
+ } else {
52-
+ event = new org.bukkit.event.hanging.HangingBreakEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), source.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION) ? org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.EXPLOSION : org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.DEFAULT);
59+
+ event = new io.papermc.paper.event.entity.EntityBreakEvent(this.getBukkitEntity(), source.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION) ? io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause.EXPLOSION : io.papermc.paper.event.entity.EntityBreakEvent.RemoveCause.DEFAULT);
5360
+ }
61+
+ cancelled = !event.callEvent();
5462
+
55-
+ event.callEvent();
63+
+ if (this.getBukkitEntity() instanceof org.bukkit.entity.Hanging hanging) {
64+
+ final org.bukkit.event.hanging.HangingBreakEvent bukkitEvent;
65+
+ if (damager != null) {
66+
+ bukkitEvent = new org.bukkit.event.hanging.HangingBreakByEntityEvent(hanging, damager.getBukkitEntity(), craftDamageSource, org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.valueOf(event.getCause().toString()));
67+
+ } else {
68+
+ bukkitEvent = new org.bukkit.event.hanging.HangingBreakEvent(hanging, org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.valueOf(event.getCause().toString()));
69+
+ }
70+
+ bukkitEvent.setCancelled(cancelled);
71+
+ cancelled = !bukkitEvent.callEvent();
72+
+ }
5673
+
57-
+ if (this.isRemoved() || event.isCancelled()) {
74+
+ if (this.isRemoved() || cancelled) {
5875
+ return true;
5976
+ }
6077
+ // CraftBukkit end

‎paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCushion.java‎

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.bukkit.craftbukkit.entity;
22

33
import org.bukkit.DyeColor;
4-
import org.bukkit.block.BlockFace;
54
import org.bukkit.craftbukkit.CraftServer;
65
import org.bukkit.entity.Cushion;
76
import org.jspecify.annotations.NullMarked;
@@ -27,20 +26,4 @@ public DyeColor getColor() {
2726
public void setColor(DyeColor color) {
2827
this.getHandle().setColor(net.minecraft.world.item.DyeColor.byId(color.getWoolData()));
2928
}
30-
31-
@Override
32-
public boolean setFacingDirection(final BlockFace face, final boolean force) {
33-
return false;
34-
}
35-
36-
@Override
37-
public BlockFace getAttachedFace() {
38-
// cushion has no facing direction, so we return self
39-
return BlockFace.SELF;
40-
}
41-
42-
@Override
43-
public void setFacingDirection(final BlockFace face) {
44-
// cushion has no facing direction
45-
}
4629
}

0 commit comments

Comments
 (0)