SPIGOT-1936: LootTable API

By: Senmori <thesenmori@gmail.com>
This commit is contained in:
CraftBukkit/Spigot
2018-08-12 18:39:51 +10:00
parent 277f0db6c9
commit 39c4334d76
15 changed files with 434 additions and 21 deletions

View File

@@ -0,0 +1,109 @@
package org.bukkit.craftbukkit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import net.minecraft.server.BlockPosition;
import net.minecraft.server.DamageSource;
import net.minecraft.server.Entity;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.IInventory;
import net.minecraft.server.LootTable;
import net.minecraft.server.LootTableInfo;
import net.minecraft.server.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootContext;
public class CraftLootTable implements org.bukkit.loot.LootTable {
private final LootTable handle;
private final NamespacedKey key;
public CraftLootTable(NamespacedKey key, LootTable handle) {
this.handle = handle;
this.key = key;
}
public LootTable getHandle() {
return handle;
}
@Override
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
LootTableInfo nmsContext = convertContext(context);
List<net.minecraft.server.ItemStack> nmsItems = handle.a(random, nmsContext); // PAIL rename populateLoot
Collection<ItemStack> bukkit = new ArrayList<>(nmsItems.size());
for (net.minecraft.server.ItemStack item : nmsItems) {
if (item.isEmpty()) {
continue;
}
bukkit.add(CraftItemStack.asBukkitCopy(item));
}
return bukkit;
}
@Override
public void fillInventory(Inventory inventory, Random random, LootContext context) {
LootTableInfo nmsContext = convertContext(context);
CraftInventory craftInventory = (CraftInventory) inventory;
IInventory handle = craftInventory.getInventory();
// TODO: When events are added, call event here w/ custom reason?
getHandle().a(handle, random, nmsContext); // PAIL rename fillInventory
}
@Override
public NamespacedKey getKey() {
return key;
}
private LootTableInfo convertContext(LootContext context) {
Location loc = context.getLocation();
WorldServer handle = ((CraftWorld) loc.getWorld()).getHandle();
LootTableInfo.a builder = new LootTableInfo.a(handle); // PAIL rename Builder
builder.a(context.getLuck()); // PAIL rename withLuck, luck
if (context.getLootedEntity() != null) {
Entity nmsLootedEntity = ((CraftEntity) context.getLootedEntity()).getHandle();
builder.a(nmsLootedEntity); // PAIL Rename withLootedEntity, lootedEntity
builder.a(DamageSource.GENERIC); // PAIL rename withDamageSource, damageSource
builder.a(new BlockPosition(nmsLootedEntity)); // PAIL rename withPosition, position
}
if (context.getKiller() != null) {
EntityHuman nmsKiller = ((CraftHumanEntity) context.getKiller()).getHandle();
builder.a(nmsKiller); // PAIL rename withKiller, killer
// If there is a player killer, damage source should reflect that in case loot tables use that information
builder.a(DamageSource.playerAttack(nmsKiller)); // PAIL rename withDamageSource, damageSource
}
return builder.a(); // PAIL rename build
}
@Override
public String toString() {
return getKey().toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof org.bukkit.loot.LootTable)) {
return false;
}
org.bukkit.loot.LootTable table = (org.bukkit.loot.LootTable) obj;
return table.getKey().equals(this.getKey());
}
}

View File

