741 lines
27 KiB
Java
741 lines
27 KiB
Java
package org.bukkit.craftbukkit.entity;
|
|
|
|
import com.google.common.base.Preconditions;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import net.minecraft.server.BlockBed;
|
|
import net.minecraft.server.BlockEnchantmentTable;
|
|
import net.minecraft.server.BlockPosition;
|
|
import net.minecraft.server.BlockWorkbench;
|
|
import net.minecraft.server.Blocks;
|
|
import net.minecraft.server.ChatComponentText;
|
|
import net.minecraft.server.Container;
|
|
import net.minecraft.server.Containers;
|
|
import net.minecraft.server.CraftingManager;
|
|
import net.minecraft.server.Entity;
|
|
import net.minecraft.server.EntityHuman;
|
|
import net.minecraft.server.EntityMinecartHopper;
|
|
import net.minecraft.server.EntityPlayer;
|
|
import net.minecraft.server.EntityTypes;
|
|
import net.minecraft.server.EnumMainHand;
|
|
import net.minecraft.server.IBlockData;
|
|
import net.minecraft.server.IChatBaseComponent;
|
|
import net.minecraft.server.IInventory;
|
|
import net.minecraft.server.IMerchant;
|
|
import net.minecraft.server.IRecipe;
|
|
import net.minecraft.server.ITileInventory;
|
|
import net.minecraft.server.ItemCooldown;
|
|
import net.minecraft.server.NBTTagCompound;
|
|
import net.minecraft.server.PacketPlayInCloseWindow;
|
|
import net.minecraft.server.PacketPlayOutOpenWindow;
|
|
import net.minecraft.server.TileEntity;
|
|
import net.minecraft.server.TileEntityBarrel;
|
|
import net.minecraft.server.TileEntityBeacon;
|
|
import net.minecraft.server.TileEntityBlastFurnace;
|
|
import net.minecraft.server.TileEntityBrewingStand;
|
|
import net.minecraft.server.TileEntityDispenser;
|
|
import net.minecraft.server.TileEntityDropper;
|
|
import net.minecraft.server.TileEntityFurnaceFurnace;
|
|
import net.minecraft.server.TileEntityHopper;
|
|
import net.minecraft.server.TileEntityLectern;
|
|
import net.minecraft.server.TileEntityShulkerBox;
|
|
import net.minecraft.server.TileEntitySmoker;
|
|
import net.minecraft.server.Vec3D;
|
|
import org.bukkit.GameMode;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.NamespacedKey;
|
|
import org.bukkit.World;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.craftbukkit.CraftServer;
|
|
import org.bukkit.craftbukkit.CraftWorld;
|
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
import org.bukkit.craftbukkit.inventory.CraftContainer;
|
|
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
|
import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest;
|
|
import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer;
|
|
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
|
import org.bukkit.craftbukkit.inventory.CraftMerchantCustom;
|
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
|
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
|
import org.bukkit.entity.HumanEntity;
|
|
import org.bukkit.entity.Villager;
|
|
import org.bukkit.event.inventory.InventoryType;
|
|
import org.bukkit.inventory.EntityEquipment;
|
|
import org.bukkit.inventory.Inventory;
|
|
import org.bukkit.inventory.InventoryView;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.inventory.MainHand;
|
|
import org.bukkit.inventory.Merchant;
|
|
import org.bukkit.inventory.PlayerInventory;
|
|
import org.bukkit.permissions.PermissibleBase;
|
|
import org.bukkit.permissions.Permission;
|
|
import org.bukkit.permissions.PermissionAttachment;
|
|
import org.bukkit.permissions.PermissionAttachmentInfo;
|
|
import org.bukkit.plugin.Plugin;
|
|
|
|
public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
|
private CraftInventoryPlayer inventory;
|
|
private final CraftInventory enderChest;
|
|
protected final PermissibleBase perm = new PermissibleBase(this);
|
|
private boolean op;
|
|
private GameMode mode;
|
|
|
|
public CraftHumanEntity(final CraftServer server, final EntityHuman entity) {
|
|
super(server, entity);
|
|
mode = server.getDefaultGameMode();
|
|
this.inventory = new CraftInventoryPlayer(entity.inventory);
|
|
enderChest = new CraftInventory(entity.getEnderChest());
|
|
}
|
|
|
|
@Override
|
|
public PlayerInventory getInventory() {
|
|
return inventory;
|
|
}
|
|
|
|
@Override
|
|
public EntityEquipment getEquipment() {
|
|
return inventory;
|
|
}
|
|
|
|
@Override
|
|
public Inventory getEnderChest() {
|
|
return enderChest;
|
|
}
|
|
|
|
@Override
|
|
public MainHand getMainHand() {
|
|
return getHandle().getMainHand()== EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getItemInHand() {
|
|
return getInventory().getItemInHand();
|
|
}
|
|
|
|
@Override
|
|
public void setItemInHand(ItemStack item) {
|
|
getInventory().setItemInHand(item);
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getItemOnCursor() {
|
|
return CraftItemStack.asCraftMirror(getHandle().inventory.getCarried());
|
|
}
|
|
|
|
@Override
|
|
public void setItemOnCursor(ItemStack item) {
|
|
net.minecraft.server.ItemStack stack = CraftItemStack.asNMSCopy(item);
|
|
getHandle().inventory.setCarried(stack);
|
|
if (this instanceof CraftPlayer) {
|
|
((EntityPlayer) getHandle()).broadcastCarriedItem(); // Send set slot for cursor
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getSleepTicks() {
|
|
return getHandle().sleepTicks;
|
|
}
|
|
|
|
@Override
|
|
public Location getBedSpawnLocation() {
|
|
World world = getServer().getWorld(getHandle().spawnWorld);
|
|
BlockPosition bed = getHandle().getBed();
|
|
|
|
if (world != null && bed != null) {
|
|
Optional<Vec3D> spawnLoc = EntityHuman.getBed(((CraftWorld) world).getHandle(), bed, getHandle().isRespawnForced());
|
|
if (spawnLoc.isPresent()) {
|
|
Vec3D vec = spawnLoc.get();
|
|
return new Location(world, vec.x, vec.y, vec.z);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void setBedSpawnLocation(Location location) {
|
|
setBedSpawnLocation(location, false);
|
|
}
|
|
|
|
@Override
|
|
public void setBedSpawnLocation(Location location, boolean override) {
|
|
if (location == null) {
|
|
getHandle().setRespawnPosition(null, override);
|
|
} else {
|
|
getHandle().setRespawnPosition(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), override);
|
|
getHandle().spawnWorld = location.getWorld().getName();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean sleep(Location location, boolean force) {
|
|
Preconditions.checkArgument(location != null, "Location == null");
|
|
Preconditions.checkArgument(location.getWorld().equals(getWorld()), "Cannot sleep across worlds");
|
|
|
|
BlockPosition blockposition = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
|
IBlockData iblockdata = getHandle().world.getType(blockposition);
|
|
if (!(iblockdata.getBlock() instanceof BlockBed)) {
|
|
return false;
|
|
}
|
|
|
|
if (getHandle().sleep(blockposition, force).left().isPresent()) {
|
|
return false;
|
|
}
|
|
|
|
// From BlockBed
|
|
iblockdata = (IBlockData) iblockdata.set(BlockBed.OCCUPIED, true);
|
|
getHandle().world.setTypeAndData(blockposition, iblockdata, 4);
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void wakeup(boolean setSpawnLocation) {
|
|
Preconditions.checkState(isSleeping(), "Cannot wakeup if not sleeping");
|
|
|
|
getHandle().wakeup(true, true, setSpawnLocation);
|
|
}
|
|
|
|
@Override
|
|
public Location getBedLocation() {
|
|
Preconditions.checkState(isSleeping(), "Not sleeping");
|
|
|
|
BlockPosition bed = getHandle().getBed();
|
|
return new Location(getWorld(), bed.getX(), bed.getY(), bed.getZ());
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return getHandle().getName();
|
|
}
|
|
|
|
@Override
|
|
public boolean isOp() {
|
|
return op;
|
|
}
|
|
|
|
@Override
|
|
public boolean isPermissionSet(String name) {
|
|
return perm.isPermissionSet(name);
|
|
}
|
|
|
|
@Override
|
|
public boolean isPermissionSet(Permission perm) {
|
|
return this.perm.isPermissionSet(perm);
|
|
}
|
|
|
|
@Override
|
|
public boolean hasPermission(String name) {
|
|
return perm.hasPermission(name);
|
|
}
|
|
|
|
@Override
|
|
public boolean hasPermission(Permission perm) {
|
|
return this.perm.hasPermission(perm);
|
|
}
|
|
|
|
@Override
|
|
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
|
|
return perm.addAttachment(plugin, name, value);
|
|
}
|
|
|
|
@Override
|
|
public PermissionAttachment addAttachment(Plugin plugin) {
|
|
return perm.addAttachment(plugin);
|
|
}
|
|
|
|
@Override
|
|
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
|
|
return perm.addAttachment(plugin, name, value, ticks);
|
|
}
|
|
|
|
@Override
|
|
public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
|
|
return perm.addAttachment(plugin, ticks);
|
|
}
|
|
|
|
@Override
|
|
public void removeAttachment(PermissionAttachment attachment) {
|
|
perm.removeAttachment(attachment);
|
|
}
|
|
|
|
@Override
|
|
public void recalculatePermissions() {
|
|
perm.recalculatePermissions();
|
|
}
|
|
|
|
@Override
|
|
public void setOp(boolean value) {
|
|
this.op = value;
|
|
perm.recalculatePermissions();
|
|
}
|
|
|
|
@Override
|
|
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
|
return perm.getEffectivePermissions();
|
|
}
|
|
|
|
@Override
|
|
public GameMode getGameMode() {
|
|
return mode;
|
|
}
|
|
|
|
@Override
|
|
public void setGameMode(GameMode mode) {
|
|
if (mode == null) {
|
|
throw new IllegalArgumentException("Mode cannot be null");
|
|
}
|
|
|
|
this.mode = mode;
|
|
}
|
|
|
|
@Override
|
|
public EntityHuman getHandle() {
|
|
return (EntityHuman) entity;
|
|
}
|
|
|
|
public void setHandle(final EntityHuman entity) {
|
|
super.setHandle(entity);
|
|
this.inventory = new CraftInventoryPlayer(entity.inventory);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "CraftHumanEntity{" + "id=" + getEntityId() + "name=" + getName() + '}';
|
|
}
|
|
|
|
@Override
|
|
public InventoryView getOpenInventory() {
|
|
return getHandle().activeContainer.getBukkitView();
|
|
}
|
|
|
|
@Override
|
|
public InventoryView openInventory(Inventory inventory) {
|
|
if(!(getHandle() instanceof EntityPlayer)) return null;
|
|
EntityPlayer player = (EntityPlayer) getHandle();
|
|
InventoryType type = inventory.getType();
|
|
Container formerContainer = getHandle().activeContainer;
|
|
|
|
ITileInventory iinventory = null;
|
|
if (inventory instanceof CraftInventoryDoubleChest) {
|
|
iinventory = ((CraftInventoryDoubleChest) inventory).tile;
|
|
} else if (inventory instanceof CraftInventory) {
|
|
CraftInventory craft = (CraftInventory) inventory;
|
|
if (craft.getInventory() instanceof ITileInventory) {
|
|
iinventory = (ITileInventory) craft.getInventory();
|
|
}
|
|
}
|
|
|
|
if (iinventory instanceof ITileInventory) {
|
|
if (iinventory instanceof TileEntity) {
|
|
TileEntity te = (TileEntity) iinventory;
|
|
if (!te.hasWorld()) {
|
|
te.setWorld(getHandle().world);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (type) {
|
|
case PLAYER:
|
|
case CHEST:
|
|
case ENDER_CHEST:
|
|
if (iinventory instanceof ITileInventory) {
|
|
getHandle().openContainer((ITileInventory) iinventory);
|
|
} else {
|
|
Containers customSize;
|
|
switch (inventory.getSize()) {
|
|
case 9:
|
|
customSize = Containers.GENERIC_9X1;
|
|
break;
|
|
case 18:
|
|
customSize = Containers.GENERIC_9X2;
|
|
break;
|
|
case 27:
|
|
customSize = Containers.GENERIC_9X3;
|
|
break;
|
|
case 36:
|
|
case 41: // PLAYER
|
|
customSize = Containers.GENERIC_9X4;
|
|
break;
|
|
case 45:
|
|
customSize = Containers.GENERIC_9X5;
|
|
break;
|
|
case 54:
|
|
customSize = Containers.GENERIC_9X6;
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException("Unsupported custom inventory size " + inventory.getSize());
|
|
}
|
|
openCustomInventory(inventory, player, customSize);
|
|
}
|
|
break;
|
|
case DISPENSER:
|
|
if (iinventory instanceof TileEntityDispenser) {
|
|
getHandle().openContainer((TileEntityDispenser) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.GENERIC_3X3);
|
|
}
|
|
break;
|
|
case DROPPER:
|
|
if (iinventory instanceof TileEntityDropper) {
|
|
getHandle().openContainer((TileEntityDropper) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.GENERIC_3X3);
|
|
}
|
|
break;
|
|
case FURNACE:
|
|
if (iinventory instanceof TileEntityFurnaceFurnace) {
|
|
getHandle().openContainer((TileEntityFurnaceFurnace) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.FURNACE);
|
|
}
|
|
break;
|
|
case WORKBENCH:
|
|
openCustomInventory(inventory, player, Containers.CRAFTING);
|
|
break;
|
|
case BREWING:
|
|
if (iinventory instanceof TileEntityBrewingStand) {
|
|
getHandle().openContainer((TileEntityBrewingStand) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.BREWING_STAND);
|
|
}
|
|
break;
|
|
case ENCHANTING:
|
|
openCustomInventory(inventory, player, Containers.ENCHANTMENT);
|
|
break;
|
|
case HOPPER:
|
|
if (iinventory instanceof TileEntityHopper) {
|
|
getHandle().openContainer((TileEntityHopper) iinventory);
|
|
} else if (iinventory instanceof EntityMinecartHopper) {
|
|
getHandle().openContainer((EntityMinecartHopper) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.HOPPER);
|
|
}
|
|
break;
|
|
case BEACON:
|
|
if (iinventory instanceof TileEntityBeacon) {
|
|
getHandle().openContainer((TileEntityBeacon) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.BEACON);
|
|
}
|
|
break;
|
|
case ANVIL:
|
|
if (iinventory instanceof ITileInventory) {
|
|
getHandle().openContainer((ITileInventory) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.ANVIL);
|
|
}
|
|
break;
|
|
case SHULKER_BOX:
|
|
if (iinventory instanceof TileEntityShulkerBox) {
|
|
getHandle().openContainer((TileEntityShulkerBox) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.SHULKER_BOX);
|
|
}
|
|
break;
|
|
case BARREL:
|
|
if (iinventory instanceof TileEntityBarrel) {
|
|
getHandle().openContainer((TileEntityBarrel) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.GENERIC_9X3);
|
|
}
|
|
break;
|
|
case BLAST_FURNACE:
|
|
if (iinventory instanceof TileEntityBlastFurnace) {
|
|
getHandle().openContainer((TileEntityBlastFurnace) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.BLAST_FURNACE);
|
|
}
|
|
break;
|
|
case LECTERN:
|
|
if (iinventory instanceof TileEntityLectern) {
|
|
getHandle().openContainer((TileEntityLectern) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.LECTERN);
|
|
}
|
|
break;
|
|
case SMOKER:
|
|
if (iinventory instanceof TileEntitySmoker) {
|
|
getHandle().openContainer((TileEntitySmoker) iinventory);
|
|
} else {
|
|
openCustomInventory(inventory, player, Containers.SMOKER);
|
|
}
|
|
break;
|
|
case STONECUTTER:
|
|
openCustomInventory(inventory, player, Containers.STONECUTTER);
|
|
break;
|
|
case LOOM:
|
|
openCustomInventory(inventory, player, Containers.LOOM);
|
|
break;
|
|
case CARTOGRAPHY:
|
|
openCustomInventory(inventory, player, Containers.CARTOGRAPHY);
|
|
break;
|
|
case GRINDSTONE:
|
|
openCustomInventory(inventory, player, Containers.GRINDSTONE);
|
|
break;
|
|
case CREATIVE:
|
|
case CRAFTING:
|
|
case MERCHANT:
|
|
default:
|
|
throw new IllegalArgumentException("Can't open a " + type + " inventory!");
|
|
}
|
|
if (getHandle().activeContainer == formerContainer) {
|
|
return null;
|
|
}
|
|
getHandle().activeContainer.checkReachable = false;
|
|
return getHandle().activeContainer.getBukkitView();
|
|
}
|
|
|
|
private void openCustomInventory(Inventory inventory, EntityPlayer player, Containers<?> windowType) {
|
|
if (player.playerConnection == null) return;
|
|
Preconditions.checkArgument(windowType != null, "Unknown windowType");
|
|
Container container = new CraftContainer(inventory, this.getHandle(), player.nextContainerCounter());
|
|
|
|
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
|
if(container == null) return;
|
|
|
|
String title = container.getBukkitView().getTitle();
|
|
|
|
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title)));
|
|
getHandle().activeContainer = container;
|
|
getHandle().activeContainer.addSlotListener(player);
|
|
}
|
|
|
|
@Override
|
|
public InventoryView openWorkbench(Location location, boolean force) {
|
|
if (!force) {
|
|
Block block = location.getBlock();
|
|
if (block.getType() != Material.CRAFTING_TABLE) {
|
|
return null;
|
|
}
|
|
}
|
|
if (location == null) {
|
|
location = getLocation();
|
|
}
|
|
getHandle().openContainer(((BlockWorkbench) Blocks.CRAFTING_TABLE).getInventory(null, getHandle().world, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ())));
|
|
if (force) {
|
|
getHandle().activeContainer.checkReachable = false;
|
|
}
|
|
return getHandle().activeContainer.getBukkitView();
|
|
}
|
|
|
|
@Override
|
|
public InventoryView openEnchanting(Location location, boolean force) {
|
|
if (!force) {
|
|
Block block = location.getBlock();
|
|
if (block.getType() != Material.ENCHANTING_TABLE) {
|
|
return null;
|
|
}
|
|
}
|
|
if (location == null) {
|
|
location = getLocation();
|
|
}
|
|
|
|
// If there isn't an enchant table we can force create one, won't be very useful though.
|
|
BlockPosition pos = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
|
getHandle().openContainer(((BlockEnchantmentTable) Blocks.ENCHANTING_TABLE).getInventory(null, getHandle().world, pos));
|
|
|
|
if (force) {
|
|
getHandle().activeContainer.checkReachable = false;
|
|
}
|
|
return getHandle().activeContainer.getBukkitView();
|
|
}
|
|
|
|
@Override
|
|
public void openInventory(InventoryView inventory) {
|
|
if (!(getHandle() instanceof EntityPlayer)) return; // TODO: NPC support?
|
|
if (((EntityPlayer) getHandle()).playerConnection == null) return;
|
|
if (getHandle().activeContainer != getHandle().defaultContainer) {
|
|
// fire INVENTORY_CLOSE if one already open
|
|
((EntityPlayer)getHandle()).playerConnection.a(new PacketPlayInCloseWindow(getHandle().activeContainer.windowId));
|
|
}
|
|
EntityPlayer player = (EntityPlayer) getHandle();
|
|
Container container;
|
|
if (inventory instanceof CraftInventoryView) {
|
|
container = ((CraftInventoryView) inventory).getHandle();
|
|
} else {
|
|
container = new CraftContainer(inventory, this.getHandle(), player.nextContainerCounter());
|
|
}
|
|
|
|
// Trigger an INVENTORY_OPEN event
|
|
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
|
if (container == null) {
|
|
return;
|
|
}
|
|
|
|
// Now open the window
|
|
InventoryType type = inventory.getType();
|
|
Containers<?> windowType = CraftContainer.getNotchInventoryType(type);
|
|
String title = inventory.getTitle();
|
|
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title)));
|
|
player.activeContainer = container;
|
|
player.activeContainer.addSlotListener(player);
|
|
}
|
|
|
|
@Override
|
|
public InventoryView openMerchant(Villager villager, boolean force) {
|
|
Preconditions.checkNotNull(villager, "villager cannot be null");
|
|
|
|
return this.openMerchant((Merchant) villager, force);
|
|
}
|
|
|
|
@Override
|
|
public InventoryView openMerchant(Merchant merchant, boolean force) {
|
|
Preconditions.checkNotNull(merchant, "merchant cannot be null");
|
|
|
|
if (!force && merchant.isTrading()) {
|
|
return null;
|
|
} else if (merchant.isTrading()) {
|
|
// we're not supposed to have multiple people using the same merchant, so we have to close it.
|
|
merchant.getTrader().closeInventory();
|
|
}
|
|
|
|
IMerchant mcMerchant;
|
|
IChatBaseComponent name;
|
|
int level = 1; // note: using level 0 with active 'is-regular-villager'-flag allows hiding the name suffix
|
|
if (merchant instanceof CraftAbstractVillager) {
|
|
mcMerchant = ((CraftAbstractVillager) merchant).getHandle();
|
|
name = ((CraftAbstractVillager) merchant).getHandle().getScoreboardDisplayName();
|
|
if (merchant instanceof CraftVillager) {
|
|
level = ((CraftVillager) merchant).getHandle().getVillagerData().getLevel();
|
|
}
|
|
} else if (merchant instanceof CraftMerchantCustom) {
|
|
mcMerchant = ((CraftMerchantCustom) merchant).getMerchant();
|
|
name = ((CraftMerchantCustom) merchant).getMerchant().getScoreboardDisplayName();
|
|
} else {
|
|
throw new IllegalArgumentException("Can't open merchant " + merchant.toString());
|
|
}
|
|
|
|
mcMerchant.setTradingPlayer(this.getHandle());
|
|
mcMerchant.openTrade(this.getHandle(), name, level);
|
|
|
|
return this.getHandle().activeContainer.getBukkitView();
|
|
}
|
|
|
|
@Override
|
|
public void closeInventory() {
|
|
getHandle().closeInventory();
|
|
}
|
|
|
|
@Override
|
|
public boolean isBlocking() {
|
|
return getHandle().isBlocking();
|
|
}
|
|
|
|
@Override
|
|
public boolean isHandRaised() {
|
|
return getHandle().isHandRaised();
|
|
}
|
|
|
|
@Override
|
|
public boolean setWindowProperty(InventoryView.Property prop, int value) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int getExpToLevel() {
|
|
return getHandle().getExpToLevel();
|
|
}
|
|
|
|
@Override
|
|
public boolean hasCooldown(Material material) {
|
|
Preconditions.checkArgument(material != null, "material");
|
|
|
|
return getHandle().getCooldownTracker().a(CraftMagicNumbers.getItem(material));
|
|
}
|
|
|
|
@Override
|
|
public int getCooldown(Material material) {
|
|
Preconditions.checkArgument(material != null, "material");
|
|
|
|
ItemCooldown.Info cooldown = getHandle().getCooldownTracker().cooldowns.get(CraftMagicNumbers.getItem(material));
|
|
return (cooldown == null) ? 0 : Math.max(0, cooldown.endTick - getHandle().getCooldownTracker().currentTick);
|
|
}
|
|
|
|
@Override
|
|
public void setCooldown(Material material, int ticks) {
|
|
Preconditions.checkArgument(material != null, "material");
|
|
Preconditions.checkArgument(ticks >= 0, "Cannot have negative cooldown");
|
|
|
|
getHandle().getCooldownTracker().a(CraftMagicNumbers.getItem(material), ticks);
|
|
}
|
|
|
|
@Override
|
|
public boolean discoverRecipe(NamespacedKey recipe) {
|
|
return discoverRecipes(Arrays.asList(recipe)) != 0;
|
|
}
|
|
|
|
@Override
|
|
public int discoverRecipes(Collection<NamespacedKey> recipes) {
|
|
return getHandle().discoverRecipes(bukkitKeysToMinecraftRecipes(recipes));
|
|
}
|
|
|
|
@Override
|
|
public boolean undiscoverRecipe(NamespacedKey recipe) {
|
|
return undiscoverRecipes(Arrays.asList(recipe)) != 0;
|
|
}
|
|
|
|
@Override
|
|
public int undiscoverRecipes(Collection<NamespacedKey> recipes) {
|
|
return getHandle().undiscoverRecipes(bukkitKeysToMinecraftRecipes(recipes));
|
|
}
|
|
|
|
private Collection<IRecipe<?>> bukkitKeysToMinecraftRecipes(Collection<NamespacedKey> recipeKeys) {
|
|
Collection<IRecipe<?>> recipes = new ArrayList<>();
|
|
CraftingManager manager = getHandle().world.getMinecraftServer().getCraftingManager();
|
|
|
|
for (NamespacedKey recipeKey : recipeKeys) {
|
|
Optional<? extends IRecipe<?>> recipe = manager.a(CraftNamespacedKey.toMinecraft(recipeKey));
|
|
if (!recipe.isPresent()) {
|
|
continue;
|
|
}
|
|
|
|
recipes.add(recipe.get());
|
|
}
|
|
|
|
return recipes;
|
|
}
|
|
|
|
@Override
|
|
public org.bukkit.entity.Entity getShoulderEntityLeft() {
|
|
if (!getHandle().getShoulderEntityLeft().isEmpty()) {
|
|
Optional<Entity> shoulder = EntityTypes.a(getHandle().getShoulderEntityLeft(), getHandle().world);
|
|
|
|
return (!shoulder.isPresent()) ? null : shoulder.get().getBukkitEntity();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void setShoulderEntityLeft(org.bukkit.entity.Entity entity) {
|
|
getHandle().setShoulderEntityLeft(entity == null ? new NBTTagCompound() : ((CraftEntity) entity).save());
|
|
if (entity != null) {
|
|
entity.remove();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public org.bukkit.entity.Entity getShoulderEntityRight() {
|
|
if (!getHandle().getShoulderEntityRight().isEmpty()) {
|
|
Optional<Entity> shoulder = EntityTypes.a(getHandle().getShoulderEntityRight(), getHandle().world);
|
|
|
|
return (!shoulder.isPresent()) ? null : shoulder.get().getBukkitEntity();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void setShoulderEntityRight(org.bukkit.entity.Entity entity) {
|
|
getHandle().setShoulderEntityRight(entity == null ? new NBTTagCompound() : ((CraftEntity) entity).save());
|
|
if (entity != null) {
|
|
entity.remove();
|
|
}
|
|
}
|
|
}
|