From ec8936b765fbfe8c4ecee8038fb19f80d9a8d1c4 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Sat, 29 Oct 2022 16:28:48 +0100 Subject: [PATCH] Updated price API --- .../java/com/willfp/eco/core/price/Price.java | 12 +++++ .../willfp/eco/core/price/PriceFactory.java | 17 ++++++- .../com/willfp/eco/core/price/Prices.java | 7 +-- .../eco/core/price/impl/PriceEconomy.java | 35 ++++++++++----- .../willfp/eco/core/price/impl/PriceFree.java | 4 +- .../willfp/eco/core/price/impl/PriceItem.java | 44 ++++++++++++++----- .../eco/internal/price/PriceFactoryEconomy.kt | 5 ++- .../eco/internal/price/PriceFactoryXP.kt | 15 +++++-- .../internal/price/PriceFactoryXPLevels.kt | 15 +++++-- 9 files changed, 117 insertions(+), 37 deletions(-) diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/Price.java b/eco-api/src/main/java/com/willfp/eco/core/price/Price.java index 10eb0df4..c7900fa4 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/Price.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/Price.java @@ -24,6 +24,16 @@ public interface Price { */ void pay(@NotNull Player player); + /** + * Give the value of the price to the player. + * + * @param player The player. + * @apiNote You should override this method, it's only marked as default for backwards compatibility purposes. + */ + default void giveTo(@NotNull Player player) { + // Override when needed. + } + /** * If the price is backed by a value, get it here. * @@ -37,7 +47,9 @@ 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(since = "6.45.0", forRemoval = true) default void setValue(final double value) { // Override when needed. } diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java b/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java index 1883f0d1..1285d26f 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/PriceFactory.java @@ -3,9 +3,12 @@ package com.willfp.eco.core.price; import org.jetbrains.annotations.NotNull; import java.util.List; +import java.util.function.Supplier; /** * Create prices. + * + * @apiNote You must override one of the create methods to prevent infinite loops. */ public interface PriceFactory { /** @@ -23,5 +26,17 @@ public interface PriceFactory { * @param value The value. * @return The price. */ - @NotNull Price create(double value); + default @NotNull Price create(double value) { + return create(() -> value); + } + + /** + * Create the price. + * + * @param function The value function. + * @return The price. + */ + default @NotNull Price create(@NotNull Supplier<@NotNull Double> function) { + return create(function.get()); + } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java b/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java index 4bcca8c4..9d614d2d 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/Prices.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; /** * Class to manage prices. @@ -65,12 +66,12 @@ public final class Prices { public static Price create(@NotNull final String expression, @Nullable final String priceName, @NotNull final MathContext context) { - double value = NumberUtils.evaluateExpression( + Supplier value = () -> NumberUtils.evaluateExpression( expression, context ); - if (value <= 0) { + if (value.get() <= 0) { return new PriceFree(); } @@ -90,7 +91,7 @@ public final class Prices { return new PriceFree(); } - return new PriceItem((int) Math.round(value), item); + return new PriceItem(() -> Math.toIntExact(Math.round(value.get())), item); } else { return factory.create(value); } diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java index 5abf7659..e25347d3 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceEconomy.java @@ -5,6 +5,8 @@ import com.willfp.eco.core.price.Price; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import java.util.function.Supplier; + /** * Economy-based price (for Vault, Treasury, etc.) */ @@ -12,7 +14,7 @@ public final class PriceEconomy implements Price { /** * The value of the price. */ - private double value; + private final Supplier function; /** * Create a new economy-based price. @@ -20,26 +22,35 @@ public final class PriceEconomy implements Price { * @param value The value. */ public PriceEconomy(final double value) { - this.value = value; + this.function = () -> value; + } + + /** + * Create a new economy-based price. + * + * @param function The function. + */ + public PriceEconomy(@NotNull final Supplier<@NotNull Double> function) { + this.function = function; } @Override - public boolean canAfford(@NotNull Player player) { - return EconomyManager.getBalance(player) >= value; + public boolean canAfford(@NotNull final Player player) { + return EconomyManager.getBalance(player) >= getValue(); } @Override - public void pay(@NotNull Player player) { - EconomyManager.removeMoney(player, value); + public void pay(@NotNull final Player player) { + EconomyManager.removeMoney(player, getValue()); + } + + @Override + public void giveTo(@NotNull final Player player) { + EconomyManager.giveMoney(player, getValue()); } @Override public double getValue() { - return value; - } - - @Override - public void setValue(final double value) { - this.value = value; + return function.get(); } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceFree.java b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceFree.java index c9eb95b4..3de0c01d 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceFree.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceFree.java @@ -16,12 +16,12 @@ public final class PriceFree implements Price { } @Override - public boolean canAfford(@NotNull Player player) { + public boolean canAfford(@NotNull final Player player) { return true; } @Override - public void pay(@NotNull Player player) { + public void pay(@NotNull final Player player) { // Do nothing. } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java index 36fd267b..42840f49 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java +++ b/eco-api/src/main/java/com/willfp/eco/core/price/impl/PriceItem.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.price.impl; +import com.willfp.eco.core.drops.DropQueue; import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.price.Price; import org.bukkit.Material; @@ -7,6 +8,8 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import java.util.function.Supplier; + /** * Item-based price. */ @@ -14,7 +17,7 @@ public final class PriceItem implements Price { /** * The amount of items. */ - private final int amountToRemove; + private final Supplier amountToRemove; /** * The item. @@ -29,7 +32,18 @@ public final class PriceItem implements Price { */ public PriceItem(final int amount, @NotNull final TestableItem item) { - this.amountToRemove = Math.max(0, amount); + this(() -> amount, item); + } + + /** + * Create a new economy-based price. + * + * @param amount The amount. + * @param item The item. + */ + public PriceItem(@NotNull final Supplier<@NotNull Integer> amount, + @NotNull final TestableItem item) { + this.amountToRemove = amount; this.item = item; } @@ -43,8 +57,9 @@ public final class PriceItem implements Price { } @Override - public boolean canAfford(@NotNull Player player) { - if (amountToRemove == 0) { + public boolean canAfford(@NotNull final Player player) { + int toRemove = amountToRemove.get(); + if (toRemove <= 0) { return true; } @@ -56,26 +71,27 @@ public final class PriceItem implements Price { } } - return count >= amountToRemove; + return count >= toRemove; } @Override - public void pay(@NotNull Player player) { + public void pay(@NotNull final Player player) { + int toRemove = amountToRemove.get(); int count = 0; for (ItemStack itemStack : player.getInventory().getContents()) { - if (count >= amountToRemove) { + if (count >= toRemove) { break; } if (item.matches(itemStack)) { int itemAmount = itemStack.getAmount(); - if (itemAmount > amountToRemove) { - itemStack.setAmount(itemAmount - amountToRemove); + if (itemAmount > toRemove) { + itemStack.setAmount(itemAmount - toRemove); } - if (itemAmount <= amountToRemove) { + if (itemAmount <= toRemove) { itemStack.setAmount(0); itemStack.setType(Material.AIR); } @@ -84,4 +100,12 @@ public final class PriceItem implements Price { } } } + + @Override + public void giveTo(@NotNull final Player player) { + new DropQueue(player) + .addItem(item.getItem()) + .forceTelekinesis() + .push(); + } } diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt index 70cb5356..6b6335a5 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryEconomy.kt @@ -3,6 +3,7 @@ package com.willfp.eco.internal.price import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import com.willfp.eco.core.price.impl.PriceEconomy +import java.util.function.Supplier object PriceFactoryEconomy : PriceFactory { override fun getNames() = listOf( @@ -10,5 +11,7 @@ object PriceFactoryEconomy : PriceFactory { "$" ) - override fun create(value: Double): Price = PriceEconomy(value) + override fun create(function: Supplier): Price { + return PriceEconomy(function) + } } diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt index 5708d8ef..91e50ffd 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXP.kt @@ -3,6 +3,7 @@ package com.willfp.eco.internal.price import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import org.bukkit.entity.Player +import java.util.function.Supplier import kotlin.math.roundToInt object PriceFactoryXP : PriceFactory { @@ -12,15 +13,21 @@ object PriceFactoryXP : PriceFactory { "experience" ) - override fun create(value: Double): Price = PriceXP(value.roundToInt()) + override fun create(function: Supplier): Price { + return PriceXP { function.get().roundToInt() } + } private class PriceXP( - private val xp: Int + private val xp: () -> Int ) : Price { - override fun canAfford(player: Player) = player.totalExperience >= xp + override fun canAfford(player: Player) = player.totalExperience >= xp() override fun pay(player: Player) { - player.totalExperience -= xp + player.totalExperience -= xp() + } + + override fun giveTo(player: Player) { + player.totalExperience += xp() } } } diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt index 8bcfb642..0aa5b52e 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/price/PriceFactoryXPLevels.kt @@ -3,6 +3,7 @@ package com.willfp.eco.internal.price import com.willfp.eco.core.price.Price import com.willfp.eco.core.price.PriceFactory import org.bukkit.entity.Player +import java.util.function.Supplier import kotlin.math.roundToInt object PriceFactoryXPLevels : PriceFactory { @@ -13,15 +14,21 @@ object PriceFactoryXPLevels : PriceFactory { "explevels", ) - override fun create(value: Double): Price = PriceXPLevel(value.roundToInt()) + override fun create(function: Supplier): Price { + return PriceXPLevel { function.get().roundToInt() } + } private class PriceXPLevel( - private val levels: Int + private val levels: () -> Int ) : Price { - override fun canAfford(player: Player) = player.level >= levels + override fun canAfford(player: Player) = player.level >= levels() override fun pay(player: Player) { - player.level -= levels + player.level -= levels() + } + + override fun giveTo(player: Player) { + player.level += levels() } } }