Reworked price/shop API to have call-site multipliers
This commit is contained in:
@@ -23,6 +23,11 @@ public class ShopSellEvent extends PlayerEvent {
|
||||
*/
|
||||
private Price price;
|
||||
|
||||
/**
|
||||
* The price multiplier.
|
||||
*/
|
||||
private double multiplier;
|
||||
|
||||
/**
|
||||
* The item to be sold.
|
||||
*/
|
||||
@@ -54,10 +59,27 @@ public class ShopSellEvent extends PlayerEvent {
|
||||
public ShopSellEvent(@NotNull final Player who,
|
||||
@NotNull final Price price,
|
||||
@Nullable final ItemStack item) {
|
||||
this(who, price, item, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new shop sell event.
|
||||
*
|
||||
* @param who The player.
|
||||
* @param price The price.
|
||||
* @param item The item.
|
||||
* @param multiplier The multiplier.
|
||||
*/
|
||||
public ShopSellEvent(@NotNull final Player who,
|
||||
@NotNull final Price price,
|
||||
@Nullable final ItemStack item,
|
||||
final double multiplier) {
|
||||
super(who);
|
||||
|
||||
this.price = price;
|
||||
this.item = item;
|
||||
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,12 +102,41 @@ public class ShopSellEvent extends PlayerEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply the value by a certain amount.
|
||||
* Get the item to be sold.
|
||||
*
|
||||
* @return The item. Can be null for some plugins, so check hasKnownItem first!
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the item is known. Some shop plugins are lacking this in their event,
|
||||
* so always check this before getItem(), as getItem() may be null.
|
||||
*
|
||||
* @return If the item is known.
|
||||
*/
|
||||
public boolean hasKnownItem() {
|
||||
return item != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price multiplier.
|
||||
*
|
||||
* @return The multiplier.
|
||||
*/
|
||||
public double getMultiplier() {
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the price multiplier.
|
||||
*
|
||||
* @param multiplier The multiplier.
|
||||
*/
|
||||
public void multiplyValueBy(final double multiplier) {
|
||||
this.price = this.price.withMultiplier(multiplier);
|
||||
public void setMultiplier(final double multiplier) {
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,26 +161,6 @@ public class ShopSellEvent extends PlayerEvent {
|
||||
this.setValue(new PriceEconomy(price));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item to be sold.
|
||||
*
|
||||
* @return The item. Can be null for some plugins, so check hasKnownItem first!
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the item is known. Some shop plugins are lacking this in their event,
|
||||
* so always check this before getItem(), as getItem() may be null.
|
||||
*
|
||||
* @return If the item is known.
|
||||
*/
|
||||
public boolean hasKnownItem() {
|
||||
return item != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
|
||||
@@ -24,7 +24,7 @@ public final class ConfiguredPrice implements Price {
|
||||
/**
|
||||
* Free.
|
||||
*/
|
||||
private static final ConfiguredPrice FREE = new ConfiguredPrice(
|
||||
public static final ConfiguredPrice FREE = new ConfiguredPrice(
|
||||
new PriceFree(),
|
||||
"Free"
|
||||
);
|
||||
@@ -52,23 +52,27 @@ public final class ConfiguredPrice implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull final Player player) {
|
||||
return this.price.canAfford(player);
|
||||
public boolean canAfford(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return this.price.canAfford(player, multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull final Player player) {
|
||||
this.price.pay(player);
|
||||
public void pay(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
this.price.pay(player, multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void giveTo(@NotNull final Player player) {
|
||||
this.price.giveTo(player);
|
||||
public void giveTo(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
this.price.giveTo(player, multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(@NotNull final Player player) {
|
||||
return this.price.getValue(player);
|
||||
public double getValue(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return this.price.getValue(player, multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,14 +86,6 @@ public final class ConfiguredPrice implements Price {
|
||||
this.price.setMultiplier(player, multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfiguredPrice withMultiplier(final double multiplier) {
|
||||
return new ConfiguredPrice(
|
||||
this.price.withMultiplier(multiplier),
|
||||
formatString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price that this delegates to.
|
||||
*
|
||||
@@ -106,8 +102,20 @@ public final class ConfiguredPrice implements Price {
|
||||
* @return The display string.
|
||||
*/
|
||||
public String getDisplay(@NotNull final Player player) {
|
||||
return this.getDisplay(player, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display string for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param multiplier The multiplier.
|
||||
* @return The display string.
|
||||
*/
|
||||
public String getDisplay(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return StringUtils.format(
|
||||
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player))),
|
||||
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player, multiplier))),
|
||||
player,
|
||||
StringUtils.FormatOption.WITH_PLACEHOLDERS
|
||||
);
|
||||
|
||||
@@ -1,49 +1,123 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A price that a player should pay.
|
||||
* <p>
|
||||
* There are important implementation details:
|
||||
* <p>
|
||||
* For backwards compatibility, all methods are default, however you must override the following:
|
||||
* <ul>
|
||||
* <li><code>canAfford(Player, double)</code></li>
|
||||
* <li><code>pay(Player, double)</code></li>
|
||||
* <li><code>giveTo(Player, double)</code></li>
|
||||
* <li><code>getValue(Player, double)</code></li>
|
||||
* <li><code>getMultiplier(Player)</code></li>
|
||||
* <li><code>setMultiplier(Player, double)</code></li>
|
||||
* </ul>
|
||||
* Otherwise, your implementation will throw {@link NotImplementedException}.
|
||||
* <p>
|
||||
* Also, getValue() should always return the value with player multipliers applied.
|
||||
*/
|
||||
public interface Price {
|
||||
/**
|
||||
* Get if the player can afford the price.
|
||||
* Get if a player can afford to pay the price.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If the player can afford.
|
||||
*/
|
||||
boolean canAfford(@NotNull Player player);
|
||||
default boolean canAfford(@NotNull final Player player) {
|
||||
return this.canAfford(player, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a player can afford to pay x times the price.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param multiplier The multiplier.
|
||||
* @return If the player can afford.
|
||||
*/
|
||||
default boolean canAfford(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
throw new NotImplementedException("Override canAfford(Player, double) in your Price implementation!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the player pay the price.
|
||||
* <p>
|
||||
* Only run this if the player can afford the price.
|
||||
* Check canAfford first.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void pay(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Give the value of the price to the player.
|
||||
* <p>
|
||||
* You should override this method, it's only marked as default for
|
||||
* backwards compatibility purposes.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
default void giveTo(@NotNull Player player) {
|
||||
// Override when needed.
|
||||
default void pay(@NotNull final Player player) {
|
||||
this.pay(player, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the price is backed by a value, get it here.
|
||||
* Make the player pay the price x times.
|
||||
* <p>
|
||||
* Check canAfford first.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param multiplier The multiplier.
|
||||
*/
|
||||
default void pay(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
throw new NotImplementedException("Override pay(Player, double) in your Price implementation!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the price to the player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
default void giveTo(@NotNull final Player player) {
|
||||
this.giveTo(player, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the price to the player x times.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param multiplier The multiplier.
|
||||
*/
|
||||
default void giveTo(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
throw new NotImplementedException("Override giveTo(Player, double) in your Price implementation!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numerical value that backs this price.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The value.
|
||||
*/
|
||||
default double getValue(@NotNull final Player player) {
|
||||
return 0;
|
||||
return getValue(player, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numeral value that backs this price multiplied x times.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param multiplier The multiplier.
|
||||
* @return The value.
|
||||
*/
|
||||
default double getValue(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
throw new NotImplementedException("Override getValue(Player, double) in your Price implementation!");
|
||||
}
|
||||
|
||||
default double getMultiplier(@NotNull final Player player) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
default void setMultiplier(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
throw new NotImplementedException("Override setMultiplier(Player, double) in your Price implementation!");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,42 +135,10 @@ public interface Price {
|
||||
* If the price is backed by a value, set it here.
|
||||
*
|
||||
* @param value The value.
|
||||
* @deprecated Values shouldn't be fixed.
|
||||
* @deprecated Values shouldn't be fixed. This method should never work.
|
||||
*/
|
||||
@Deprecated(since = "6.45.0", forRemoval = true)
|
||||
default void setValue(final double value) {
|
||||
// Override when needed.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price multiplier for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The value.
|
||||
*/
|
||||
default double getMultiplier(@NotNull final Player player) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the price multiplier for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param multiplier The multiplier.
|
||||
*/
|
||||
default void setMultiplier(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
// Override when needed.
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy this price with a given base multiplier.
|
||||
*
|
||||
* @param multiplier The multiplier.
|
||||
* @return The price with the multiplier applied.
|
||||
*/
|
||||
@NotNull
|
||||
default Price withMultiplier(final double multiplier) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,23 +52,27 @@ public final class PriceEconomy implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull final Player player) {
|
||||
return EconomyManager.getBalance(player) >= getValue(player);
|
||||
public boolean canAfford(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return EconomyManager.getBalance(player) >= getValue(player, multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull final Player player) {
|
||||
EconomyManager.removeMoney(player, getValue(player));
|
||||
public void pay(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
EconomyManager.removeMoney(player, getValue(player, multiplier));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void giveTo(@NotNull final Player player) {
|
||||
EconomyManager.giveMoney(player, getValue(player));
|
||||
public void giveTo(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
EconomyManager.giveMoney(player, getValue(player, multiplier));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(@NotNull final Player player) {
|
||||
return this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player);
|
||||
public double getValue(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,15 +85,4 @@ public final class PriceEconomy implements Price {
|
||||
final double multiplier) {
|
||||
this.multipliers.put(player.getUniqueId(), multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PriceEconomy withMultiplier(double multiplier) {
|
||||
PriceEconomy copy = new PriceEconomy(
|
||||
baseContext,
|
||||
ctx -> function.apply(ctx) * multiplier
|
||||
);
|
||||
|
||||
copy.multipliers.putAll(this.multipliers);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,37 @@ public final class PriceFree implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull final Player player) {
|
||||
public boolean canAfford(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull final Player player) {
|
||||
// Do nothing.
|
||||
public void pay(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void giveTo(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMultiplier(@NotNull final Player player) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMultiplier(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,9 @@ public final class PriceItem implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull final Player player) {
|
||||
int toRemove = (int) getValue(player);
|
||||
public boolean canAfford(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
int toRemove = (int) getValue(player, multiplier);
|
||||
if (toRemove <= 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -92,8 +93,9 @@ public final class PriceItem implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull final Player player) {
|
||||
int toRemove = (int) getValue(player);
|
||||
public void pay(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
int toRemove = (int) getValue(player, multiplier);
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||
@@ -119,9 +121,10 @@ public final class PriceItem implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void giveTo(@NotNull final Player player) {
|
||||
public void giveTo(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
ItemStack itemStack = item.getItem().clone();
|
||||
itemStack.setAmount((int) getValue(player));
|
||||
itemStack.setAmount((int) getValue(player, multiplier));
|
||||
|
||||
new DropQueue(player)
|
||||
.addItem(itemStack)
|
||||
@@ -130,9 +133,11 @@ public final class PriceItem implements Price {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(@NotNull final Player player) {
|
||||
public double getValue(@NotNull final Player player,
|
||||
final double multiplier) {
|
||||
return Math.toIntExact(Math.round(
|
||||
this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
||||
this.function.apply(MathContext.copyWithPlayer(baseContext, player))
|
||||
* getMultiplier(player) * multiplier
|
||||
));
|
||||
}
|
||||
|
||||
@@ -146,16 +151,4 @@ public final class PriceItem implements Price {
|
||||
final double multiplier) {
|
||||
this.multipliers.put(player.getUniqueId(), multiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PriceItem withMultiplier(double multiplier) {
|
||||
PriceItem copy = new PriceItem(
|
||||
baseContext,
|
||||
ctx -> function.apply(ctx) * multiplier,
|
||||
item
|
||||
);
|
||||
|
||||
copy.multipliers.putAll(this.multipliers);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,20 +31,20 @@ class PriceFactoryUltraEconomy(private val currency: Currency) : PriceFactory {
|
||||
private val Player.account: Account?
|
||||
get() = api.accounts.uuid(this.uniqueId).orElse(null)
|
||||
|
||||
override fun canAfford(player: Player): Boolean {
|
||||
return (player.account?.getBalance(currency)?.onHand ?: 0f) >= getValue(player)
|
||||
override fun canAfford(player: Player, multiplier: Double): Boolean {
|
||||
return (player.account?.getBalance(currency)?.onHand ?: 0f) >= getValue(player, multiplier)
|
||||
}
|
||||
|
||||
override fun pay(player: Player) {
|
||||
player.account?.getBalance(currency)?.removeHand(getValue(player).toFloat())
|
||||
override fun pay(player: Player, multiplier: Double) {
|
||||
player.account?.getBalance(currency)?.removeHand(getValue(player, multiplier).toFloat())
|
||||
}
|
||||
|
||||
override fun giveTo(player: Player) {
|
||||
player.account?.getBalance(currency)?.addHand(getValue(player).toFloat())
|
||||
override fun giveTo(player: Player, multiplier: Double) {
|
||||
player.account?.getBalance(currency)?.addHand(getValue(player, multiplier).toFloat())
|
||||
}
|
||||
|
||||
override fun getValue(player: Player): Double {
|
||||
return function(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
||||
override fun getValue(player: Player, multiplier: Double): Double {
|
||||
return function(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) * multiplier
|
||||
}
|
||||
|
||||
override fun getMultiplier(player: Player): Double {
|
||||
@@ -54,17 +54,5 @@ class PriceFactoryUltraEconomy(private val currency: Currency) : PriceFactory {
|
||||
override fun setMultiplier(player: Player, multiplier: Double) {
|
||||
multipliers[player.uniqueId] = multiplier
|
||||
}
|
||||
|
||||
override fun withMultiplier(multiplier: Double): Price {
|
||||
val copy = PriceUltraEconomy(
|
||||
currency,
|
||||
baseContext
|
||||
) {
|
||||
function(it) * multiplier
|
||||
}
|
||||
|
||||
copy.multipliers.putAll(this.multipliers)
|
||||
return copy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class ShopDeluxeSellwands : ShopIntegration {
|
||||
|
||||
val ecoEvent = ShopSellEvent(event.player, PriceEconomy(event.money), null)
|
||||
Bukkit.getPluginManager().callEvent(ecoEvent)
|
||||
event.money = ecoEvent.value.getValue(event.player)
|
||||
event.money = ecoEvent.value.getValue(event.player) * ecoEvent.multiplier
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class ShopEconomyShopGUI : ShopIntegration {
|
||||
|
||||
val ecoEvent = ShopSellEvent(event.player, PriceEconomy(event.price), event.itemStack)
|
||||
Bukkit.getPluginManager().callEvent(ecoEvent)
|
||||
event.price = ecoEvent.value.getValue(event.player)
|
||||
event.price = ecoEvent.value.getValue(event.player) * ecoEvent.multiplier
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class ShopShopGuiPlus : ShopIntegration {
|
||||
|
||||
val ecoEvent = ShopSellEvent(event.player, PriceEconomy(event.price), event.shopItem.item)
|
||||
Bukkit.getPluginManager().callEvent(ecoEvent)
|
||||
event.price = ecoEvent.value.getValue(event.player)
|
||||
event.price = ecoEvent.value.getValue(event.player) * ecoEvent.multiplier
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class ShopZShop : ShopIntegration {
|
||||
|
||||
val ecoEvent = ShopSellEvent(event.player, PriceEconomy(event.price), event.button.itemStack)
|
||||
Bukkit.getPluginManager().callEvent(ecoEvent)
|
||||
event.price = ecoEvent.value.getValue(event.player)
|
||||
event.price = ecoEvent.value.getValue(event.player) * ecoEvent.multiplier
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user