SPIGOT-2272: Add API for virtual Merchants

This commit is contained in:
Lukas Hennig 2016-11-21 15:29:36 +11:00 committed by md_5
parent 7fc4255d1a
commit 0b154b1852
7 changed files with 207 additions and 37 deletions

View file

@ -43,12 +43,12 @@
+ }
+
+ public org.bukkit.inventory.InventoryHolder getOwner() {
+ return (CraftVillager) ((EntityVillager) this.merchant).getBukkitEntity();
+ return (merchant instanceof EntityVillager) ? (CraftVillager) ((EntityVillager) this.merchant).getBukkitEntity() : null;
+ }
+
+ @Override
+ public Location getLocation() {
+ return ((EntityVillager) this.merchant).getBukkitEntity().getLocation();
+ return (merchant instanceof EntityVillager) ? ((EntityVillager) this.merchant).getBukkitEntity().getLocation() : null;
+ }
+ // CraftBukkit end
+

View file

@ -59,6 +59,7 @@ import org.bukkit.craftbukkit.help.SimpleHelpMap;
import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe;
import org.bukkit.craftbukkit.inventory.CraftInventoryCustom;
import org.bukkit.craftbukkit.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.inventory.CraftMerchantCustom;
import org.bukkit.craftbukkit.inventory.CraftRecipe;
import org.bukkit.craftbukkit.inventory.CraftShapedRecipe;
import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
@ -85,6 +86,7 @@ import org.bukkit.generator.ChunkGenerator;
import org.bukkit.help.HelpMap;
import org.bukkit.inventory.FurnaceRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.Recipe;
@ -1480,6 +1482,11 @@ public final class CraftServer implements Server {
return new CraftInventoryCustom(owner, size, title);
}
@Override
public Merchant createMerchant(String title) {
return new CraftMerchantCustom(title);
}
@Override
public HelpMap getHelpMap() {
return helpMap;

View file

@ -8,8 +8,10 @@ import net.minecraft.server.*;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.inventory.MainHand;
import org.bukkit.inventory.Merchant;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Villager;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
@ -22,8 +24,8 @@ import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.inventory.CraftMerchant;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
@ -357,16 +359,32 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
@Override
public InventoryView openMerchant(Villager villager, boolean force) {
Preconditions.checkNotNull(villager, "villager cannot be null");
if (!force && villager.isTrading()) {
return this.openMerchant(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 (villager.isTrading()) {
// we're not supposed to have multiple people using the same villager, so we have to close it.
villager.getTrader().closeInventory();
} 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();
}
EntityVillager ev = ((CraftVillager) villager).getHandle();
ev.setTradingPlayer(this.getHandle());
this.getHandle().openTrade(ev);
IMerchant mcMerchant;
if (merchant instanceof CraftVillager) {
mcMerchant = ((CraftVillager) merchant).getHandle();
} else if (merchant instanceof CraftMerchant) {
mcMerchant = ((CraftMerchant) merchant).getMerchant();
} else {
throw new IllegalArgumentException("Can't open merchant " + merchant.toString());
}
mcMerchant.setTradingPlayer(this.getHandle());
this.getHandle().openTrade(mcMerchant);
return this.getHandle().activeContainer.getBukkitView();
}

View file

@ -1,16 +1,11 @@
package org.bukkit.craftbukkit.entity;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.EntityVillager;
import net.minecraft.server.MerchantRecipeList;
import org.apache.commons.lang.Validate;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftMerchantRecipe;
import org.bukkit.craftbukkit.inventory.CraftMerchant;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Villager;
@ -20,6 +15,8 @@ import org.bukkit.inventory.MerchantRecipe;
public class CraftVillager extends CraftAgeable implements Villager, InventoryHolder {
private CraftMerchant merchant;
public CraftVillager(CraftServer server, EntityVillager entity) {
super(server, entity);
}
@ -53,38 +50,33 @@ public class CraftVillager extends CraftAgeable implements Villager, InventoryHo
return new CraftInventory(getHandle().inventory);
}
@Override
public List<MerchantRecipe> getRecipes() {
return Collections.unmodifiableList(Lists.transform(getHandle().getOffers(null), new Function<net.minecraft.server.MerchantRecipe, MerchantRecipe>() {
@Override
public MerchantRecipe apply(net.minecraft.server.MerchantRecipe recipe) {
return recipe.asBukkit();
}
}));
private CraftMerchant getMerchant() {
return (merchant == null) ? merchant = new CraftMerchant(getHandle()) : merchant;
}
@Override
public void setRecipes(List<MerchantRecipe> list) {
MerchantRecipeList recipes = getHandle().getOffers(null);
recipes.clear();
for (MerchantRecipe m : list) {
recipes.add(CraftMerchantRecipe.fromBukkit(m).toMinecraft());
}
public List<MerchantRecipe> getRecipes() {
return getMerchant().getRecipes();
}
@Override
public void setRecipes(List<MerchantRecipe> recipes) {
this.getMerchant().setRecipes(recipes);
}
@Override
public MerchantRecipe getRecipe(int i) {
return getHandle().getOffers(null).get(i).asBukkit();
return getMerchant().getRecipe(i);
}
@Override
public void setRecipe(int i, MerchantRecipe merchantRecipe) {
getHandle().getOffers(null).set(i, CraftMerchantRecipe.fromBukkit(merchantRecipe).toMinecraft());
getMerchant().setRecipe(i, merchantRecipe);
}
@Override
public int getRecipeCount() {
return getHandle().getOffers(null).size();
return getMerchant().getRecipeCount();
}
@Override
@ -94,8 +86,7 @@ public class CraftVillager extends CraftAgeable implements Villager, InventoryHo
@Override
public HumanEntity getTrader() {
EntityHuman eh = getHandle().getTrader();
return eh == null ? null : eh.getBukkitEntity();
return getMerchant().getTrader();
}
@Override

View file

@ -0,0 +1,80 @@
package org.bukkit.craftbukkit.inventory;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.IMerchant;
import net.minecraft.server.MerchantRecipeList;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.MerchantRecipe;
public class CraftMerchant implements Merchant {
protected final IMerchant merchant;
public CraftMerchant(IMerchant merchant) {
this.merchant = merchant;
}
public IMerchant getMerchant() {
return merchant;
}
@Override
public List<MerchantRecipe> getRecipes() {
return Collections.unmodifiableList(Lists.transform(merchant.getOffers(null), new Function<net.minecraft.server.MerchantRecipe, MerchantRecipe>() {
@Override
public MerchantRecipe apply(net.minecraft.server.MerchantRecipe recipe) {
return recipe.asBukkit();
}
}));
}
@Override
public void setRecipes(List<MerchantRecipe> recipes) {
MerchantRecipeList recipesList = merchant.getOffers(null);
recipesList.clear();
for (MerchantRecipe recipe : recipes) {
recipesList.add(CraftMerchantRecipe.fromBukkit(recipe).toMinecraft());
}
}
@Override
public MerchantRecipe getRecipe(int i) {
return merchant.getOffers(null).get(i).asBukkit();
}
@Override
public void setRecipe(int i, MerchantRecipe merchantRecipe) {
merchant.getOffers(null).set(i, CraftMerchantRecipe.fromBukkit(merchantRecipe).toMinecraft());
}
@Override
public int getRecipeCount() {
return merchant.getOffers(null).size();
}
@Override
public boolean isTrading() {
return getTrader() != null;
}
@Override
public HumanEntity getTrader() {
EntityHuman eh = merchant.getTrader();
return eh == null ? null : eh.getBukkitEntity();
}
@Override
public int hashCode() {
return merchant.hashCode();
}
@Override
public boolean equals(final Object obj) {
return obj instanceof CraftMerchant && ((CraftMerchant) obj).merchant.equals(this.merchant);
}
}

View file

@ -0,0 +1,74 @@
package org.bukkit.craftbukkit.inventory;
import net.minecraft.server.BlockPosition;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.IChatBaseComponent;
import net.minecraft.server.IMerchant;
import net.minecraft.server.ItemStack;
import net.minecraft.server.MerchantRecipe;
import net.minecraft.server.MerchantRecipeList;
import net.minecraft.server.World;
import org.bukkit.craftbukkit.util.CraftChatMessage;
public class CraftMerchantCustom extends CraftMerchant {
public CraftMerchantCustom(String title) {
super(new MinecraftMerchant(title));
}
@Override
public String toString() {
return "CraftMerchantCustom";
}
private static class MinecraftMerchant implements IMerchant {
private final String title;
private final MerchantRecipeList trades = new MerchantRecipeList();
private EntityHuman tradingPlayer;
public MinecraftMerchant(String title) {
this.title = title;
}
@Override
public void setTradingPlayer(EntityHuman entityhuman) {
this.tradingPlayer = entityhuman;
}
@Override
public EntityHuman getTrader() {
return this.tradingPlayer;
}
@Override
public MerchantRecipeList getOffers(EntityHuman entityhuman) {
return this.trades;
}
@Override
public void a(MerchantRecipe merchantrecipe) {
// increase recipe's uses
merchantrecipe.g(); // PAIL: rename
}
@Override
public void a(ItemStack itemstack) {
}
@Override
public IChatBaseComponent getScoreboardDisplayName() {
return CraftChatMessage.fromString(title)[0];
}
@Override
public World t_() {
return null;
}
@Override
public BlockPosition u_() {
return null;
}
}
}

View file

@ -19,8 +19,8 @@ public class CraftMerchantRecipe extends MerchantRecipe {
public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward) {
super(result, uses, maxUses, experienceReward);
this.handle = new net.minecraft.server.MerchantRecipe(
null,
null,
net.minecraft.server.ItemStack.a,
net.minecraft.server.ItemStack.a,
CraftItemStack.asNMSCopy(result),
uses,
maxUses,