mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
LootTable API
Provides API to control what Loot Table an object uses. Also provides an Event to control if a lootable inventory should auto replenish for a player. Provides methods to determine players looted state for an object
This commit is contained in:
parent
391451207f
commit
397d3cac4b
16 changed files with 259 additions and 10 deletions
|
@ -0,0 +1,17 @@
|
||||||
|
package com.destroystokyo.paper.loottable;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an Inventory that can generate loot, such as Chests inside of Fortresses and Mineshafts
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
public interface LootableBlockInventory extends LootableInventory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block that is lootable
|
||||||
|
* @return The Block
|
||||||
|
*/
|
||||||
|
Block getBlock();
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.destroystokyo.paper.loottable;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an Inventory that can generate loot, such as Minecarts inside of Mineshafts
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
public interface LootableEntityInventory extends LootableInventory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity that is lootable
|
||||||
|
* @return The Entity
|
||||||
|
*/
|
||||||
|
Entity getEntity();
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package com.destroystokyo.paper.loottable;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.loot.Lootable;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an Inventory that contains a Loot Table associated to it that will
|
||||||
|
* automatically fill on first open.
|
||||||
|
* <p>
|
||||||
|
* A new feature and API is provided to support automatically refreshing the contents
|
||||||
|
* of the inventory based on that Loot Table after a configurable amount of time has passed.
|
||||||
|
* <p>
|
||||||
|
* The behavior of how the Inventory is filled based on the loot table may vary based
|
||||||
|
* on Minecraft versions and the Loot Table feature.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
public interface LootableInventory extends Lootable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server owners have to enable whether an object in a world should refill
|
||||||
|
*
|
||||||
|
* @return If the world this inventory is currently in has Replenishable Lootables enabled
|
||||||
|
*/
|
||||||
|
boolean isRefillEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this object has ever been filled
|
||||||
|
*
|
||||||
|
* @return Has ever been filled
|
||||||
|
*/
|
||||||
|
boolean hasBeenFilled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has this player ever looted this block
|
||||||
|
*
|
||||||
|
* @param player The player to check
|
||||||
|
* @return Whether this player has looted this block
|
||||||
|
*/
|
||||||
|
default boolean hasPlayerLooted(final Player player) {
|
||||||
|
return this.hasPlayerLooted(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this player can loot this block. Takes into account the "restrict player reloot" settings
|
||||||
|
*
|
||||||
|
* @param player the player to check
|
||||||
|
* @return Whether this player can loot this block
|
||||||
|
*/
|
||||||
|
boolean canPlayerLoot(UUID player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has this player ever looted this block
|
||||||
|
*
|
||||||
|
* @param player The player to check
|
||||||
|
* @return Whether this player has looted this block
|
||||||
|
*/
|
||||||
|
boolean hasPlayerLooted(UUID player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the timestamp, in milliseconds, of when the player last looted this object
|
||||||
|
*
|
||||||
|
* @param player The player to check
|
||||||
|
* @return Timestamp last looted, or null if player has not looted this object
|
||||||
|
*/
|
||||||
|
default @Nullable Long getLastLooted(final Player player) {
|
||||||
|
return this.getLastLooted(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the timestamp, in milliseconds, of when the player last looted this object
|
||||||
|
*
|
||||||
|
* @param player The player to check
|
||||||
|
* @return Timestamp last looted, or null if player has not looted this object
|
||||||
|
*/
|
||||||
|
@Nullable Long getLastLooted(UUID player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the state of whether a player has looted this block
|
||||||
|
*
|
||||||
|
* @param player The player to change state for
|
||||||
|
* @param looted true to add player to looted list, false to remove
|
||||||
|
* @return The previous state of whether the player had looted this or not
|
||||||
|
*/
|
||||||
|
default boolean setHasPlayerLooted(final Player player, final boolean looted) {
|
||||||
|
return this.setHasPlayerLooted(player.getUniqueId(), looted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the state of whether a player has looted this block
|
||||||
|
*
|
||||||
|
* @param player The player to change state for
|
||||||
|
* @param looted true to add player to looted list, false to remove
|
||||||
|
* @return The previous state of whether the player had looted this or not
|
||||||
|
*/
|
||||||
|
boolean setHasPlayerLooted(UUID player, boolean looted);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Whether this object has been filled and now has a pending refill
|
||||||
|
*
|
||||||
|
* @return Has pending refill
|
||||||
|
*/
|
||||||
|
boolean hasPendingRefill();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the timestamp in milliseconds that the Lootable object was last refilled
|
||||||
|
*
|
||||||
|
* @return -1 if it was never refilled, or timestamp in milliseconds
|
||||||
|
*/
|
||||||
|
long getLastFilled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the timestamp in milliseconds that the Lootable object will refill
|
||||||
|
*
|
||||||
|
* @return -1 if it is not scheduled for refill, or timestamp in milliseconds
|
||||||
|
*/
|
||||||
|
long getNextRefill();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the timestamp in milliseconds of the next refill for this object
|
||||||
|
*
|
||||||
|
* @param refillAt timestamp in milliseconds. -1 to clear next refill
|
||||||
|
* @return The previous scheduled time to refill, or -1 if was not scheduled
|
||||||
|
*/
|
||||||
|
long setNextRefill(long refillAt);
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.destroystokyo.paper.loottable;
|
||||||
|
|
||||||
|
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.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public class LootableInventoryReplenishEvent extends PlayerEvent implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
|
private final LootableInventory inventory;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public LootableInventoryReplenishEvent(final Player player, final LootableInventory inventory) {
|
||||||
|
super(player);
|
||||||
|
this.inventory = inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LootableInventory getInventory() {
|
||||||
|
return this.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,4 +5,4 @@ import org.bukkit.loot.Lootable;
|
||||||
/**
|
/**
|
||||||
* Represents a captured state of a Barrel.
|
* Represents a captured state of a Barrel.
|
||||||
*/
|
*/
|
||||||
public interface Barrel extends Container, Lootable, Lidded { }
|
public interface Barrel extends Container, com.destroystokyo.paper.loottable.LootableBlockInventory, Lidded { } // Paper
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.bukkit.block;
|
package org.bukkit.block;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableBlockInventory; // Paper
|
||||||
|
import org.bukkit.Nameable; // Paper
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -7,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
/**
|
/**
|
||||||
* Represents a captured state of a chest.
|
* Represents a captured state of a chest.
|
||||||
*/
|
*/
|
||||||
public interface Chest extends Container, Lootable, Lidded {
|
public interface Chest extends Container, LootableBlockInventory, Lidded { // Paper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the inventory of the chest block represented by this block state.
|
* Gets the inventory of the chest block represented by this block state.
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||||
* Represents a captured state of a crafter.
|
* Represents a captured state of a crafter.
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
public interface Crafter extends Container, Lootable {
|
public interface Crafter extends Container, com.destroystokyo.paper.loottable.LootableBlockInventory { // Paper - LootTable API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of ticks which this block will remain in the crafting
|
* Gets the number of ticks which this block will remain in the crafting
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.bukkit.block;
|
package org.bukkit.block;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||||
import org.bukkit.Nameable;
|
import org.bukkit.Nameable;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
import org.bukkit.projectiles.BlockProjectileSource;
|
import org.bukkit.projectiles.BlockProjectileSource;
|
||||||
|
@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
/**
|
/**
|
||||||
* Represents a captured state of a dispenser.
|
* Represents a captured state of a dispenser.
|
||||||
*/
|
*/
|
||||||
public interface Dispenser extends Container, Nameable, Lootable {
|
public interface Dispenser extends Container, Nameable, LootableBlockInventory { // Paper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the BlockProjectileSource object for the dispenser.
|
* Gets the BlockProjectileSource object for the dispenser.
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package org.bukkit.block;
|
package org.bukkit.block;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a captured state of a dropper.
|
* Represents a captured state of a dropper.
|
||||||
*/
|
*/
|
||||||
public interface Dropper extends Container, Lootable {
|
public interface Dropper extends Container, LootableBlockInventory { // Paper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to drop a randomly selected item from the dropper's inventory,
|
* Tries to drop a randomly selected item from the dropper's inventory,
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package org.bukkit.block;
|
package org.bukkit.block;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a captured state of a hopper.
|
* Represents a captured state of a hopper.
|
||||||
*/
|
*/
|
||||||
public interface Hopper extends Container, Lootable { }
|
public interface Hopper extends Container, LootableBlockInventory { } // Paper
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.bukkit.block;
|
package org.bukkit.block;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -7,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
/**
|
/**
|
||||||
* Represents a captured state of a ShulkerBox.
|
* Represents a captured state of a ShulkerBox.
|
||||||
*/
|
*/
|
||||||
public interface ShulkerBox extends Container, Lootable, Lidded {
|
public interface ShulkerBox extends Container, LootableBlockInventory, Lidded { // Paper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link DyeColor} corresponding to this ShulkerBox
|
* Get the {@link DyeColor} corresponding to this ShulkerBox
|
||||||
|
|
|
@ -6,5 +6,5 @@ import org.bukkit.loot.Lootable;
|
||||||
/**
|
/**
|
||||||
* A {@link Boat} with a chest.
|
* A {@link Boat} with a chest.
|
||||||
*/
|
*/
|
||||||
public interface ChestBoat extends Boat, InventoryHolder, Lootable {
|
public interface ChestBoat extends Boat, InventoryHolder, com.destroystokyo.paper.loottable.LootableEntityInventory { // Paper
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,4 +61,12 @@ public interface Mob extends LivingEntity, Lootable {
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public Sound getAmbientSound();
|
public Sound getAmbientSound();
|
||||||
|
|
||||||
|
// Paper start - LootTable API
|
||||||
|
@Override
|
||||||
|
default void setLootTable(final @Nullable org.bukkit.loot.LootTable table, final long seed) {
|
||||||
|
this.setLootTable(table);
|
||||||
|
this.setSeed(seed);
|
||||||
|
}
|
||||||
|
// Paper end - LootTable API
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.bukkit.entity.minecart;
|
package org.bukkit.entity.minecart;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableEntityInventory;
|
||||||
import org.bukkit.entity.Minecart;
|
import org.bukkit.entity.Minecart;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
|
@ -7,7 +8,7 @@ import org.bukkit.loot.Lootable;
|
||||||
/**
|
/**
|
||||||
* Represents a Minecart with a Hopper inside it
|
* Represents a Minecart with a Hopper inside it
|
||||||
*/
|
*/
|
||||||
public interface HopperMinecart extends Minecart, InventoryHolder, Lootable {
|
public interface HopperMinecart extends Minecart, InventoryHolder, LootableEntityInventory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether or not this Minecart will pick up
|
* Checks whether or not this Minecart will pick up
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.bukkit.entity.minecart;
|
package org.bukkit.entity.minecart;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.loottable.LootableEntityInventory;
|
||||||
import org.bukkit.entity.Minecart;
|
import org.bukkit.entity.Minecart;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.loot.Lootable;
|
import org.bukkit.loot.Lootable;
|
||||||
|
@ -9,5 +10,5 @@ import org.bukkit.loot.Lootable;
|
||||||
* minecarts} have their own inventory that can be accessed using methods
|
* minecarts} have their own inventory that can be accessed using methods
|
||||||
* from the {@link InventoryHolder} interface.
|
* from the {@link InventoryHolder} interface.
|
||||||
*/
|
*/
|
||||||
public interface StorageMinecart extends Minecart, InventoryHolder, Lootable {
|
public interface StorageMinecart extends Minecart, InventoryHolder, LootableEntityInventory { // Paper
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,31 @@ public interface Lootable {
|
||||||
@Nullable
|
@Nullable
|
||||||
LootTable getLootTable();
|
LootTable getLootTable();
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
/**
|
||||||
|
* Set the loot table and seed for a container or entity at the same time.
|
||||||
|
*
|
||||||
|
* @param table the Loot Table this {@link org.bukkit.block.Container} or {@link org.bukkit.entity.Mob} will have.
|
||||||
|
* @param seed the seed to used to generate loot. Default is 0.
|
||||||
|
*/
|
||||||
|
void setLootTable(final @Nullable LootTable table, final long seed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this object has a Loot Table
|
||||||
|
* @return Has a loot table
|
||||||
|
*/
|
||||||
|
default boolean hasLootTable() {
|
||||||
|
return this.getLootTable() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the associated Loot Table to this object
|
||||||
|
*/
|
||||||
|
default void clearLootTable() {
|
||||||
|
this.setLootTable(null);
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the seed used when this Loot Table generates loot.
|
* Set the seed used when this Loot Table generates loot.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue