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 7a8eff04..a59c64e9 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 @@ -91,7 +91,7 @@ public final class Prices { return new PriceFree(); } - return new PriceItem(() -> Math.toIntExact(Math.round(function.apply(context))), item); + return new PriceItem(context, function, item); } else { return factory.create(context, function); } 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 42840f49..d83d2bc7 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 @@ -2,22 +2,31 @@ 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.math.MathContext; import com.willfp.eco.core.price.Price; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import java.util.function.Supplier; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; /** * Item-based price. */ public final class PriceItem implements Price { + /** + * The base MathContext. + */ + private final MathContext baseContext; + /** * The amount of items. */ - private final Supplier amountToRemove; + private final Function function; /** * The item. @@ -25,25 +34,33 @@ public final class PriceItem implements Price { private final TestableItem item; /** - * Create a new economy-based price. + * The multipliers. + */ + private final Map multipliers = new HashMap<>(); + + /** + * Create a new item-based price. * * @param amount The amount. * @param item The item. */ public PriceItem(final int amount, @NotNull final TestableItem item) { - this(() -> amount, item); + this(MathContext.EMPTY, ctx -> (double) amount, item); } /** - * Create a new economy-based price. + * Create a new item-based price. * - * @param amount The amount. - * @param item The item. + * @param baseContext The base MathContext. + * @param function The function to get the amount of items to remove. + * @param item The item. */ - public PriceItem(@NotNull final Supplier<@NotNull Integer> amount, + public PriceItem(@NotNull final MathContext baseContext, + @NotNull final Function function, @NotNull final TestableItem item) { - this.amountToRemove = amount; + this.baseContext = baseContext; + this.function = function; this.item = item; } @@ -58,7 +75,7 @@ public final class PriceItem implements Price { @Override public boolean canAfford(@NotNull final Player player) { - int toRemove = amountToRemove.get(); + int toRemove = (int) getValue(player); if (toRemove <= 0) { return true; } @@ -76,7 +93,7 @@ public final class PriceItem implements Price { @Override public void pay(@NotNull final Player player) { - int toRemove = amountToRemove.get(); + int toRemove = (int) getValue(player); int count = 0; for (ItemStack itemStack : player.getInventory().getContents()) { @@ -103,9 +120,30 @@ public final class PriceItem implements Price { @Override public void giveTo(@NotNull final Player player) { + ItemStack itemStack = item.getItem().clone(); + itemStack.setAmount((int) getValue(player)); + new DropQueue(player) - .addItem(item.getItem()) + .addItem(itemStack) .forceTelekinesis() .push(); } + + @Override + public double getValue(@NotNull final Player player) { + return Math.toIntExact(Math.round( + this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player) + )); + } + + @Override + public double getMultiplier(@NotNull final Player player) { + return this.multipliers.getOrDefault(player.getUniqueId(), 1.0); + } + + @Override + public void setMultiplier(@NotNull final Player player, + final double multiplier) { + this.multipliers.put(player.getUniqueId(), multiplier); + } }