Updated price API

This commit is contained in:
Auxilor
2022-10-29 16:28:48 +01:00
parent cf347de4b8
commit ec8936b765
9 changed files with 117 additions and 37 deletions

View File

@@ -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.
}

View File

@@ -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());
}
}

View File

@@ -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<Double> 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);
}

View File

@@ -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<Double> 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();
}
}

View File

@@ -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.
}
}

View File

@@ -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<Integer> 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();
}
}