From 972b9fea86022c4136504fbd3ac9c00070b96baa Mon Sep 17 00:00:00 2001 From: Xor Boole Date: Tue, 1 Mar 2016 08:30:04 +1100 Subject: Add Merchant API --- src/main/java/org/bukkit/entity/HumanEntity.java | 13 +++ src/main/java/org/bukkit/entity/Villager.java | 91 ++++++++++++++- .../event/entity/VillagerAcquireTradeEvent.java | 64 +++++++++++ .../event/entity/VillagerReplenishTradeEvent.java | 89 +++++++++++++++ .../org/bukkit/inventory/MerchantInventory.java | 19 ++++ .../java/org/bukkit/inventory/MerchantRecipe.java | 125 +++++++++++++++++++++ 6 files changed, 400 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/bukkit/event/entity/VillagerAcquireTradeEvent.java create mode 100644 src/main/java/org/bukkit/event/entity/VillagerReplenishTradeEvent.java create mode 100644 src/main/java/org/bukkit/inventory/MerchantRecipe.java (limited to 'src') diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java index ff8b4331..3d216770 100644 --- a/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/src/main/java/org/bukkit/entity/HumanEntity.java @@ -96,6 +96,19 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, Permissible, Inv */ public void openInventory(InventoryView inventory); + /** + * Starts a trade between the player and the villager. + * + * Note that only one player may trade with a villager at once. You must use + * the force parameter for this. + * + * @param trader The merchant to trade with. Cannot be null. + * @param force whether to force the trade even if another player is trading + * @return The newly opened inventory view, or null if it could not be + * opened. + */ + public InventoryView openMerchant(Villager trader, boolean force); + /** * Force-closes the currently open inventory view for this player, if any. */ diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java index 51035c93..069c8435 100644 --- a/src/main/java/org/bukkit/entity/Villager.java +++ b/src/main/java/org/bukkit/entity/Villager.java @@ -1,9 +1,14 @@ package org.bukkit.entity; +import java.util.List; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.MerchantRecipe; + /** * Represents a villager NPC */ -public interface Villager extends Ageable, NPC { +public interface Villager extends Ageable, NPC, InventoryHolder { /** * Gets the current profession of this villager. @@ -19,6 +24,90 @@ public interface Villager extends Ageable, NPC { */ public void setProfession(Profession profession); + /** + * Get a list of trades currently available from this villager. + * + * @return an immutable list of trades + */ + List getRecipes(); + + /** + * Set the list of trades currently available from this villager. + *
+ * This will not change the selected trades of players currently trading + * with this villager. + * + * @param recipes a list of recipes + */ + void setRecipes(List recipes); + + /** + * Get the recipe at a certain index of this villager's trade list. + * + * @param i the index + * @return the recipe + * @throws IndexOutOfBoundsException + */ + MerchantRecipe getRecipe(int i) throws IndexOutOfBoundsException; + + /** + * Set the recipe at a certain index of this villager's trade list. + * + * @param i the index + * @param recipe the recipe + * @throws IndexOutOfBoundsException + */ + void setRecipe(int i, MerchantRecipe recipe) throws IndexOutOfBoundsException; + + /** + * Get the number of trades this villager currently has available. + * + * @return the recipe count + */ + int getRecipeCount(); + + /** + * Gets this villager's inventory. + *
+ * Note that this inventory is not the Merchant inventory, rather, it is the + * items that a villager might have collected (from harvesting crops, etc.) + * + * @inheritDoc + */ + @Override + Inventory getInventory(); + + /** + * Gets whether this villager is currently trading. + * + * @return whether the villager is trading + */ + boolean isTrading(); + + /** + * Gets the player this villager is trading with, or null if it is not + * currently trading. + * + * @return the trader, or null + */ + HumanEntity getTrader(); + + /** + * Gets this villager's riches, the number of emeralds this villager has + * been given. + * + * @return the villager's riches + */ + int getRiches(); + + /** + * Sets this villager's riches. + * + * @see Villager#getRiches() + * + * @param riches the new riches + */ + void setRiches(int riches); /** * Represents the various different Villager professions there may be. diff --git a/src/main/java/org/bukkit/event/entity/VillagerAcquireTradeEvent.java b/src/main/java/org/bukkit/event/entity/VillagerAcquireTradeEvent.java new file mode 100644 index 00000000..a63271eb --- /dev/null +++ b/src/main/java/org/bukkit/event/entity/VillagerAcquireTradeEvent.java @@ -0,0 +1,64 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Villager; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.MerchantRecipe; + +/** + * Called whenever a villager acquires a new trade. + */ +public class VillagerAcquireTradeEvent extends EntityEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + // + private MerchantRecipe recipe; + + public VillagerAcquireTradeEvent(Villager what, MerchantRecipe recipe) { + super(what); + this.recipe = recipe; + } + + /** + * Get the recipe to be acquired. + * + * @return the new recipe + */ + public MerchantRecipe getRecipe() { + return recipe; + } + + /** + * Set the recipe to be acquired. + * + * @param recipe the new recipe + */ + public void setRecipe(MerchantRecipe recipe) { + this.recipe = recipe; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public Villager getEntity() { + return (Villager) super.getEntity(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/org/bukkit/event/entity/VillagerReplenishTradeEvent.java b/src/main/java/org/bukkit/event/entity/VillagerReplenishTradeEvent.java new file mode 100644 index 00000000..1bb39ca6 --- /dev/null +++ b/src/main/java/org/bukkit/event/entity/VillagerReplenishTradeEvent.java @@ -0,0 +1,89 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Villager; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.MerchantRecipe; + +/** + * Called when a villager's trade's maximum uses is increased, due to a player's + * trade. + * + * @see MerchantRecipe#getMaxUses() + */ +public class VillagerReplenishTradeEvent extends EntityEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + // + private MerchantRecipe recipe; + private int bonus; + + public VillagerReplenishTradeEvent(Villager what, MerchantRecipe recipe, int bonus) { + super(what); + this.recipe = recipe; + this.bonus = bonus; + } + + /** + * Get the recipe to replenish. + * + * @return the replenished recipe + */ + public MerchantRecipe getRecipe() { + return recipe; + } + + /** + * Set the recipe to replenish. + * + * @param recipe the replenished recipe + */ + public void setRecipe(MerchantRecipe recipe) { + this.recipe = recipe; + } + + /** + * Get the bonus uses added. The maximum uses of the recipe will be + * increased by this number. + * + * @return the extra uses added + */ + public int getBonus() { + return bonus; + } + + /** + * Set the bonus uses added. + * + * @see VillagerReplenishTradeEvent#getBonus() + * @param bonus the extra uses added + */ + public void setBonus(int bonus) { + this.bonus = bonus; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public Villager getEntity() { + return (Villager) super.getEntity(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/org/bukkit/inventory/MerchantInventory.java b/src/main/java/org/bukkit/inventory/MerchantInventory.java index 163f4597..d51fdbda 100644 --- a/src/main/java/org/bukkit/inventory/MerchantInventory.java +++ b/src/main/java/org/bukkit/inventory/MerchantInventory.java @@ -1,4 +1,23 @@ package org.bukkit.inventory; +/** + * Represents a trading inventory between a player and a villager. + *
+ * The holder of this Inventory is the owning Villager. + */ public interface MerchantInventory extends Inventory { + + /** + * Get the index of the currently selected recipe. + * + * @return the index of the currently selected recipe + */ + int getSelectedRecipeIndex(); + + /** + * Get the currently selected recipe. + * + * @return the currently selected recipe + */ + MerchantRecipe getSelectedRecipe(); } diff --git a/src/main/java/org/bukkit/inventory/MerchantRecipe.java b/src/main/java/org/bukkit/inventory/MerchantRecipe.java new file mode 100644 index 00000000..0a9fb637 --- /dev/null +++ b/src/main/java/org/bukkit/inventory/MerchantRecipe.java @@ -0,0 +1,125 @@ +package org.bukkit.inventory; + +import com.google.common.base.Preconditions; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a Villager's trade. + * + * Trades can take one or two ingredients, and provide one result. The + * ingredients' Itemstack amounts are respected in the trade. + *
+ * A trade has a limited number of uses, after which the trade can no longer be + * used, unless the player uses a different trade, which will cause its maximum + * uses to increase. + *
+ * A trade may or may not reward experience for being completed. + * + * @see org.bukkit.event.entity.VillagerReplenishTradeEvent + */ +public class MerchantRecipe implements Recipe { + + private ItemStack result; + private List ingredients = new ArrayList(); + private int uses; + private int maxUses; + private boolean experienceReward; + + public MerchantRecipe(ItemStack result, int maxUses) { + this(result, 0, maxUses, false); + } + + public MerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward) { + this.result = result; + this.uses = uses; + this.maxUses = maxUses; + this.experienceReward = experienceReward; + } + + @Override + public ItemStack getResult() { + return result; + } + + public void addIngredient(ItemStack item) { + Preconditions.checkState(ingredients.size() < 2, "Merchant can only have 2 ingredients"); + ingredients.add(item.clone()); + } + + public void removeIngredient(int index) { + ingredients.remove(index); + } + + public void setIngredients(List ingredients) { + this.ingredients = new ArrayList(); + for (ItemStack item : ingredients) { + this.ingredients.add(item.clone()); + } + } + + public List getIngredients() { + List copy = new ArrayList(); + for (ItemStack item : ingredients) { + copy.add(item.clone()); + } + return copy; + } + + /** + * Get the number of times this trade has been used. + * + * @return the number of uses + */ + public int getUses() { + return uses; + } + + /** + * Set the number of times this trade has been used. + * + * @param uses the number of uses + */ + public void setUses(int uses) { + this.uses = uses; + } + + /** + * Get the maximum number of uses this trade has. + *
+ * The maximum uses of this trade may increase when a player trades with the + * owning villager. + * + * @return the maximum number of uses + */ + public int getMaxUses() { + return maxUses; + } + + /** + * Set the maximum number of uses this trade has. + * + * @param maxUses the maximum number of time this trade can be used + */ + public void setMaxUses(int maxUses) { + this.maxUses = maxUses; + } + + /** + * Whether to reward experience for the trade. + * + * @return whether to reward experience for completing this trade + */ + public boolean hasExperienceReward() { + return experienceReward; + } + + /** + * Set whether to reward experience for the trade. + * + * @param flag whether to reward experience for completing this trade + */ + public void setExperienceReward(boolean flag) { + this.experienceReward = flag; + } +} -- cgit v1.2.3