Added price system
This commit is contained in:
26
eco-api/src/main/java/com/willfp/eco/core/price/Price.java
Normal file
26
eco-api/src/main/java/com/willfp/eco/core/price/Price.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A price that a player should pay.
|
||||
*/
|
||||
public interface Price {
|
||||
/**
|
||||
* Get if the player can afford the price.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If the player can afford.
|
||||
*/
|
||||
boolean canAfford(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Make the player pay the price.
|
||||
* <p>
|
||||
* Only run this if the player can afford the price.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void pay(@NotNull Player player);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Create prices.
|
||||
*/
|
||||
public interface PriceFactory {
|
||||
/**
|
||||
* Get the names (how the price looks in lookup strings).
|
||||
* <p>
|
||||
* For example, for XP Levels this would be 'l', 'xpl', 'levels', etc.
|
||||
*
|
||||
* @return The allowed names.
|
||||
*/
|
||||
@NotNull List<String> getNames();
|
||||
|
||||
/**
|
||||
* Create the price.
|
||||
*
|
||||
* @param value The value.
|
||||
* @return The price.
|
||||
*/
|
||||
@NotNull Price create(double value);
|
||||
}
|
||||
84
eco-api/src/main/java/com/willfp/eco/core/price/Prices.java
Normal file
84
eco-api/src/main/java/com/willfp/eco/core/price/Prices.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.price.impl.PriceEconomy;
|
||||
import com.willfp.eco.core.price.impl.PriceFree;
|
||||
import com.willfp.eco.core.price.impl.PriceItem;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Class to manage prices.
|
||||
*/
|
||||
public final class Prices {
|
||||
/**
|
||||
* All factories.
|
||||
*/
|
||||
private static final Map<String, PriceFactory> FACTORIES = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Register a new price factory.
|
||||
*
|
||||
* @param factory The factory.
|
||||
*/
|
||||
public static void registerPriceFactory(@NotNull final PriceFactory factory) {
|
||||
for (String name : factory.getNames()) {
|
||||
FACTORIES.put(name.toLowerCase(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a price from a string.
|
||||
* <p>
|
||||
* A price string should look like {@code 5000}, {@code 2000 levels},
|
||||
* {@code 200 g_souls}, {@code 200 pots of gold}, etc.
|
||||
*
|
||||
* @param key The key.
|
||||
* @return The price, or {@link PriceFree} if invalid.
|
||||
*/
|
||||
@NotNull
|
||||
public static Price lookup(@NotNull final String key) {
|
||||
String[] split = key.split(" ");
|
||||
|
||||
if (split.length == 0) {
|
||||
return new PriceFree();
|
||||
}
|
||||
|
||||
double value;
|
||||
|
||||
try {
|
||||
value = Double.parseDouble(split[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
value = 0.0;
|
||||
}
|
||||
|
||||
if (split.length == 1) {
|
||||
return new PriceEconomy(value);
|
||||
}
|
||||
|
||||
String name = String.join(" ", Arrays.copyOfRange(split, 1, split.length));
|
||||
|
||||
PriceFactory factory = FACTORIES.get(name.toLowerCase());
|
||||
|
||||
if (factory == null) {
|
||||
TestableItem item = Items.lookup(name.toLowerCase());
|
||||
|
||||
if (item instanceof EmptyTestableItem) {
|
||||
return new PriceFree();
|
||||
}
|
||||
|
||||
return new PriceItem((int) Math.round(value), item);
|
||||
}
|
||||
|
||||
return factory.create(value);
|
||||
}
|
||||
|
||||
private Prices() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.willfp.eco.core.price.impl;
|
||||
|
||||
import com.willfp.eco.core.integrations.economy.EconomyManager;
|
||||
import com.willfp.eco.core.price.Price;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Economy-based price (for Vault, Treasury, etc.)
|
||||
*/
|
||||
public final class PriceEconomy implements Price {
|
||||
/**
|
||||
* The value of the price.
|
||||
*/
|
||||
private final double value;
|
||||
|
||||
/**
|
||||
* Create a new economy-based price.
|
||||
*
|
||||
* @param value The value.
|
||||
*/
|
||||
public PriceEconomy(final double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull Player player) {
|
||||
return EconomyManager.getBalance(player) >= value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull Player player) {
|
||||
EconomyManager.removeMoney(player, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.price.impl;
|
||||
|
||||
import com.willfp.eco.core.price.Price;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Free (default) price.
|
||||
*/
|
||||
public final class PriceFree implements Price {
|
||||
/**
|
||||
* Create a new free price.
|
||||
*/
|
||||
public PriceFree() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull Player player) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.willfp.eco.core.price.impl;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Item-based price.
|
||||
*/
|
||||
public final class PriceItem implements Price {
|
||||
/**
|
||||
* The amount of items.
|
||||
*/
|
||||
private final int amountToRemove;
|
||||
|
||||
/**
|
||||
* The item.
|
||||
*/
|
||||
private final TestableItem item;
|
||||
|
||||
/**
|
||||
* Create a new economy-based price.
|
||||
*
|
||||
* @param amount The amount.
|
||||
*/
|
||||
public PriceItem(final int amount,
|
||||
@NotNull final TestableItem item) {
|
||||
this.amountToRemove = Math.max(0, amount);
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull Player player) {
|
||||
if (amountToRemove == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||
if (item.matches(itemStack)) {
|
||||
count += itemStack.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
return count >= amountToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull Player player) {
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||
if (count >= amountToRemove) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (item.matches(itemStack)) {
|
||||
int itemAmount = itemStack.getAmount();
|
||||
|
||||
if (itemAmount > amountToRemove) {
|
||||
itemStack.setAmount(itemAmount - amountToRemove);
|
||||
}
|
||||
|
||||
if (itemAmount <= amountToRemove) {
|
||||
itemStack.setAmount(0);
|
||||
itemStack.setType(Material.AIR);
|
||||
}
|
||||
|
||||
count += itemAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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
|
||||
|
||||
object PriceFactoryEconomy : PriceFactory {
|
||||
override fun getNames() = listOf(
|
||||
"coins",
|
||||
"$"
|
||||
)
|
||||
|
||||
override fun create(value: Double): Price = PriceEconomy(value)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
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 kotlin.math.roundToInt
|
||||
|
||||
object PriceFactoryXP : PriceFactory {
|
||||
override fun getNames() = listOf(
|
||||
"xp",
|
||||
"exp",
|
||||
"experience"
|
||||
)
|
||||
|
||||
override fun create(value: Double): Price = PriceXP(value.roundToInt())
|
||||
|
||||
private class PriceXP(
|
||||
private val xp: Int
|
||||
) : Price {
|
||||
override fun canAfford(player: Player) = player.totalExperience >= xp
|
||||
|
||||
override fun pay(player: Player) {
|
||||
player.totalExperience -= xp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
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 kotlin.math.roundToInt
|
||||
|
||||
object PriceFactoryXPLevels : PriceFactory {
|
||||
override fun getNames() = listOf(
|
||||
"levels",
|
||||
"xp levels",
|
||||
"exp levels",
|
||||
"l",
|
||||
"xpl",
|
||||
"expl"
|
||||
)
|
||||
|
||||
override fun create(value: Double): Price = PriceXPLevel(value.roundToInt())
|
||||
|
||||
private class PriceXPLevel(
|
||||
private val levels: Int
|
||||
) : Price {
|
||||
override fun canAfford(player: Player) = player.level >= levels
|
||||
|
||||
override fun pay(player: Player) {
|
||||
player.level -= levels
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.integrations.shop.ShopManager
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.price.Prices
|
||||
import com.willfp.eco.internal.entities.EntityArgParserAdult
|
||||
import com.willfp.eco.internal.entities.EntityArgParserAttackDamage
|
||||
import com.willfp.eco.internal.entities.EntityArgParserAttackSpeed
|
||||
@@ -45,11 +46,14 @@ import com.willfp.eco.internal.items.ArgParserTexture
|
||||
import com.willfp.eco.internal.items.ArgParserUnbreakable
|
||||
import com.willfp.eco.internal.lookup.SegmentParserGroup
|
||||
import com.willfp.eco.internal.lookup.SegmentParserUseIfPresent
|
||||
import com.willfp.eco.internal.price.PriceFactoryEconomy
|
||||
import com.willfp.eco.internal.price.PriceFactoryXP
|
||||
import com.willfp.eco.internal.price.PriceFactoryXPLevels
|
||||
import com.willfp.eco.internal.spigot.arrows.ArrowDataListener
|
||||
import com.willfp.eco.internal.spigot.data.DataListener
|
||||
import com.willfp.eco.internal.spigot.data.DataYml
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.PlayerBlockListener
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.storage.ProfileSaver
|
||||
import com.willfp.eco.internal.spigot.display.PacketAutoRecipe
|
||||
import com.willfp.eco.internal.spigot.display.PacketChat
|
||||
@@ -161,6 +165,10 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
Entities.registerArgParser(EntityArgParserSilent)
|
||||
Entities.registerArgParser(EntityArgParserEquipment)
|
||||
|
||||
Prices.registerPriceFactory(PriceFactoryEconomy)
|
||||
Prices.registerPriceFactory(PriceFactoryXPLevels)
|
||||
Prices.registerPriceFactory(PriceFactoryXP)
|
||||
|
||||
CraftingRecipeListener.registerListener(ComplexInComplex)
|
||||
CraftingRecipeListener.registerListener(ComplexInVanilla)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user