@@ -95,6 +95,7 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.loot.LootTable;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.Plugin;
@@ -1765,6 +1766,13 @@ public final class CraftServer implements Server {
}
}
public LootTable getLootTable(NamespacedKey key) {
Validate.notNull(key, "NamespacedKey cannot be null");
LootTableRegistry registry = getServer().aP(); // PAIL getLootTableRegistry
return new CraftLootTable(key, registry.a(CraftNamespacedKey.toMinecraft(key))); // PAIL rename getLootTable
}
@Deprecated
@Override
public UnsafeValues getUnsafe() {

View File

@@ -1,12 +1,17 @@
package org.bukkit.craftbukkit.block;
import net.minecraft.server.MinecraftKey;
import net.minecraft.server.TileEntityLootable;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Nameable;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.loot.LootTable;
import org.bukkit.loot.Lootable;
public abstract class CraftLootable<T extends TileEntityLootable> extends CraftContainer<T> implements Nameable {
public abstract class CraftLootable<T extends TileEntityLootable> extends CraftContainer<T> implements Nameable, Lootable {
public CraftLootable(Block block, Class<T> tileEntityClass) {
super(block, tileEntityClass);
@@ -34,5 +39,38 @@ public abstract class CraftLootable<T extends TileEntityLootable> extends CraftC
if (!this.getSnapshot().hasCustomName()) {
lootable.setCustomName(null);
}
if (this.getSnapshot().Q_() == null) {
lootable.a((MinecraftKey) null, 0L); // PAIL rename setLootTable
}
}
@Override
public LootTable getLootTable() {
if (getSnapshot().Q_() == null) {
return null;
}
MinecraftKey key = getSnapshot().Q_();
return Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(key));
}
@Override
public void setLootTable(LootTable table) {
setLootTable(table, getSeed());
}
@Override
public long getSeed() {
return getSnapshotNBT().getLong("LootTableSeed"); // returns OL if an error occurred
}
@Override
public void setSeed(long seed) {
setLootTable(getLootTable(), seed);
}
private void setLootTable(LootTable table, long seed) {
MinecraftKey key = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
getSnapshot().a(key, seed); // PAIL setLootTable
}
}

View File

@@ -9,7 +9,7 @@ import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.inventory.Inventory;
@SuppressWarnings("deprecation")
public class CraftMinecartChest extends CraftMinecart implements StorageMinecart {
public class CraftMinecartChest extends CraftMinecartContainer implements StorageMinecart {
private final CraftInventory inventory;
public CraftMinecartChest(CraftServer server, EntityMinecartChest entity) {

View File

@@ -0,0 +1,54 @@
package org.bukkit.craftbukkit.entity;
import net.minecraft.server.EntityMinecartAbstract;
import net.minecraft.server.EntityMinecartContainer;
import net.minecraft.server.MinecraftKey;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.loot.LootTable;
import org.bukkit.loot.Lootable;
public abstract class CraftMinecartContainer extends CraftMinecart implements Lootable {
public CraftMinecartContainer(CraftServer server, EntityMinecartAbstract entity) {
super(server, entity);
}
@Override
public EntityMinecartContainer getHandle() {
return (EntityMinecartContainer) entity;
}
@Override
public void setLootTable(LootTable table) {
setLootTable(table, getSeed());
}
@Override
public LootTable getLootTable() {
MinecraftKey nmsTable = getHandle().Q_(); // PAIL getLootTable
if (nmsTable == null) {
return null; // return empty loot table?
}
NamespacedKey key = CraftNamespacedKey.fromMinecraft(nmsTable);
return Bukkit.getLootTable(key);
}
@Override
public void setSeed(long seed) {
setLootTable(getLootTable(), seed);
}
@Override
public long getSeed() {
return getHandle().d; // PAIL rename lootTableSeed
}
private void setLootTable(LootTable table, long seed) {
MinecraftKey newKey = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
getHandle().a(newKey, seed);
}
}

View File

@@ -8,10 +8,10 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.inventory.Inventory;
final class CraftMinecartHopper extends CraftMinecart implements HopperMinecart {
public final class CraftMinecartHopper extends CraftMinecartContainer implements HopperMinecart {
private final CraftInventory inventory;
CraftMinecartHopper(CraftServer server, EntityMinecartHopper entity) {
public CraftMinecartHopper(CraftServer server, EntityMinecartHopper entity) {
super(server, entity);
inventory = new CraftInventory(entity);
}

View File

@@ -1,9 +1,13 @@
package org.bukkit.craftbukkit.entity;
import net.minecraft.server.EntityInsentient;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mob;
import org.bukkit.loot.LootTable;
public abstract class CraftMob extends CraftLivingEntity implements Mob {
public CraftMob(CraftServer server, EntityInsentient entity) {
@@ -36,4 +40,29 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
public String toString() {
return "CraftMob";
}
@Override
public void setLootTable(LootTable table) {
getHandle().bI = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey()); // PAIL rename lootTableKey
}
@Override
public LootTable getLootTable() {
if (getHandle().bI == null) {
getHandle().bI = getHandle().getLootTable(); // Restore to entity default
}
NamespacedKey key = CraftNamespacedKey.fromMinecraft(getHandle().bI); // PAIL rename lootTableKey
return Bukkit.getLootTable(key);
}
@Override
public void setSeed(long seed) {
getHandle().bJ = seed; // PAIL rename lootTableSeed
}
@Override
public long getSeed() {
return getHandle().bJ; // PAIL rename lootTableSeed
}
}