mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-08 03:22:19 +01:00
SPIGOT-1936: LootTable API
By: Senmori <thesenmori@gmail.com>
This commit is contained in:
parent
15d9fd30b9
commit
f50aec2a42
14 changed files with 421 additions and 8 deletions
|
@ -33,6 +33,7 @@ import org.bukkit.inventory.InventoryHolder;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
@ -1253,6 +1254,16 @@ public final class Bukkit {
|
|||
return server.getTag(registry, tag, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified {@link LootTable}.
|
||||
*
|
||||
* @param key the name of the LootTable
|
||||
* @return the LootTable, or null if no LootTable is found with that name
|
||||
*/
|
||||
public static LootTable getLootTable(NamespacedKey key) {
|
||||
return server.getLootTable(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see UnsafeValues
|
||||
* @return the unsafe values instance
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.bukkit.inventory.InventoryHolder;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
@ -1036,6 +1037,14 @@ public interface Server extends PluginMessageRecipient {
|
|||
*/
|
||||
<T extends Keyed> Tag<T> getTag(String registry, NamespacedKey tag, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Gets the specified {@link LootTable}.
|
||||
*
|
||||
* @param key the name of the LootTable
|
||||
* @return the LootTable, or null if no LootTable is found with that name
|
||||
*/
|
||||
LootTable getLootTable(NamespacedKey key);
|
||||
|
||||
/**
|
||||
* @see UnsafeValues
|
||||
* @return the unsafe values instance
|
||||
|
|
|
@ -2,11 +2,12 @@ package org.bukkit.block;
|
|||
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a chest.
|
||||
*/
|
||||
public interface Chest extends Container, Nameable {
|
||||
public interface Chest extends Container, Nameable, Lootable {
|
||||
|
||||
/**
|
||||
* Gets the inventory of the chest block represented by this block state.
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a dispenser.
|
||||
*/
|
||||
public interface Dispenser extends Container, Nameable {
|
||||
public interface Dispenser extends Container, Nameable, Lootable {
|
||||
|
||||
/**
|
||||
* Gets the BlockProjectileSource object for the dispenser.
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a dropper.
|
||||
*/
|
||||
public interface Dropper extends Container, Nameable {
|
||||
public interface Dropper extends Container, Nameable, Lootable {
|
||||
|
||||
/**
|
||||
* Tries to drop a randomly selected item from the dropper's inventory,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a hopper.
|
||||
*/
|
||||
public interface Hopper extends Container, Nameable { }
|
||||
public interface Hopper extends Container, Nameable, Lootable { }
|
||||
|
|
|
@ -2,11 +2,12 @@ package org.bukkit.block;
|
|||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a ShulkerBox.
|
||||
*/
|
||||
public interface ShulkerBox extends Container, Nameable {
|
||||
public interface ShulkerBox extends Container, Nameable, Lootable {
|
||||
|
||||
/**
|
||||
* Get the {@link DyeColor} corresponding to this ShulkerBox
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package org.bukkit.entity;
|
||||
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a Mob. Mobs are living entities with simple AI.
|
||||
*/
|
||||
public interface Mob extends LivingEntity {
|
||||
public interface Mob extends LivingEntity, Lootable {
|
||||
|
||||
/**
|
||||
* Instructs this Mob to set the specified LivingEntity as its target.
|
||||
|
|
|
@ -2,11 +2,12 @@ package org.bukkit.entity.minecart;
|
|||
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a Minecart with a Hopper inside it
|
||||
*/
|
||||
public interface HopperMinecart extends Minecart, InventoryHolder {
|
||||
public interface HopperMinecart extends Minecart, InventoryHolder, Lootable {
|
||||
|
||||
/**
|
||||
* Checks whether or not this Minecart will pick up
|
||||
|
|
|
@ -2,11 +2,12 @@ package org.bukkit.entity.minecart;
|
|||
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a minecart with a chest. These types of {@link Minecart
|
||||
* minecarts} have their own inventory that can be accessed using methods
|
||||
* from the {@link InventoryHolder} interface.
|
||||
*/
|
||||
public interface StorageMinecart extends Minecart, InventoryHolder {
|
||||
public interface StorageMinecart extends Minecart, InventoryHolder, Lootable {
|
||||
}
|
||||
|
|
168
paper-api/src/main/java/org/bukkit/loot/LootContext.java
Normal file
168
paper-api/src/main/java/org/bukkit/loot/LootContext.java
Normal file
|
@ -0,0 +1,168 @@
|
|||
package org.bukkit.loot;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
|
||||
/**
|
||||
* Represents additional information a {@link LootTable} can use to modify it's
|
||||
* generated loot.
|
||||
*/
|
||||
public final class LootContext {
|
||||
|
||||
public static final int DEFAULT_LOOT_MODIFIER = -1;
|
||||
|
||||
private final Location location;
|
||||
private final float luck;
|
||||
private final int lootingModifier;
|
||||
private final Entity lootedEntity;
|
||||
private final HumanEntity killer;
|
||||
|
||||
private LootContext(Location location, float luck, int lootingModifier, Entity lootedEntity, HumanEntity killer) {
|
||||
Validate.notNull(location, "LootContext location cannot be null");
|
||||
Validate.notNull(location.getWorld(), "LootContext World cannot be null");
|
||||
this.location = location;
|
||||
this.luck = luck;
|
||||
this.lootingModifier = lootingModifier;
|
||||
this.lootedEntity = lootedEntity;
|
||||
this.killer = killer;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Location} to store where the loot will be generated.
|
||||
*
|
||||
* @return the Location of where the loot will be generated
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the {@link org.bukkit.potion.PotionEffectType#LUCK} that an
|
||||
* entity can have. The higher the value the better chance of receiving more
|
||||
* loot.
|
||||
*
|
||||
* @return luck
|
||||
*/
|
||||
public float getLuck() {
|
||||
return luck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the
|
||||
* {@link org.bukkit.enchantments.Enchantment#LOOT_BONUS_MOBS} the
|
||||
* {@link #getKiller()} entity has on their equipped item.
|
||||
*
|
||||
* This value is only set via
|
||||
* {@link LootContext.Builder#lootingModifier(int)}. If not set, the
|
||||
* {@link #getKiller()} entity's looting level will be used instead.
|
||||
*
|
||||
* @return the looting level
|
||||
*/
|
||||
public int getLootingModifier() {
|
||||
return lootingModifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Entity} that was killed. Can be null.
|
||||
*
|
||||
* @return the looted entity or null
|
||||
*/
|
||||
public Entity getLootedEntity() {
|
||||
return lootedEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link HumanEntity} who killed the {@link #getLootedEntity()}.
|
||||
* Can be null.
|
||||
*
|
||||
* @return the killer entity, or null.
|
||||
*/
|
||||
public HumanEntity getKiller() {
|
||||
return killer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to make building {@link LootContext} easier. The only
|
||||
* required argument is {@link Location} with a valid (non-null)
|
||||
* {@link org.bukkit.World}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final Location location;
|
||||
private float luck;
|
||||
private int lootingModifier = LootContext.DEFAULT_LOOT_MODIFIER;
|
||||
private Entity lootedEntity;
|
||||
private HumanEntity killer;
|
||||
|
||||
/**
|
||||
* Creates a new LootContext.Builder instance to facilitate easy
|
||||
* creation of {@link LootContext}s.
|
||||
*
|
||||
* @param location the location the LootContext should use
|
||||
*/
|
||||
public Builder(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set how much luck to have when generating loot.
|
||||
*
|
||||
* @param luck the luck level
|
||||
* @return the Builder
|
||||
*/
|
||||
public Builder luck(float luck) {
|
||||
this.luck = luck;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link org.bukkit.enchantments.Enchantment#LOOT_BONUS_MOBS}
|
||||
* level equivalent to use when generating loot. Values less than or
|
||||
* equal to 0 will force the {@link LootTable} to only return a single
|
||||
* {@link org.bukkit.inventory.ItemStack} per pool.
|
||||
*
|
||||
* @param modifier the looting level modifier
|
||||
* @return the Builder
|
||||
*/
|
||||
public Builder lootingModifier(int modifier) {
|
||||
this.lootingModifier = modifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The entity that was killed.
|
||||
*
|
||||
* @param lootedEntity the looted entity
|
||||
* @return the Builder
|
||||
*/
|
||||
public Builder lootedEntity(Entity lootedEntity) {
|
||||
this.lootedEntity = lootedEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link org.bukkit.entity.HumanEntity} that killed
|
||||
* {@link #getLootedEntity()}. This entity will be used to get the
|
||||
* looting level if {@link #lootingModifier(int)} is not set.
|
||||
*
|
||||
* @param killer the killer entity
|
||||
* @return the Builder
|
||||
*/
|
||||
public Builder killer(HumanEntity killer) {
|
||||
this.killer = killer;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link LootContext} instance using the supplied
|
||||
* parameters.
|
||||
*
|
||||
* @return a new {@link LootContext} instance
|
||||
*/
|
||||
public LootContext build() {
|
||||
return new LootContext(location, luck, lootingModifier, lootedEntity, killer);
|
||||
}
|
||||
}
|
||||
}
|
37
paper-api/src/main/java/org/bukkit/loot/LootTable.java
Normal file
37
paper-api/src/main/java/org/bukkit/loot/LootTable.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package org.bukkit.loot;
|
||||
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* LootTables are technical files that represent what items should be in
|
||||
* naturally generated containers, what items should be dropped when killing a
|
||||
* mob, or what items can be fished.
|
||||
*
|
||||
* See the <a href="https://minecraft.gamepedia.com/Loot_table">
|
||||
* Minecraft Wiki</a> for more information.
|
||||
*/
|
||||
public interface LootTable extends Keyed {
|
||||
|
||||
/**
|
||||
* Returns a mutable list of loot generated by this LootTable.
|
||||
*
|
||||
* @param random the random instance to use to generate loot
|
||||
* @param context context within to populate loot
|
||||
* @return a list of ItemStacks
|
||||
*/
|
||||
Collection<ItemStack> populateLoot(Random random, LootContext context);
|
||||
|
||||
/**
|
||||
* Attempt to fill an inventory with this LootTable's loot.
|
||||
*
|
||||
* @param inventory the inventory to fill
|
||||
* @param random the random instance to use to generate loot
|
||||
* @param context context within to populate loot
|
||||
*/
|
||||
void fillInventory(Inventory inventory, Random random, LootContext context);
|
||||
}
|
128
paper-api/src/main/java/org/bukkit/loot/LootTables.java
Normal file
128
paper-api/src/main/java/org/bukkit/loot/LootTables.java
Normal file
|
@ -0,0 +1,128 @@
|
|||
package org.bukkit.loot;
|
||||
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
|
||||
/**
|
||||
* This enum holds a list of all known {@link LootTable}s offered by Mojang.
|
||||
* This list is not guaranteed to be accurate in future versions.
|
||||
*
|
||||
* See the
|
||||
* <a href="https://minecraft.gamepedia.com/Loot_table#List_of_loot_tables">
|
||||
* Minecraft Wiki</a> for more information on loot tables.
|
||||
*/
|
||||
public enum LootTables implements Keyed {
|
||||
|
||||
EMPTY("empty"),
|
||||
// Chests/Dispensers - treasure chests
|
||||
ABANDONED_MINESHAFT("chests/abandoned_mineshaft"),
|
||||
BURIED_TREASURE("chests/buried_treasure"),
|
||||
DESERT_PYRAMID("chests/desert_pyramid"),
|
||||
END_CITY_TREASURE("chests/end_city_treasure"),
|
||||
IGLOO_CHEST("chests/igloo_chest"),
|
||||
JUNGLE_TEMPLE("chests/jungle_temple"),
|
||||
JUNGLE_TEMPLE_DISPENSER("chests/jungle_temple_dispenser"),
|
||||
NETHER_BRIDGE("chests/nether_bridge"),
|
||||
SHIPWRECK_MAP("chests/shipwreck_map"),
|
||||
SHIPWRECK_SUPPLY("chests/shipwreck_supply"),
|
||||
SHIPWRECK_TREASURE("chests/shipwreck_treasure"),
|
||||
SIMPLE_DUNGEON("chests/simple_dungeon"),
|
||||
SPAWN_BONUS_CHEST("chests/spawn_bonus_chest"),
|
||||
STRONGHOLD_CORRIDOR("chests/stronghold_corridor"),
|
||||
STRONGHOLD_CROSSING("chests/stronghold_crossing"),
|
||||
STRONGHOLD_LIBRARY("chests/stronghold_library"),
|
||||
UNDERWATER_RUIN_BIG("chests/underwater_ruin_big"),
|
||||
UNDERWATER_RUIN_SMALL("chests/underwater_ruin_small"),
|
||||
VILLAGE_BLACKSMITH("chests/village_blacksmith"),
|
||||
WOODLAND_MANSION("chests/woodland_mansion"),
|
||||
// Entities
|
||||
BAT("entities/bat"),
|
||||
BLAZE("entities/blaze"),
|
||||
CAVE_SPIDER("entities/cave_spider"),
|
||||
CHICKEN("entities/chicken"),
|
||||
COD("entities/cod"),
|
||||
COW("entities/cow"),
|
||||
CREEPER("entities/creeper"),
|
||||
DOLPHIN("entities/dolphin"),
|
||||
DONKEY("entities/donkey"),
|
||||
DROWNED("entities/drowned"),
|
||||
ELDER_GUARDIAN("entities/elder_guardian"),
|
||||
ENDERMAN("entities/enderman"),
|
||||
ENDERMITE("entities/endermite"),
|
||||
ENDER_DRAGON("entities/ender_dragon"),
|
||||
EVOKER("entities/evoker"),
|
||||
GHAST("entities/ghast"),
|
||||
GIANT("entities/giant"),
|
||||
GUARDIAN("entities/guardian"),
|
||||
HORSE("entities/horse"),
|
||||
HUSK("entities/husk"),
|
||||
IRON_GOLEM("entities/iron_golem"),
|
||||
LLAMA("entities/llama"),
|
||||
MAGMA_CUBE("entities/magma_cube"),
|
||||
MULE("entities/mule"),
|
||||
MUSHROOM_COW("entities/mushroom_cow"),
|
||||
OCELOT("entities/ocelot"),
|
||||
PARROT("entities/parrot"),
|
||||
PHANTOM("entities/phantom"),
|
||||
PIG("entities/pig"),
|
||||
POLAR_BEAR("entities/polar_bear"),
|
||||
PUFFERFISH("entities/pufferfish"),
|
||||
RABBIT("entities/rabbit"),
|
||||
SALMON("entities/salmon"),
|
||||
// Sheep entry here, moved below for organizational purposes
|
||||
SHULKER("entities/shulker"),
|
||||
SILVERFISH("entities/silverfish"),
|
||||
SKELETON("entities/skeleton"),
|
||||
SKELETON_HORSE("entities/skeleton_horse"),
|
||||
SLIME("entities/slime"),
|
||||
SNOW_GOLEM("entities/snow_golem"),
|
||||
SPIDER("entities/spider"),
|
||||
SQUID("entities/squid"),
|
||||
STRAY("entities/stray"),
|
||||
TROPICAL_FISH("entities/tropical_fish"),
|
||||
TURTLE("entities/turtle"),
|
||||
VEX("entities/vex"),
|
||||
VILLAGER("entities/villager"),
|
||||
VINDICATOR("entities/vindicator"),
|
||||
WITCH("entities/witch"),
|
||||
WITHER_SKELETON("entities/wither_skeleton"),
|
||||
WOLF("entities/wolf"),
|
||||
ZOMBIE("entities/zombie"),
|
||||
ZOMBIE_HORSE("entities/zombie_horse"),
|
||||
ZOMBIE_PIGMAN("entities/zombie_pigman"),
|
||||
ZOMBIE_VILLAGER("entities/zombie_villager"),
|
||||
// Gameplay
|
||||
FISHING("gameplay/fishing"),
|
||||
FISHING_FISH("gameplay/fishing/fish"),
|
||||
FISHING_JUNK("gameplay/fishing/junk"),
|
||||
FISHING_TREASURE("gameplay/fishing/treasure"),
|
||||
// Sheep
|
||||
SHEEP("entities/sheep"),
|
||||
SHEEP_BLACK("entities/sheep/black"),
|
||||
SHEEP_BLUE("entities/sheep/blue"),
|
||||
SHEEP_BROWN("entities/sheep/brown"),
|
||||
SHEEP_CYAN("entities/sheep/cyan"),
|
||||
SHEEP_GRAY("entities/sheep/gray"),
|
||||
SHEEP_GREEN("entities/sheep/green"),
|
||||
SHEEP_LIGHT_BLUE("entities/sheep/light_blue"),
|
||||
SHEEP_LIME("entities/sheep/lime"),
|
||||
SHEEP_MAGENTA("entities/sheep/magenta"),
|
||||
SHEEP_ORANGE("entities/sheep/orange"),
|
||||
SHEEP_PINK("entities/sheep/pink"),
|
||||
SHEEP_PURPLE("entities/sheep/purple"),
|
||||
SHEEP_RED("entities/sheep/red"),
|
||||
SHEEP_WHITE("entities/sheep/white"),
|
||||
SHEEP_YELLOW("entities/sheep/yellow"),
|
||||
;
|
||||
|
||||
private final String location;
|
||||
|
||||
private LootTables(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return NamespacedKey.minecraft(location);
|
||||
}
|
||||
}
|
51
paper-api/src/main/java/org/bukkit/loot/Lootable.java
Normal file
51
paper-api/src/main/java/org/bukkit/loot/Lootable.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
package org.bukkit.loot;
|
||||
|
||||
/**
|
||||
* Represents a {@link org.bukkit.block.Container} or a
|
||||
* {@link org.bukkit.entity.Mob} that can have a loot table.
|
||||
* <br>
|
||||
* Container loot will only generate upon opening, and only when the container
|
||||
* is <i>first</i> opened.
|
||||
* <br>
|
||||
* Entities will only generate loot upon death.
|
||||
*/
|
||||
public interface Lootable {
|
||||
|
||||
/**
|
||||
* Set the loot table for a container or entity.
|
||||
* <br>
|
||||
* To remove a loot table use null. Do not use {@link LootTables#EMPTY} to
|
||||
* clear a LootTable.
|
||||
*
|
||||
* @param table the Loot Table this {@link org.bukkit.block.Container} or
|
||||
* {@link org.bukkit.entity.Mob} will have.
|
||||
*/
|
||||
void setLootTable(LootTable table);
|
||||
|
||||
/**
|
||||
* Gets the Loot Table attached to this block or entity.
|
||||
* <br>
|
||||
*
|
||||
* If an block/entity does not have a loot table, this will return null, NOT
|
||||
* an empty loot table.
|
||||
*
|
||||
* @return the Loot Table attached to this block or entity.
|
||||
*/
|
||||
LootTable getLootTable();
|
||||
|
||||
/**
|
||||
* Set the seed used when this Loot Table generates loot.
|
||||
*
|
||||
* @param seed the seed to used to generate loot. Default is 0.
|
||||
*/
|
||||
void setSeed(long seed);
|
||||
|
||||
/**
|
||||
* Get the Loot Table's seed.
|
||||
* <br>
|
||||
* The seed is used when generating loot.
|
||||
*
|
||||
* @return the seed
|
||||
*/
|
||||
long getSeed();
|
||||
}
|
Loading…
Reference in a new issue