mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-25 22:10:21 +01:00
Add PlayerLiddedOpenEvent
This commit is contained in:
parent
0450bda4fe
commit
abf6eca3dc
4 changed files with 139 additions and 6 deletions
|
@ -0,0 +1,89 @@
|
|||
package io.papermc.paper.event.player;
|
||||
|
||||
import io.papermc.paper.block.LidMode;
|
||||
import io.papermc.paper.block.LidState;
|
||||
import io.papermc.paper.block.Lidded;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Called when a player opens a {@link Lidded} block.
|
||||
*
|
||||
* <p>
|
||||
* This is called every time a player opens a {@link Lidded} block
|
||||
* regardless of if the lid is already open (e.g. multiple players).
|
||||
* <p>
|
||||
* Cancelling this event prevents the player from being considered in other {@link Lidded} methods:
|
||||
* they will not contribute to the {@link Lidded#getTrueLidState()} and {@link Lidded#getEffectiveLidState()}.
|
||||
* <p>
|
||||
* This event is called twice for double chests, once for each half.
|
||||
*/
|
||||
@NullMarked
|
||||
public class PlayerLiddedOpenEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
private final Lidded blockState;
|
||||
private final Block block;
|
||||
private boolean cancelled;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public PlayerLiddedOpenEvent(final @NotNull Player who, final @NotNull Lidded blockState, final @NotNull Block block) {
|
||||
super(who);
|
||||
this.cancelled = false;
|
||||
this.blockState = blockState;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Lidded} block involved in this event.
|
||||
* @return the lidded block
|
||||
*/
|
||||
@NotNull
|
||||
public Lidded getLidded() {
|
||||
return blockState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block involved in this event.
|
||||
* @return the block
|
||||
*/
|
||||
@NotNull
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the block would appear to open, if this event is not cancelled.
|
||||
* return if the block would appear to open
|
||||
*/
|
||||
public boolean isOpening() {
|
||||
return blockState.getLidMode() == LidMode.DEFAULT && blockState.getTrueLidState() == LidState.CLOSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
protected abstract void onOpen(Level level, BlockPos pos, BlockState state);
|
||||
|
||||
@@ -20,10 +_,94 @@
|
||||
@@ -20,10 +_,109 @@
|
||||
|
||||
protected abstract void openerCountChanged(Level level, BlockPos pos, BlockState state, int count, int openCount);
|
||||
|
||||
|
@ -33,13 +33,17 @@
|
|||
- public void incrementOpeners(Player player, Level level, BlockPos pos, BlockState state) {
|
||||
+ // Paper start - add Improved Lidded API
|
||||
+ private io.papermc.paper.block.LidMode apiLidMode = io.papermc.paper.block.LidMode.DEFAULT;
|
||||
+ private final java.util.Set<Player> cancelledPlayers = new java.util.HashSet<>(); // Paper - store players whose opening was cancelled by PlayerLiddedOpenEvent
|
||||
+
|
||||
+ public void startForceLiddedLidOpen(Level level, BlockPos pos, BlockState state) {
|
||||
+ incrementOpeners(null, level, pos, state);
|
||||
+ }
|
||||
+
|
||||
+ public void stopForceLiddedLidOpen(Level level, BlockPos pos, BlockState state) {
|
||||
+ decrementOpeners(null, level, pos, state);
|
||||
+ apiLidMode = io.papermc.paper.block.LidMode.DEFAULT;
|
||||
+ }
|
||||
+
|
||||
+ public void startForceLiddedLidClose(Level level, BlockPos pos, BlockState state) {
|
||||
+ if (this.getTrueLidState() == io.papermc.paper.block.LidState.OPEN) {
|
||||
+ this.onClose(level, pos, state);
|
||||
|
@ -47,6 +51,7 @@
|
|||
+ }
|
||||
+ this.openerCountChanged(level, pos, state, this.openCount, 0);
|
||||
+ }
|
||||
+
|
||||
+ public void stopForceLiddedLidClose(Level level, BlockPos pos, BlockState state) {
|
||||
+ if (this.getTrueLidState() == io.papermc.paper.block.LidState.OPEN) {
|
||||
+ this.onOpen(level, pos, state);
|
||||
|
@ -56,12 +61,15 @@
|
|||
+ this.openerCountChanged(level, pos, state, 0, this.openCount);
|
||||
+ apiLidMode = io.papermc.paper.block.LidMode.DEFAULT;
|
||||
+ }
|
||||
+
|
||||
+ public io.papermc.paper.block.LidMode getLidMode() {
|
||||
+ return apiLidMode;
|
||||
+ }
|
||||
+
|
||||
+ public void setLidMode(final io.papermc.paper.block.LidMode targetLidMode) {
|
||||
+ apiLidMode = targetLidMode;
|
||||
+ }
|
||||
+
|
||||
+ public io.papermc.paper.block.LidState getEffectiveLidState() {
|
||||
+ return switch (apiLidMode) {
|
||||
+ case OPEN_UNTIL_VIEWED, FORCED_OPEN -> io.papermc.paper.block.LidState.OPEN;
|
||||
|
@ -69,6 +77,7 @@
|
|||
+ default -> getTrueLidState();
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ public io.papermc.paper.block.LidState getTrueLidState() {
|
||||
+ boolean virtualViewerPresent = (apiLidMode == io.papermc.paper.block.LidMode.FORCED_OPEN || apiLidMode == io.papermc.paper.block.LidMode.OPEN_UNTIL_VIEWED);
|
||||
+ int trueOpenCount = this.openCount - (virtualViewerPresent ? 1 : 0);
|
||||
|
@ -80,6 +89,12 @@
|
|||
+ // Paper end - add Improved Lidded API
|
||||
+
|
||||
+ public void incrementOpeners(@javax.annotation.Nullable Player player, Level level, BlockPos pos, BlockState state) { // Paper - make player nullable for New Lidded API
|
||||
+ // Paper start - Call PlayerLiddedOpenEvent
|
||||
+ if (player != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLiddedOpenEvent(player, level, pos)) {
|
||||
+ cancelledPlayers.add(player);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call PlayerLiddedOpenEvent
|
||||
+ // Paper start - add Improved Lidded API
|
||||
+ if (this.openCount == 0 && apiLidMode == io.papermc.paper.block.LidMode.CLOSED_UNTIL_NOT_VIEWED) {
|
||||
+ apiLidMode = io.papermc.paper.block.LidMode.DEFAULT;
|
||||
|
@ -104,7 +119,7 @@
|
|||
if (i == 0) {
|
||||
this.onOpen(level, pos, state);
|
||||
level.gameEvent(player, GameEvent.CONTAINER_OPEN, pos);
|
||||
@@ -31,11 +_,43 @@
|
||||
@@ -31,11 +_,44 @@
|
||||
}
|
||||
|
||||
this.openerCountChanged(level, pos, state, i, this.openCount);
|
||||
|
@ -122,6 +137,7 @@
|
|||
|
||||
- public void decrementOpeners(Player player, Level level, BlockPos pos, BlockState state) {
|
||||
+ public void decrementOpeners(@javax.annotation.Nullable Player player, Level level, BlockPos pos, BlockState state) { // Paper - make player nullable for New Lidded API
|
||||
+ if (player != null && cancelledPlayers.remove(player)) return; // Paper - do not decrement if player's opening was cancelled by PlayerLiddedOpenEvent
|
||||
+ int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
|
||||
+ if (this.openCount == 0) return; // Paper - Prevent ContainerOpenersCounter openCount from going negative
|
||||
int i = this.openCount--;
|
||||
|
@ -149,7 +165,17 @@
|
|||
if (this.openCount == 0) {
|
||||
this.onClose(level, pos, state);
|
||||
level.gameEvent(player, GameEvent.CONTAINER_CLOSE, pos);
|
||||
@@ -59,8 +_,14 @@
|
||||
@@ -53,14 +_,24 @@
|
||||
|
||||
public void recheckOpeners(Level level, BlockPos pos, BlockState state) {
|
||||
List<Player> playersWithContainerOpen = this.getPlayersWithContainerOpen(level, pos);
|
||||
+ // Paper start - maintain cancelledPlayers, list of players with the chest open, but without the lid.
|
||||
+ cancelledPlayers.removeIf(java.util.function.Predicate.not(playersWithContainerOpen::contains));
|
||||
+ playersWithContainerOpen.removeIf(cancelledPlayers::contains);
|
||||
+ // Paper end - maintain cancelledPlayers, list of players with the chest open, but without the lid.
|
||||
this.maxInteractionRange = 0.0;
|
||||
|
||||
for (Player player : playersWithContainerOpen) {
|
||||
this.maxInteractionRange = Math.max(player.blockInteractionRange(), this.maxInteractionRange);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,13 @@
|
|||
this.openCount = type;
|
||||
if (type == 0) {
|
||||
this.animationStatus = ShulkerBoxBlockEntity.AnimationStatus.CLOSING;
|
||||
@@ -159,6 +_,71 @@
|
||||
@@ -159,6 +_,72 @@
|
||||
level.updateNeighborsAt(pos, state.getBlock());
|
||||
}
|
||||
|
||||
+ // Paper start - add Improved Lidded API
|
||||
+ private io.papermc.paper.block.LidMode apiLidMode = io.papermc.paper.block.LidMode.DEFAULT;
|
||||
+ private final java.util.Set<Player> cancelledPlayers = new java.util.HashSet<>(); // Paper - store players whose opening was cancelled by PlayerLiddedOpenEvent
|
||||
+
|
||||
+ public void startForceLiddedLidOpen() {
|
||||
+ this.openCount++;
|
||||
|
@ -118,10 +119,16 @@
|
|||
@Override
|
||||
public void startOpen(Player player) {
|
||||
if (!this.remove && !player.isSpectator()) {
|
||||
@@ -166,13 +_,36 @@
|
||||
@@ -166,20 +_,63 @@
|
||||
this.openCount = 0;
|
||||
}
|
||||
|
||||
+ // Paper start - Call PlayerLiddedOpenEvent
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLiddedOpenEvent(player, this.level, this.worldPosition)) {
|
||||
+ cancelledPlayers.add(player);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call PlayerLiddedOpenEvent
|
||||
+ // Paper start - add Improved Lidded API
|
||||
+ if (this.openCount == 0) {
|
||||
+ if (apiLidMode == io.papermc.paper.block.LidMode.CLOSED_UNTIL_NOT_VIEWED) {
|
||||
|
@ -155,9 +162,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +_,19 @@
|
||||
@Override
|
||||
public void stopOpen(Player player) {
|
||||
if (!this.remove && !player.isSpectator()) {
|
||||
+ if (cancelledPlayers.remove(player)) return; // Paper - do not decrement if player's opening was cancelled by PlayerLiddedOpenEvent
|
||||
this.openCount--;
|
||||
+
|
||||
+ // Paper start - add Improved Lidded API
|
||||
|
|
|
@ -2271,4 +2271,14 @@ public class CraftEventFactory {
|
|||
return event;
|
||||
}
|
||||
// Paper end - add EntityFertilizeEggEvent
|
||||
|
||||
public static boolean callPlayerLiddedOpenEvent(net.minecraft.world.entity.player.Player who, final Level world, final BlockPos pos) {
|
||||
Player player = (Player) who.getBukkitEntity();
|
||||
Block block = CraftBlock.at(world, pos);
|
||||
io.papermc.paper.block.PaperLidded blockState = (io.papermc.paper.block.PaperLidded) CraftBlockStates.getBlockState(block);
|
||||
|
||||
io.papermc.paper.event.player.PlayerLiddedOpenEvent event = new io.papermc.paper.event.player.PlayerLiddedOpenEvent(player, blockState, block);
|
||||
|
||||
return event.callEvent();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue