Overhaul SoundEvent

This commit is contained in:
Lexi
2022-04-21 21:04:03 -04:00
parent affcc4ee25
commit 1ebb4c1e79
4 changed files with 451 additions and 226 deletions

View File

@@ -6,10 +6,10 @@ Subject: [PATCH] Add SoundEvent
diff --git a/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java b/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..74109b772f3d38fdd58721ec1e491ff0f8f4f122
index 0000000000000000000000000000000000000000..19c9f7af91402d5f966915ebc80d76ab9ac92872
--- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java
@@ -0,0 +1,52 @@
@@ -0,0 +1,67 @@
+package me.lexikiq.event.sound;
+
+import org.apache.commons.lang.Validate;
@@ -18,9 +18,15 @@ index 0000000000000000000000000000000000000000..74109b772f3d38fdd58721ec1e491ff0
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Called when an entity sound is sent to a player.
+ * Cancelling this event will prevent the packet from sending.
@@ -28,46 +34,55 @@ index 0000000000000000000000000000000000000000..74109b772f3d38fdd58721ec1e491ff0
+ * This type of sound represents one that will follow the {@link #getOrigin() originating} entity.
+ */
+public class EntitySoundEvent extends NamedSoundEvent {
+ private @NotNull Entity origin;
+ private @NotNull Entity origin;
+
+ public EntitySoundEvent(@Nullable HumanEntity except, @NotNull Entity origin, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ super(except, sound, category, volume, pitch);
+ Validate.notNull(origin, "origin cannot be null");
+ this.origin = origin;
+ }
+ @Deprecated
+ public EntitySoundEvent(@Nullable HumanEntity except, @NotNull Entity origin, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ this(except, origin, sound, category, volume, pitch, null, null);
+ }
+
+ /**
+ * Gets the entity that the sound is originating from.
+ public EntitySoundEvent(@Nullable HumanEntity except, @NotNull Entity origin, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, @Nullable Function<SoundEvent, Double> distanceFunction, @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ super(except, sound, category, volume, pitch, distanceFunction, recipientsFunction);
+ this.origin = Objects.requireNonNull(origin, "origin cannot be null");
+ }
+
+ /**
+ * Gets the entity that the sound is originating from.
+ *
+ * @return originating entity
+ */
+ public @NotNull Entity getOrigin() {
+ return origin;
+ }
+ * @return originating entity
+ */
+ public @NotNull Entity getOrigin() {
+ return origin;
+ }
+
+ /**
+ * Sets the entity that the sound will originate from.
+ /**
+ * Sets the entity that the sound will originate from.
+ *
+ * @param origin originating entity
+ */
+ public void setOrigin(@NotNull Entity origin) {
+ Validate.notNull(origin, "origin cannot be null");
+ if (!this.origin.getWorld().equals(origin.getWorld()))
+ throw new IllegalArgumentException("Entity must be in same world as originating location");
+ this.origin = origin;
+ }
+ * @param origin originating entity
+ */
+ public void setOrigin(@NotNull Entity origin) {
+ Validate.notNull(origin, "origin cannot be null");
+ if (!this.origin.getWorld().equals(origin.getWorld()))
+ throw new IllegalArgumentException("Entity must be in same world as originating location");
+ this.origin = origin;
+ }
+
+ @Override
+ public @NotNull World getWorld() {
+ return origin.getWorld();
+ }
+
+ @Override
+ public @NotNull Vector getPosition() {
+ return origin.getLocation().toVector();
+ }
+}
diff --git a/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0dce9bcdd
index 0000000000000000000000000000000000000000..9d7f3656c55a0bb7a8258a0418954563f8730551
--- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java
@@ -0,0 +1,126 @@
@@ -0,0 +1,139 @@
+package me.lexikiq.event.sound;
+
+import me.lexikiq.HasLocation;
@@ -78,10 +93,16 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0
+import org.bukkit.SoundCategory;
+import org.bukkit.World;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
@@ -89,57 +110,80 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0
+ * {@link Location}. Cancelling this event will prevent the packet from sending.
+ */
+public class LocationCustomSoundEvent extends SoundEvent implements Keyed, HasLocation {
+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList();
+ private @NotNull
+ final World world;
+ private @NotNull World world;
+ private @NotNull Vector vector;
+ private @NotNull NamespacedKey key;
+ private boolean cancelled;
+
+ public LocationCustomSoundEvent(@Nullable HumanEntity except, @NotNull World world, @NotNull Vector vector, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ super(except, category, volume, pitch);
+ Validate.notNull(world, "world cannot be null");
+ Validate.notNull(vector, "vector cannot be null");
+ Validate.notNull(key, "key cannot be null");
+ this.world = world;
+ this.vector = vector;
+ this.key = key;
+ @Deprecated
+ public LocationCustomSoundEvent(@Nullable HumanEntity except,
+ @NotNull World world,
+ @NotNull Vector vector,
+ @NotNull NamespacedKey key,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch) {
+ this(except, world, vector, key, category, volume, pitch, null, null);
+ }
+
+ public LocationCustomSoundEvent(@Nullable HumanEntity except, @NotNull Location location, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ this(except, checkNotNull(location, "location").getWorld(), location.toVector(), key, category, volume, pitch);
+ @Deprecated
+ public LocationCustomSoundEvent(@Nullable HumanEntity except,
+ @NotNull Location location,
+ @NotNull NamespacedKey key,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch) {
+ this(except, location, key, category, volume, pitch, null, null);
+ }
+
+ public LocationCustomSoundEvent(@NotNull HumanEntity except, @NotNull Vector vector, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(except, "except"), except.getWorld(), vector, key, category, volume, pitch);
+ public LocationCustomSoundEvent(@Nullable HumanEntity except,
+ @NotNull World world,
+ @NotNull Vector vector,
+ @NotNull NamespacedKey key,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch,
+ @Nullable Function<SoundEvent, Double> distanceFunction,
+ @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ super(except, category, volume, pitch, distanceFunction, recipientsFunction);
+ this.world = Objects.requireNonNull(world, "world cannot be null");
+ this.vector = Objects.requireNonNull(vector, "vector cannot be null");
+ this.key = Objects.requireNonNull(key, "key cannot be null");
+ }
+
+ public LocationCustomSoundEvent(@NotNull HumanEntity except, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(except, "except"), except.getLocation().toVector(), key, category, volume, pitch);
+ public LocationCustomSoundEvent(@Nullable HumanEntity except,
+ @NotNull Location location,
+ @NotNull NamespacedKey key,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch,
+ @Nullable Function<SoundEvent, Double> distanceFunction,
+ @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ this(except, checkNotNull(location, "location").getWorld(), location.toVector(), key, category, volume, pitch, distanceFunction, recipientsFunction);
+ }
+
+ @NotNull
+ public static org.bukkit.event.HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ /**
+ * Gets the position of the sound.
+ *
+ * @return position in the world
+ */
+ public @NotNull Vector getVector() {
+ @Override
+ public @NotNull Vector getPosition() {
+ return vector;
+ }
+
+ /**
+ * Sets the position of the sound.
+ *
+ * @param vector position in the world
+ * @param position position in the world
+ */
+ public void setPosition(@NotNull Vector position) {
+ this.vector = Objects.requireNonNull(position, "position cannot be null");
+ }
+
+ /**
+ * Sets the position of the sound.
+ *
+ * @param vector position in the world
+ * @deprecated use {@link #setPosition(Vector)} instead
+ */
+ @Deprecated
+ public void setVector(@NotNull Vector vector) {
+ Validate.notNull(vector, "vector cannot be null");
+ this.vector = vector;
+ setPosition(vector);
+ }
+
+ /**
@@ -159,8 +203,7 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0
+ * @param key asset key
+ */
+ public void setKey(@NotNull NamespacedKey key) {
+ Validate.notNull(key, "key cannot be null");
+ this.key = key;
+ this.key = Objects.requireNonNull(key, "key cannot be null");
+ }
+
+ @Override
@@ -169,96 +212,116 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0
+ }
+
+ /**
+ * Gets the location of the sound being played.
+ * Sets the world in which the sound is played.
+ * <p>
+ * This may not have an effect if the {@link #getRecipientsFunction()} has been modified.
+ *
+ * @return copy of sound location
+ * @see #getVector()
+ * @see #setVector(Vector)
+ * @param world world to play the sound in
+ */
+ public @NotNull Location getLocation() {
+ return new Location(world, vector.getX(), vector.getY(), vector.getZ());
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ @Override
+ public @NotNull org.bukkit.event.HandlerList getHandlers() {
+ return handlers;
+ public void setWorld(@NotNull World world) {
+ this.world = Objects.requireNonNull(world, "world cannot be null");
+ }
+}
diff --git a/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..013472f40edbfea49785d48cc0f7ad7c5b69fe58
index 0000000000000000000000000000000000000000..7f42c904362107c55cc5877eab1b513bcdf34571
--- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java
@@ -0,0 +1,77 @@
@@ -0,0 +1,112 @@
+package me.lexikiq.event.sound;
+
+import me.lexikiq.HasLocation;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
+import org.bukkit.Sound;
+import org.bukkit.SoundCategory;
+import org.bukkit.World;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Called when a sound available in {@link Sound} is sent to a {@link Location}.
+ * Cancelling this event will prevent the packet from sending.
+ */
+public class LocationNamedSoundEvent extends NamedSoundEvent implements HasLocation {
+ private @NotNull
+ final World world;
+ private @NotNull World world;
+ private @NotNull Vector vector;
+
+ public LocationNamedSoundEvent(@Nullable HumanEntity receiver, @NotNull World world, @NotNull Vector vector, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ super(receiver, sound, category, volume, pitch);
+ this.world = checkNotNull(world, "world");
+ this.vector = checkNotNull(vector, "vector");
+ @Deprecated
+ public LocationNamedSoundEvent(@Nullable HumanEntity except,
+ @NotNull World world,
+ @NotNull Vector vector,
+ @NotNull Sound sound,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch) {
+ this(except, world, vector, sound, category, volume, pitch, null, null);
+ }
+
+ public LocationNamedSoundEvent(@Nullable HumanEntity receiver, @NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ this(receiver, checkNotNull(location, "location").getWorld(), location.toVector(), sound, category, volume, pitch);
+ @Deprecated
+ public LocationNamedSoundEvent(@Nullable HumanEntity except,
+ @NotNull Location location,
+ @NotNull Sound sound,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch) {
+ this(except, location, sound, category, volume, pitch, null, null);
+ }
+
+ public LocationNamedSoundEvent(@NotNull HumanEntity receiver, @NotNull Vector vector, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(receiver, "receiver"), receiver.getWorld(), vector, sound, category, volume, pitch);
+ public LocationNamedSoundEvent(@Nullable HumanEntity except,
+ @NotNull World world,
+ @NotNull Vector vector,
+ @NotNull Sound sound,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch,
+ @Nullable Function<SoundEvent, Double> distanceFunction,
+ @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ super(except, sound, category, volume, pitch, distanceFunction, recipientsFunction);
+ this.world = Objects.requireNonNull(world, "world cannot be null");
+ this.vector = Objects.requireNonNull(vector, "vector cannot be null");
+ }
+
+ public LocationNamedSoundEvent(@NotNull HumanEntity receiver, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(receiver, "receiver"), receiver.getLocation().toVector(), sound, category, volume, pitch);
+ public LocationNamedSoundEvent(@Nullable HumanEntity except,
+ @NotNull Location location,
+ @NotNull Sound sound,
+ @NotNull SoundCategory category,
+ float volume,
+ float pitch,
+ @Nullable Function<SoundEvent, Double> distanceFunction,
+ @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ this(except, Objects.requireNonNull(location, "location cannot be null").getWorld(), location.toVector(), sound, category, volume, pitch, distanceFunction, recipientsFunction);
+ }
+
+ /**
+ * Gets the position of the sound.
+ *
+ * @return position in the world
+ */
+ public @NotNull Vector getVector() {
+ @Override
+ public @NotNull Vector getPosition() {
+ return vector;
+ }
+
+ /**
+ * Sets the position of the sound.
+ *
+ * @param vector position in the world
+ * @param position position in the world
+ */
+ public void setPosition(@NotNull Vector position) {
+ this.vector = Objects.requireNonNull(position, "position cannot be null");
+ }
+
+ /**
+ * Sets the position of the sound.
+ *
+ * @param vector position in the world
+ * @deprecated use {@link #setPosition(Vector)} instead
+ */
+ @Deprecated
+ public void setVector(@NotNull Vector vector) {
+ Validate.notNull(vector, "vector cannot be null");
+ this.vector = vector;
+ setPosition(vector);
+ }
+
+ @Override
@@ -267,53 +330,58 @@ index 0000000000000000000000000000000000000000..013472f40edbfea49785d48cc0f7ad7c
+ }
+
+ /**
+ * Gets the location of the sound being played.
+ * Sets the world in which the sound is played.
+ * <p>
+ * This may not have an effect if the {@link #getRecipientsFunction()} has been modified.
+ *
+ * @return copy of sound location
+ * @see #getVector()
+ * @see #setVector(Vector)
+ * @param world world to play the sound in
+ */
+ public @NotNull Location getLocation() {
+ return new Location(world, vector.getX(), vector.getY(), vector.getZ());
+ public void setWorld(@NotNull World world) {
+ this.world = Objects.requireNonNull(world, "world cannot be null");
+ }
+}
diff --git a/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..9256d75f5bb9ed8f42a7ff0613433bb1b7e37769
index 0000000000000000000000000000000000000000..3ca767cfeb7fc0982830e49cde6bb0e87075c3f9
--- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java
@@ -0,0 +1,65 @@
@@ -0,0 +1,54 @@
+package me.lexikiq.event.sound;
+
+import org.apache.commons.lang.Validate;
+import org.bukkit.Sound;
+import org.bukkit.SoundCategory;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Called when a sound available in {@link Sound} is sent to a player.
+ * Cancelling this event will prevent the packet from sending.
+ */
+public abstract class NamedSoundEvent extends SoundEvent {
+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList();
+ private @NotNull Sound sound;
+ private boolean cancelled;
+
+ public NamedSoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+
+ @Deprecated
+ protected NamedSoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ super(except, category, volume, pitch);
+ Validate.notNull(sound, "sound cannot be null");
+ this.sound = sound;
+ this.sound = Objects.requireNonNull(sound, "sound cannot be null");
+ }
+
+ public NamedSoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, @Nullable Function<SoundEvent, Double> distanceFunction, @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ super(except, category, volume, pitch, distanceFunction, recipientsFunction);
+ this.sound = Objects.requireNonNull(sound, "sound cannot be null");
+ }
+
+ // boilerplate
+
+ @NotNull
+ public static org.bukkit.event.HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ /**
+ * Gets the sound being played.
+ *
@@ -329,60 +397,80 @@ index 0000000000000000000000000000000000000000..9256d75f5bb9ed8f42a7ff0613433bb1
+ * @param sound sound to play
+ */
+ public void setSound(@NotNull Sound sound) {
+ Validate.notNull(sound, "sound cannot be null");
+ this.sound = sound;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ @Override
+ public @NotNull org.bukkit.event.HandlerList getHandlers() {
+ return handlers;
+ this.sound = Objects.requireNonNull(sound, "sound cannot be null");
+ }
+}
diff --git a/src/main/java/me/lexikiq/event/sound/SoundEvent.java b/src/main/java/me/lexikiq/event/sound/SoundEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc94aeae3ec
index 0000000000000000000000000000000000000000..6cc614b9e1b187f43433d13624d74672c97c2174
--- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/SoundEvent.java
@@ -0,0 +1,117 @@
@@ -0,0 +1,313 @@
+package me.lexikiq.event.sound;
+
+import me.lexikiq.OptionalHumanEntity;
+import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
+import org.bukkit.SoundCategory;
+import org.bukkit.World;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Called when a sound is sent to a player.
+ * Cancelling this event will prevent the packet from sending.
+ */
+// TODO 1.18: use sealed class
+public abstract class SoundEvent extends Event implements Cancellable, OptionalHumanEntity {
+ private @Nullable final HumanEntity except;
+
+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList();
+ public static final @NotNull Function<SoundEvent, Double> DEFAULT_DISTANCE_FUNCTION = event -> event.getVolume() > 1.0F ? (double) (16.0F * event.getVolume()) : 16.0D;
+ public static final @NotNull Function<SoundEvent, List<Player>> DEFAULT_RECIPIENTS_FUNCTION = new WrappedRecipientsFunction(event -> {
+ final double distance = event.calculateDistance();
+ return event.getWorld().getPlayers().stream()
+ .filter(player -> {
+ Location pl = player.getLocation();
+ Vector sv = event.getPosition();
+ double x = sv.getX() - pl.getX();
+ double y = sv.getY() - pl.getY();
+ double z = sv.getZ() - pl.getZ();
+ return x * x + y * y + z * z < distance * distance;
+ })
+ .toList();
+ });
+
+ private @Nullable HumanEntity except;
+ private @NotNull Function<@NotNull SoundEvent, @NotNull Double> distanceFunction;
+ private @NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> recipientsFunction;
+ // <end to-do>
+ private @NotNull SoundCategory category;
+ private float volume;
+ private float pitch;
+ private boolean cancelled;
+
+ public SoundEvent(@Nullable HumanEntity except, @NotNull SoundCategory category, float volume, float pitch) {
+ @Deprecated
+ protected SoundEvent(@Nullable HumanEntity except, @NotNull SoundCategory category, float volume, float pitch) {
+ this(except, category, volume, pitch, null, null);
+ }
+
+ protected SoundEvent(@Nullable HumanEntity except, @NotNull SoundCategory category, float volume, float pitch, @Nullable Function<SoundEvent, Double> distanceFunction, @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
+ super(true);
+ Validate.notNull(category, "category cannot be null");
+ this.except = except;
+ this.category = category;
+ this.category = Objects.requireNonNull(category, "category cannot be null");
+ this.volume = volume;
+ this.pitch = pitch;
+ this.distanceFunction = Objects.requireNonNullElse(distanceFunction, DEFAULT_DISTANCE_FUNCTION);
+ this.recipientsFunction = wrapRecipientsFunction(Objects.requireNonNullElse(recipientsFunction, DEFAULT_RECIPIENTS_FUNCTION));
+ }
+
+ /**
@@ -407,6 +495,15 @@ index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc9
+ }
+
+ /**
+ * Sets the player that <b>won't</b> be receiving this sound.
+ *
+ * @param except player excluded from receiving this sound
+ */
+ public void setException(@Nullable HumanEntity except) {
+ this.except = except;
+ }
+
+ /**
+ * Gets the category of sounds this will be played with.
+ *
+ * @return category of sounds
@@ -421,8 +518,7 @@ index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc9
+ * @param category category of sounds
+ */
+ public void setCategory(@NotNull SoundCategory category) {
+ Validate.notNull(category, "category cannot be null");
+ this.category = category;
+ this.category = Objects.requireNonNull(category, "category cannot be null");
+ }
+
+ /**
@@ -464,10 +560,162 @@ index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc9
+ }
+
+ /**
+ * Calculates the distance of the sound.
+ * <p>
+ * The distance value is dynamically calculated using a
+ * {@link Function Function&lt;SoundEvent, Double&gt;}.
+ * In vanilla Minecraft, the default function is {@link #DEFAULT_DISTANCE_FUNCTION}
+ * ({@code event -> event.getVolume() > 1.0F ? (double) (16.0F * event.getVolume()) : 16.0D}).
+ * </p>
+ * This is used by the vanilla implementation of {@link #calculateRecipients()}, though custom
+ * implementations won't always use this method.
+ *
+ * @return calculated distance
+ * @see #getDistanceFunction()
+ * @see #setDistanceFunction(Function)
+ */
+ public double calculateDistance() {
+ return distanceFunction.apply(this);
+ }
+
+ /**
+ * Gets the function that calculates the distance of the sound.
+ *
+ * @return distance function
+ * @see #calculateDistance()
+ * @see #setDistanceFunction(Function)
+ */
+ public @NotNull Function<@NotNull SoundEvent, @NotNull Double> getDistanceFunction() {
+ return distanceFunction;
+ }
+
+ /**
+ * Sets the function that calculates the distance of the sound.
+ *
+ * @param distanceFunction distance function
+ * @see #calculateDistance()
+ * @see #getDistanceFunction()
+ */
+ public void setDistanceFunction(@NotNull Function<@NotNull SoundEvent, @NotNull Double> distanceFunction) {
+ this.distanceFunction = Objects.requireNonNull(distanceFunction, "distanceFunction cannot be null");
+ }
+
+ /**
+ * Determines which players will receive this sound packet.
+ *
+ * @return immutable list of players
+ * @see #getRecipientsFunction()
+ * @see #setRecipientsFunction(Function)
+ */
+ public @NotNull List<Player> calculateRecipients() {
+ return recipientsFunction.apply(this);
+ }
+
+ /**
+ * Gets the function that determines which players will receive the sound packet.
+ *
+ * @return recipients function
+ * @see #calculateRecipients()
+ * @see #setRecipientsFunction(Function)
+ */
+ public @NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> getRecipientsFunction() {
+ return recipientsFunction;
+ }
+
+ /**
+ * Sets the function that determines which players will receive the sound packet.
+ * <p>
+ * This function does not need to query {@link #getException()} as this is done automatically.
+ *
+ * @param recipientsFunction recipients function
+ * @see #calculateRecipients()
+ * @see #getRecipientsFunction()
+ */
+ public void setRecipientsFunction(@NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> recipientsFunction) {
+ this.recipientsFunction = wrapRecipientsFunction(Objects.requireNonNull(recipientsFunction, "recipientsFunction cannot be null"));
+ }
+
+ /**
+ * Gets the world in which the sound is being played.
+ *
+ * @return sound's world
+ */
+ @NotNull
+ public abstract World getWorld();
+
+ /**
+ * Gets the position at which the sound is being played.
+ *
+ * @return sound's position
+ */
+ @NotNull
+ public abstract Vector getPosition();
+
+ /**
+ * Gets the position at which the sound is being played.
+ *
+ * @return sound's position
+ * @deprecated use {@link #getPosition()} instead for clarity
+ */
+ @Deprecated
+ @NotNull
+ public Vector getVector() {
+ return getPosition();
+ }
+
+ /**
+ * Gets the location of the sound being played.
+ *
+ * @return copy of sound location
+ * @see #getPosition()
+ */
+ public @NotNull Location getLocation() {
+ Vector pos = getPosition();
+ return new Location(getWorld(), pos.getX(), pos.getY(), pos.getZ());
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ @NotNull
+ public static org.bukkit.event.HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ @Override
+ public @NotNull org.bukkit.event.HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private record WrappedRecipientsFunction(@NotNull Function<SoundEvent, List<Player>> wrapped) implements Function<SoundEvent, List<Player>> {
+ @Override
+ public List<Player> apply(SoundEvent event) {
+ List<Player> recipients = wrapped.apply(event);
+ HumanEntity except = event.getException();
+ if (except != null) {
+ List<Player> filteredRecipients = new ArrayList<>(recipients.size());
+ for (Player player : recipients) {
+ if (!player.getUniqueId().equals(except.getUniqueId()))
+ filteredRecipients.add(player);
+ }
+ return filteredRecipients;
+ }
+ return recipients;
+ }
+ }
+
+ @NotNull
+ private static Function<SoundEvent, List<Player>> wrapRecipientsFunction(@NotNull Function<SoundEvent, List<Player>> recipientsFunction) {
+ if (recipientsFunction instanceof WrappedRecipientsFunction)
+ return recipientsFunction;
+ else
+ return new WrappedRecipientsFunction(recipientsFunction);
+ }
+}

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Add SoundEvent
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index a002713686e66faf0d18662586a7a236c27ca7d2..757dafc3150e52c5876679d8d121a69d6cd45b4e 100644
index a002713686e66faf0d18662586a7a236c27ca7d2..14fc9abcba864620148dcdab921a5d95f98a9391 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1495,12 +1495,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -13,26 +13,32 @@ index a002713686e66faf0d18662586a7a236c27ca7d2..757dafc3150e52c5876679d8d121a69d
@Override
public void playSound(@Nullable Player except, double x, double y, double z, SoundEvent sound, SoundSource category, float volume, float pitch) {
- this.server.getPlayerList().broadcast(except, x, y, z, volume > 1.0F ? (double) (16.0F * volume) : 16.0D, this.dimension(), new ClientboundSoundPacket(sound, category, x, y, z, volume, pitch));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(except == null ? null : except.getBukkitEntity(), getWorld(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch), this.server, volume > 1.0F ? (double) (16.0F * volume) : 16.0D); // Parchment
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(except == null ? null : except.getBukkitEntity(), getWorld(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch, null, null)); // Parchment
}
@Override
public void playSound(@Nullable Player except, Entity entity, SoundEvent sound, SoundSource category, float volume, float pitch) {
- this.server.getPlayerList().broadcast(except, entity.getX(), entity.getY(), entity.getZ(), volume > 1.0F ? (double) (16.0F * volume) : 16.0D, this.dimension(), new ClientboundSoundEntityPacket(sound, category, entity, volume, pitch));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.EntitySoundEvent(except == null ? null : except.getBukkitEntity(), entity.getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch), this.server, volume > 1.0F ? (double) (16.0F * volume) : 16.0D); // Parchment
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.EntitySoundEvent(except == null ? null : except.getBukkitEntity(), entity.getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch, null, null)); // Parchment
}
@Override
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 78fda0c982810b8b881a87099f355247566e513a..24f59eb2899692302f5c5e39d96d0c5ed224a904 100644
index 78fda0c982810b8b881a87099f355247566e513a..1ec20f19c8d6a606f608e0293eaf5f8f764b3b92 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -2174,7 +2174,7 @@ public class ServerPlayer extends Player {
@@ -2174,7 +2174,13 @@ public class ServerPlayer extends Player {
@Override
public void playNotifySound(SoundEvent event, SoundSource category, float volume, float pitch) {
- this.connection.send(new ClientboundSoundPacket(event, category, this.getX(), this.getY(), this.getZ(), volume, pitch));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(event), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch), this); // Parchment
+ // Parchment start
+ List<org.bukkit.entity.Player> recipients = java.util.Collections.singletonList(getBukkitEntity());
+ org.bukkit.Location location = getBukkitEntity().getLocation();
+ org.bukkit.Sound sound = org.bukkit.craftbukkit.CraftSound.getBukkit(event);
+ org.bukkit.SoundCategory bukkitCategory = org.bukkit.SoundCategory.valueOf(category.name());
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(null, location, sound, bukkitCategory, volume, pitch, $ -> 0d, $ -> recipients));
+ // Parchment end
}
@Override
@@ -50,15 +56,22 @@ index 46e6e68f78d07c04cd2f4d477dca7a06313c20e9..f7d9316645ba94089a867c6348caaf77
}
// Added from changeDimension
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 94e76e295dbd0f3bac4b30a3e7338cd56a971207..4f55f1bd49137b60957a05faad0e0c2a9dec07dc 100644
index 94e76e295dbd0f3bac4b30a3e7338cd56a971207..e951db59902fafa41832f73bab4086b63fe76f46 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1832,7 +1832,7 @@ public abstract class Player extends LivingEntity {
@@ -1832,7 +1832,14 @@ public abstract class Player extends LivingEntity {
private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
fromEntity.level.playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself
if (fromEntity instanceof ServerPlayer) {
- ((ServerPlayer) fromEntity).connection.send(new ClientboundSoundPacket(soundEffect, soundCategory, x, y, z, volume, pitch));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(fromEntity.getBukkitEntity(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(soundEffect), org.bukkit.SoundCategory.valueOf(soundCategory.name()), volume, pitch), (ServerPlayer) fromEntity); // Parchment
+ // Parchment start
+ List<org.bukkit.entity.Player> recipients = java.util.Collections.singletonList(((net.minecraft.server.level.ServerPlayer) fromEntity).getBukkitEntity());
+ org.bukkit.World world = fromEntity.level.getWorld();
+ org.bukkit.util.Vector vector = new org.bukkit.util.Vector(x, y, z);
+ org.bukkit.Sound sound = org.bukkit.craftbukkit.CraftSound.getBukkit(soundEffect);
+ org.bukkit.SoundCategory category = org.bukkit.SoundCategory.valueOf(soundCategory.name());
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(null, world, vector, sound, category, volume, pitch, event -> 0d, event -> recipients));
+ // Parchment end
}
}
// Paper end
@@ -85,10 +98,10 @@ index a79ba23ecf887ecbb6e095140f019ebb6fd0a6f7..5112edc5e68a386e9bb16ac0ec9d998e
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index ea01507f96d81c6fbcfeb65902017bbc332de650..8e8b520ba2c8359bcf846e1977c1793122565d01 100644
index ea01507f96d81c6fbcfeb65902017bbc332de650..b774a27eb4d11cd1bef807193a6df6012dde3794 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1888,4 +1888,77 @@ public class CraftEventFactory {
@@ -1888,4 +1888,41 @@ public class CraftEventFactory {
return event.callEvent();
}
// Paper end
@@ -97,72 +110,36 @@ index ea01507f96d81c6fbcfeb65902017bbc332de650..8e8b520ba2c8359bcf846e1977c17931
+ private static net.minecraft.network.protocol.Packet<net.minecraft.network.protocol.game.ClientGamePacketListener> handleSoundEvent(me.lexikiq.event.sound.SoundEvent _event) {
+ if (!_event.callEvent()) {
+ return null;
+ } else {
+ float volume = _event.getVolume();
+ float pitch = _event.getPitch();
+ net.minecraft.sounds.SoundSource source = net.minecraft.sounds.SoundSource.valueOf(_event.getCategory().name());
+ }
+ float volume = _event.getVolume();
+ float pitch = _event.getPitch();
+ net.minecraft.sounds.SoundSource source = net.minecraft.sounds.SoundSource.valueOf(_event.getCategory().name());
+
+ if (_event instanceof me.lexikiq.event.sound.NamedSoundEvent namedSoundEvent) {
+ net.minecraft.sounds.SoundEvent sound = org.bukkit.craftbukkit.CraftSound.getSoundEffect(namedSoundEvent.getSound());
+ if (_event instanceof me.lexikiq.event.sound.NamedSoundEvent namedSoundEvent) {
+ net.minecraft.sounds.SoundEvent sound = org.bukkit.craftbukkit.CraftSound.getSoundEffect(namedSoundEvent.getSound());
+
+ if (_event instanceof me.lexikiq.event.sound.LocationNamedSoundEvent event) {
+ org.bukkit.util.Vector pos = event.getVector();
+ return new net.minecraft.network.protocol.game.ClientboundSoundPacket(sound, source, pos.getX(), pos.getY(), pos.getZ(), volume, pitch);
+ } else {
+ me.lexikiq.event.sound.EntitySoundEvent event = (me.lexikiq.event.sound.EntitySoundEvent) _event;
+ return new net.minecraft.network.protocol.game.ClientboundSoundEntityPacket(sound, source, ((CraftEntity) event.getOrigin()).getHandle(), volume, pitch);
+ }
+ } else {
+ me.lexikiq.event.sound.LocationCustomSoundEvent event = (me.lexikiq.event.sound.LocationCustomSoundEvent) _event;
+ org.bukkit.util.Vector pos = event.getVector();
+ return new net.minecraft.network.protocol.game.ClientboundCustomSoundPacket(CraftNamespacedKey.toMinecraft(event.getKey()), source, org.bukkit.craftbukkit.util.CraftVector.toNMS(pos), volume, pitch);
+ if (_event instanceof me.lexikiq.event.sound.LocationNamedSoundEvent event) {
+ org.bukkit.util.Vector pos = event.getPosition();
+ return new net.minecraft.network.protocol.game.ClientboundSoundPacket(sound, source, pos.getX(), pos.getY(), pos.getZ(), volume, pitch);
+ } else if (_event instanceof me.lexikiq.event.sound.EntitySoundEvent event) {
+ return new net.minecraft.network.protocol.game.ClientboundSoundEntityPacket(sound, source, ((CraftEntity) event.getOrigin()).getHandle(), volume, pitch);
+ }
+ } else if (_event instanceof me.lexikiq.event.sound.LocationCustomSoundEvent event) {
+ org.bukkit.util.Vector pos = event.getPosition();
+ return new net.minecraft.network.protocol.game.ClientboundCustomSoundPacket(CraftNamespacedKey.toMinecraft(event.getKey()), source, org.bukkit.craftbukkit.util.CraftVector.toNMS(pos), volume, pitch);
+ }
+ throw new IllegalArgumentException("Unknown sound event: " + _event.getClass().getName());
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, java.util.function.Consumer<net.minecraft.network.protocol.Packet<net.minecraft.network.protocol.game.ClientGamePacketListener>> soundPlayer) {
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event) {
+ org.apache.commons.lang3.Validate.notNull(event, "event");
+ org.apache.commons.lang3.Validate.notNull(soundPlayer, "soundPlayer");
+ if (!(event instanceof me.lexikiq.event.sound.LocationNamedSoundEvent || event instanceof me.lexikiq.event.sound.LocationCustomSoundEvent || event instanceof me.lexikiq.event.sound.EntitySoundEvent)) {
+ throw new IllegalArgumentException("Unknown sound event: " + event.getClass().getName());
+ }
+ java.util.concurrent.CompletableFuture.supplyAsync(() -> handleSoundEvent(event), net.minecraft.server.MCUtil.asyncExecutor).thenAcceptAsync(packet -> {
+ java.util.concurrent.CompletableFuture.supplyAsync(() -> handleSoundEvent(event), net.minecraft.server.MCUtil.asyncExecutor).handleAsync((packet, throwable) -> {
+ if (packet != null)
+ soundPlayer.accept(packet);
+ event.calculateRecipients().forEach(recipient -> ((org.bukkit.craftbukkit.entity.CraftPlayer) recipient).getHandle().connection.send(packet));
+ else if (throwable != null)
+ org.slf4j.LoggerFactory.getLogger("SoundEvent").error("Error while handling sound event", throwable);
+ return null;
+ }, net.minecraft.server.MCUtil.asyncExecutor);
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, CraftPlayer sendTo) {
+ playSoundEvent(event, sendTo.getHandle());
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, ServerPlayer sendTo) {
+ playSoundEvent(event, sendTo.connection);
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, net.minecraft.server.network.ServerPlayerConnection sendTo) {
+ playSoundEvent(event, sendTo::send);
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, net.minecraft.server.MinecraftServer server, double radius) {
+ playSoundEvent(event, server.getPlayerList(), radius);
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, net.minecraft.server.players.PlayerList playerList, double radius) {
+ final net.minecraft.world.entity.player.Player player = event.getPlayer() == null ? null : ((org.bukkit.craftbukkit.entity.CraftHumanEntity) event.getPlayer()).getHandle();
+ final net.minecraft.resources.ResourceKey<Level> world = ((CraftWorld) event.getWorld()).getHandle().dimension();
+ final org.bukkit.util.Vector pos;
+ if (event instanceof me.lexikiq.HasLocation hasLoc) {
+ pos = hasLoc.getLocation().toVector();
+ } else if (event instanceof me.lexikiq.event.sound.EntitySoundEvent entityEvent) {
+ pos = entityEvent.getOrigin().getLocation().toVector();
+ } else {
+ throw new IllegalArgumentException("Could not determine location of sound event");
+ }
+ final double posX = pos.getX();
+ final double posY = pos.getY();
+ final double posZ = pos.getZ();
+ playSoundEvent(event, packet -> playerList.broadcast(player, posX, posY, posZ, radius, world, packet));
+ }
+ // Parchment end
}

View File

@@ -146,10 +146,10 @@ index 88439b8f82a97a9763dadfc6c9dbaf0912ab3eb7..73a9b765b58bb547712c014c8b908653
public static boolean canSetSpawn(Level world) {
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index b2f49ee945dae88c15a76e7ba5433b7ca150e9d6..a7679036d31f0262a68dd1bfb2871901b1d41825 100644
index b774a27eb4d11cd1bef807193a6df6012dde3794..911c0dd8a5863ae93dbd82fd3d6aafc267994081 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -955,7 +955,7 @@ public class CraftEventFactory {
@@ -961,7 +961,7 @@ public class CraftEventFactory {
CraftEventFactory.entityDamage = null;
EntityDamageEvent event;
if (damager == null) {
@@ -158,7 +158,7 @@ index b2f49ee945dae88c15a76e7ba5433b7ca150e9d6..a7679036d31f0262a68dd1bfb2871901
} else if (entity instanceof EnderDragon && /*PAIL FIXME ((EntityEnderDragon) entity).target == damager*/ false) {
event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions);
} else {
@@ -991,7 +991,7 @@ public class CraftEventFactory {
@@ -997,7 +997,7 @@ public class CraftEventFactory {
return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
} else if (source == DamageSource.OUT_OF_WORLD) {
@@ -167,7 +167,7 @@ index b2f49ee945dae88c15a76e7ba5433b7ca150e9d6..a7679036d31f0262a68dd1bfb2871901
event.setCancelled(cancelled);
CraftEventFactory.callEvent(event);
if (!event.isCancelled()) {
@@ -999,7 +999,7 @@ public class CraftEventFactory {
@@ -1005,7 +1005,7 @@ public class CraftEventFactory {
}
return event;
} else if (source == DamageSource.LAVA) {

View File

@@ -48,12 +48,12 @@ index 8c30e28b97ac7e8b54322c903e0b75ee8135620b..4ca85a02a1eb46b5958aae55946c67ce
});
state.spawnAfterBreak((ServerLevel) world, pos, stack);
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index a3245218525f538aaba00c72f3500880853dd9d0..760d35356591380a3e4a5cbd71ebe2ce13050dbc 100644
index 911c0dd8a5863ae93dbd82fd3d6aafc267994081..7aafe7cd3a8dae6b8f7b662049bf48bc6d698789 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1954,5 +1954,11 @@ public class CraftEventFactory {
final double posZ = pos.getZ();
playSoundEvent(event, packet -> playerList.broadcast(player, posX, posY, posZ, radius, world, packet));
@@ -1924,5 +1924,11 @@ public class CraftEventFactory {
return null;
}, net.minecraft.server.MCUtil.asyncExecutor);
}
+
+ public static List<ItemStack> callBlockDropResourcesEvent(LevelAccessor world, BlockPos pos, List<ItemStack> items) {