Add vault change state event (#12069)

This commit is contained in:
Warrior 2025-04-26 16:34:12 +02:00 committed by GitHub
parent deaccd2c42
commit f86b435228
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 143 additions and 3 deletions

View File

@ -0,0 +1,79 @@
package io.papermc.paper.event.block;
import com.google.common.base.Preconditions;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Vault;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Called when a vault block changes state.
*/
@NullMarked
public class VaultChangeStateEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final @Nullable Player player;
private final Vault.State currentState;
private final Vault.State newState;
private boolean cancelled = false;
@ApiStatus.Internal
public VaultChangeStateEvent(final Block vaultBlock, final @Nullable Player player, final Vault.State currentState, final Vault.State newState) {
super(vaultBlock);
this.player = player;
this.currentState = currentState;
this.newState = newState;
}
/**
* Gets the player associated with this state change, if applicable.
*
* @return The associated player, or {@code null} if not known.
*/
public @Nullable Player getPlayer() {
return this.player;
}
/**
* Gets the state the vault is currently in.
*
* @return The current vault state.
*/
public Vault.State getCurrentState() {
return currentState;
}
/**
* Gets the state the vault is attempting to transition to.
*
* @return The new vault state.
*/
public Vault.State getNewState() {
return newState;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@ -1,17 +1,52 @@
--- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
@@ -260,6 +_,11 @@
@@ -260,7 +_,12 @@
if (!list.isEmpty()) {
player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
stack.consume(config.keyItem().getCount(), player);
- unlock(level, state, pos, config, serverData, sharedData, list);
+ // CraftBukkit start
+ org.bukkit.event.block.BlockDispenseLootEvent vaultDispenseLootEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDispenseLootEvent(level, pos, player, list);
+ if (vaultDispenseLootEvent.isCancelled()) return;
+ list = vaultDispenseLootEvent.getDispensedLoot().stream().map(org.bukkit.craftbukkit.inventory.CraftItemStack::asNMSCopy).toList();
+ // CraftBukkit end
unlock(level, state, pos, config, serverData, sharedData, list);
+ unlock(level, state, pos, config, serverData, sharedData, list, player); // Paper - Vault API
serverData.addToRewardedPlayers(player);
sharedData.updateConnectedPlayersWithinRange(level, pos, serverData, config, config.deactivationRange());
}
@@ -269,8 +_,30 @@
}
static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData) {
- VaultState vaultState = oldState.getValue(VaultBlock.STATE);
- VaultState vaultState1 = newState.getValue(VaultBlock.STATE);
+ // Paper start - Vault API
+ setVaultState(level, pos, oldState, newState, config,sharedData, null);
+ }
+
+ static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData, @Nullable Player associatedPlayer) {
+ VaultState vaultState = oldState.getValue(VaultBlock.STATE); final VaultState oldVaultState = vaultState;
+ VaultState vaultState1 = newState.getValue(VaultBlock.STATE); final VaultState newVaultState = vaultState1;
+ org.bukkit.entity.Player apiAssociatedPlayer = null;
+ if (associatedPlayer != null) {
+ apiAssociatedPlayer = (org.bukkit.entity.Player) associatedPlayer.getBukkitEntity();
+ } else if (newVaultState == VaultState.ACTIVE) {
+ final Set<UUID> connectedPlayers = sharedData.getConnectedPlayers();
+ if (!connectedPlayers.isEmpty()) { // Used over sharedData#hasConnectedPlayers to ensure belows iterator#next is always okay.
+ apiAssociatedPlayer = level.getCraftServer().getPlayer(connectedPlayers.iterator().next());
+ }
+ }
+ final io.papermc.paper.event.block.VaultChangeStateEvent event = new io.papermc.paper.event.block.VaultChangeStateEvent(
+ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos),
+ apiAssociatedPlayer,
+ org.bukkit.craftbukkit.block.data.CraftBlockData.toBukkit(oldVaultState, org.bukkit.block.data.type.Vault.State.class),
+ org.bukkit.craftbukkit.block.data.CraftBlockData.toBukkit(newVaultState, org.bukkit.block.data.type.Vault.State.class)
+ );
+ if (!event.callEvent()) return;
+ // Paper end - Vault API
level.setBlock(pos, newState, 3);
vaultState.onTransition(level, pos, vaultState1, config, sharedData, newState.getValue(VaultBlock.OMINOUS));
}
@@ -282,6 +_,11 @@
ItemStack randomDisplayItemFromLootTable = getRandomDisplayItemFromLootTable(
level, pos, config.overrideLootTableToDisplay().orElse(config.lootTable())
@ -24,3 +59,29 @@
sharedData.setDisplayItem(randomDisplayItemFromLootTable);
}
}
@@ -304,10 +_,24 @@
VaultSharedData sharedData,
List<ItemStack> itemsToEject
) {
+ // Paper start - Vault API
+ unlock(level, state, pos, config, serverData, sharedData, itemsToEject, null);
+ }
+ private static void unlock(
+ ServerLevel level,
+ BlockState state,
+ BlockPos pos,
+ VaultConfig config,
+ VaultServerData serverData,
+ VaultSharedData sharedData,
+ List<ItemStack> itemsToEject,
+ final @Nullable Player associatedPlayer
+ ) {
+ // Paper end - Vault API
serverData.setItemsToEject(itemsToEject);
sharedData.setDisplayItem(serverData.getNextItemToEject());
serverData.pauseStateUpdatingUntil(level.getGameTime() + 14L);
- setVaultState(level, pos, state, state.setValue(VaultBlock.STATE, VaultState.UNLOCKING), config, sharedData);
+ setVaultState(level, pos, state, state.setValue(VaultBlock.STATE, VaultState.UNLOCKING), config, sharedData, associatedPlayer); // Paper - Vault API
}
private static List<ItemStack> resolveItemsToEject(ServerLevel level, VaultConfig config, BlockPos pos, Player player, ItemStack key) {

View File

@ -165,7 +165,7 @@ public class CraftBlockData implements BlockData {
* @throws IllegalStateException if the Enum could not be converted
*/
@SuppressWarnings("unchecked")
private static <B extends Enum<B>> B toBukkit(Enum<?> nms, Class<B> bukkit) {
public static <B extends Enum<B>> B toBukkit(Enum<?> nms, Class<B> bukkit) {
if (nms instanceof Direction) {
return (B) CraftBlock.notchToBlockFace((Direction) nms);
}