Skip to content

Commit

Permalink
Add discounts system with automatic discounts for admin shops
Browse files Browse the repository at this point in the history
  • Loading branch information
Bestem0r committed Jan 19, 2023
1 parent f820886 commit 85af0b2
Show file tree
Hide file tree
Showing 15 changed files with 410 additions and 88 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
<dependency>
<groupId>com.github.Bestem0r</groupId>
<artifactId>BestemorCore</artifactId>
<version>328787c3d7</version>
<version>58279fde88</version>
<scope>compile</scope>
</dependency>

Expand Down
24 changes: 20 additions & 4 deletions src/main/java/net/bestemor/villagermarket/VMPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
import net.milkbowl.vault.economy.Economy;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;

public class VMPlugin extends CorePlugin {

Expand All @@ -32,6 +31,8 @@ public class VMPlugin extends CorePlugin {
private ChatListener chatListener;
private PlayerListener playerListener;

private final Map<String, String> localizedMaterials = new HashMap<>();

@Override
protected void onPluginEnable() {
setupEconomy();
Expand All @@ -50,7 +51,7 @@ protected void onPluginEnable() {
this.playerListener = new PlayerListener(this);
registerEvents();

Bukkit.getLogger().warning("[VillagerMarket] §cYou are running a §aBETA 1.11.5-#2 of VillagerMarket! Please expect and report all bugs in my discord server");
Bukkit.getLogger().warning("[VillagerMarket] §cYou are running a §aBETA 1.11.5-#8 of VillagerMarket! Please expect and report all bugs in my discord server");

Bukkit.getScheduler().runTaskLater(this, () -> {
if (Bukkit.getPluginManager().getPlugin("VillagerBank") != null) {
Expand All @@ -63,6 +64,17 @@ protected void onPluginEnable() {
new PlaceholderManager(this).register();
}

File materials = new File(getDataFolder(), "materials.yml");
if (materials.exists()) {
FileConfiguration config = YamlConfiguration.loadConfiguration(materials);
ConfigurationSection section = config.getConfigurationSection("materials");
if (section != null) {
for (String key : section.getKeys(false)) {
localizedMaterials.put(key, section.getString(key));
}
}
}

VillagerMarketAPI.init(this);
}

Expand Down Expand Up @@ -156,6 +168,10 @@ public PlayerListener getPlayerEvents() {
return playerListener;
}

public String getLocalizedMaterial(String material) {
return localizedMaterials.get(material);
}

public Economy getEconomy() {
return econ;
}
Expand Down
61 changes: 49 additions & 12 deletions src/main/java/net/bestemor/villagermarket/menu/EditItemMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.bestemor.core.menu.MenuContent;
import net.bestemor.villagermarket.VMPlugin;
import net.bestemor.villagermarket.shop.*;
import net.bestemor.villagermarket.utils.VMUtils;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
Expand All @@ -17,6 +18,7 @@
import org.bukkit.inventory.meta.ItemMeta;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
Expand Down Expand Up @@ -80,18 +82,9 @@ protected void onUpdate(MenuContent content) {
} else if (shopItem.getSellPrice().equals(BigDecimal.ZERO)) {
priceBuilder.replace("%price%", ConfigManager.getString("quantity.free"));
} else if (shopItem.getMode() == ItemMode.BUY_AND_SELL) {
String price;
String currency = ConfigManager.getString("currency");
String buyPrice = shopItem.getBuyPrice().stripTrailingZeros().toPlainString();
String sellPrice = shopItem.getSellPrice().stripTrailingZeros().toPlainString();
if (ConfigManager.getBoolean("currency_before")) {
price = currency + buyPrice + " / " + currency + sellPrice;
} else {
price = buyPrice + currency + " / " + sellPrice + currency;
}
priceBuilder.replace("%price%", price);
priceBuilder.replace("%price%", VMUtils.formatBuySellPrice(shopItem.getBuyPrice(false), shopItem.getSellPrice(false)));
} else {
priceBuilder.replaceCurrency("%price%", shopItem.getSellPrice());
priceBuilder.replaceCurrency("%price%", shopItem.getSellPrice(false));
}
ItemStack priceItem = priceBuilder.build();
if (shopItem.getMode() == ItemMode.BUY_AND_SELL) {
Expand Down Expand Up @@ -188,9 +181,20 @@ protected void onUpdate(MenuContent content) {
} else {
shopItem.setItemTrade(null, 0);
event.getView().close();
typePrice(player, event.getClick().isRightClick());
typePrice(player, shopItem.getMode() == ItemMode.BUY_AND_SELL && !event.getClick().isRightClick());
}
}));

if (!shopItem.isItemTrade()) {
ItemStack discountItem = ConfigManager.getItem("menus.edit_item.items.discount")
.replace("%discount%", String.valueOf(shopItem.getDiscount()))
.replace("%discount_end%", ConfigManager.getTimeLeft(shopItem.getDiscountEnd())).build();

content.setClickable(13, Clickable.of(discountItem, (event) -> {
event.getView().close();
typeDiscount((Player) event.getWhoClicked());
}));
}
}

@Override
Expand Down Expand Up @@ -248,6 +252,39 @@ private void typePrice(Player player, boolean isBuy) {
});
}

private void typeDiscount(Player player) {
player.sendMessage(ConfigManager.getMessage("messages.type_discount"));
plugin.getChatListener().addStringListener(player, (amountS) -> {
if (!VMUtils.isInteger(amountS)) {
player.sendMessage(ConfigManager.getMessage("messages.not_number"));
return;
}
int discount = Integer.parseInt(amountS);
if (discount < 0 || discount > 100) {
typeDiscount(player);
return;
}
if (discount == 0) {
shopItem.setDiscount(0, Instant.MIN);
update();
open(player);
return;
}
player.sendMessage(ConfigManager.getMessage("messages.type_time"));
plugin.getChatListener().addStringListener(player, (timeS) -> {
String amount = timeS.substring(0, timeS.length() - 1);
String unit = timeS.substring(timeS.length() - 1);
if (!VMUtils.isInteger(amount) || (!unit.equals("d") && !unit.equals("h") && !unit.equals("m"))) {
player.sendMessage(ConfigManager.getMessage("messages.not_valid_time"));
return;
}
shopItem.setDiscount(discount, VMUtils.getTimeFromNow(timeS));
update();
open(player);
});
});
}

private void handleLimit(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
if (shop instanceof AdminShop && event.getClick() == ClickType.RIGHT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ protected void buyItem(int slot, Player player) {
CurrencyBuilder message = ConfigManager.getCurrencyBuilder("messages.bought_item_as_customer")
.replace("%amount%", String.valueOf(shopItem.getAmount()))
.replace("%item%", shopItem.getItemName())
.replace("%shop%", getShopName());
.replace("%shop%", getShopName())
.addPrefix();

if (shopItem.isItemTrade()) {
message.replace("%price%", shopItem.getItemTradeAmount() + "x " + shopItem.getItemTradeName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ protected void buyItem(int slot, Player player) {
CurrencyBuilder message = ConfigManager.getCurrencyBuilder("messages.bought_item_as_customer")
.replace("%amount%", String.valueOf(shopItem.getAmount()))
.replace("%item%", shopItem.getItemName())
.replace("%shop%", getShopName());
.replace("%shop%", getShopName())
.addPrefix();

if (shopItem.isItemTrade()) {
message.replace("%price%", shopItem.getItemTradeAmount() + "x " + shopItem.getItemTradeName());
Expand Down
108 changes: 75 additions & 33 deletions src/main/java/net/bestemor/villagermarket/shop/ShopItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.bestemor.villagermarket.utils.VMUtils;
import net.milkbowl.vault.economy.Economy;
import org.apache.commons.lang.WordUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.ConfigurationSection;
Expand All @@ -20,7 +21,6 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;

import static net.bestemor.villagermarket.shop.ItemMode.*;
Expand All @@ -43,16 +43,17 @@ public enum LimitMode {

private BigDecimal sellPrice;
private BigDecimal buyPrice;
private int amount = 0;
private int amount;
private int itemTradeAmount = 0;
private ItemStack itemTrade;

//Limit variables
private int discount = 0;
private int limit = 0;
private LimitMode limitMode = LimitMode.PLAYER;
private String cooldown = "never";
private int serverTrades = 0;
private Instant nextReset;
private Instant discountEnd;
private final Map<UUID, Integer> playerLimits = new HashMap<>();

int storageAmount = 0;
Expand Down Expand Up @@ -104,6 +105,10 @@ public ShopItem(VMPlugin plugin, ConfigurationSection section) {
if (this.cooldown != null && !this.cooldown.equals("never")) {
this.nextReset = Instant.ofEpochSecond(section.getLong("next_reset"));
}
if (section.getConfigurationSection("discount") != null) {
this.discount = section.getInt("discount.amount");
this.discountEnd = Instant.ofEpochSecond(section.getLong("discount.end"));
}

ConfigurationSection limits = section.getConfigurationSection("limits");
if (limits != null) {
Expand All @@ -114,10 +119,30 @@ public ShopItem(VMPlugin plugin, ConfigurationSection section) {
}

public BigDecimal getSellPrice() {
return sellPrice == null ? BigDecimal.ZERO : sellPrice;
return getSellPrice(true);
}
public BigDecimal getSellPrice(boolean applyDiscount) {
if (sellPrice == null) {
return BigDecimal.ZERO;
} else if (!applyDiscount || discount <= 0) {
return sellPrice;
} else {
return sellPrice.subtract(sellPrice.multiply(BigDecimal.valueOf(discount / 100.0)));
}
}
public BigDecimal getBuyPrice() {
return mode != BUY_AND_SELL ? getSellPrice() : buyPrice == null ? BigDecimal.ZERO : buyPrice;
return getBuyPrice(true);
}
public BigDecimal getBuyPrice(boolean applyDiscount) {
if (mode != BUY_AND_SELL) {
return getSellPrice();
} else if (buyPrice == null) {
return BigDecimal.ZERO;
} else if (!applyDiscount || discount <= 0) {
return buyPrice;
} else {
return buyPrice.subtract(buyPrice.multiply(BigDecimal.valueOf(discount / 100.0)));
}
}
public Material getType() { return item.getType(); }
public int getSlot() {
Expand Down Expand Up @@ -242,33 +267,21 @@ private void reloadData(VillagerShop shop) {
}

private void resetCooldown() {
Instant i = Instant.now().truncatedTo(ChronoUnit.MINUTES);
if (cooldown == null) {
nextReset = Instant.ofEpochSecond(0);
return;
}
String s = cooldown.substring(0, cooldown.length() - 1);
if (!VMUtils.isInteger(s)) {
nextReset = Instant.ofEpochSecond(0);
cooldown = null;
return;
this.nextReset = VMUtils.getTimeFromNow(cooldown);
if (nextReset.getEpochSecond() == 0) {
this.cooldown = null;
}
}
public void setDiscount(int discount, Instant discountEnd) {
this.discount = discount;
this.discountEnd = discountEnd;
}
public int getDiscount() {
return discount;
}

int amount = Integer.parseInt(s);
switch (cooldown.substring(cooldown.length() - 1)) {
case "m":
i = i.plus(amount, ChronoUnit.MINUTES);
break;
case "h":
i = i.plus(amount, ChronoUnit.HOURS).truncatedTo(ChronoUnit.HOURS);
break;
case "d":
i = i.plus(amount, ChronoUnit.DAYS).truncatedTo(ChronoUnit.DAYS);
break;
default:

}
this.nextReset = i;
public Instant getDiscountEnd() {
return discountEnd;
}

public void clearLimits() {
Expand Down Expand Up @@ -352,18 +365,45 @@ private List<String> getLore(String path, ItemMode mode, Player p) {
if (isItemTrade()) {
builder.replace("%price%", getItemTradeAmount() + "x" + " " + getItemName(itemTrade));
} else if (getSellPrice().equals(BigDecimal.ZERO)) {

builder.replace("%price%", ConfigManager.getString("quantity.free"));
builder.replace("%price_per_unit%", ConfigManager.getString("quantity.free"));
} else if (mode != BUY_AND_SELL) {
builder.replaceCurrency("%price%", getSellPrice());
if (discount > 0) {
ChatColor c = VMUtils.getCodeBeforePlaceholder(ConfigManager.getStringList(lorePath), "%price%");
String prePrice = ConfigManager.getCurrencyBuilder("%price%").replaceCurrency("%price%", sellPrice).build();
String currentPrice = ConfigManager.getCurrencyBuilder("%price%").replaceCurrency("%price%", getSellPrice()).build();
builder.replace("%price%", "§m" + prePrice + c + " " + currentPrice);
} else {
builder.replaceCurrency("%price%", getSellPrice());
}
builder.replaceCurrency("%price_per_unit%", getSellPrice().divide(BigDecimal.valueOf(getAmount()), RoundingMode.HALF_UP));
} else {
boolean isCustomerMenu = path.equals("shopfront");
builder.replaceCurrency("%buy_price%", isCustomerMenu ? getSellPrice() : getBuyPrice());
builder.replaceCurrency("%sell_price%", isCustomerMenu ? getBuyPrice() : getSellPrice());
if (isAdmin && !isCustomerMenu) {
builder.replace("%price%", VMUtils.formatBuySellPrice(getBuyPrice(false), getSellPrice(false)));
} else if (discount > 0) {
String preSell = ConfigManager.getCurrencyBuilder("%price%").replaceCurrency("%price%", sellPrice).build();
String currentSell = ConfigManager.getCurrencyBuilder("%price%").replaceCurrency("%price%", getSellPrice()).build();
String preBuy = ConfigManager.getCurrencyBuilder("%price%").replaceCurrency("%price%", buyPrice).build();
String currentBuy = ConfigManager.getCurrencyBuilder("%price%").replaceCurrency("%price%", getBuyPrice()).build();

ChatColor cBuy = VMUtils.getCodeBeforePlaceholder(ConfigManager.getStringList(lorePath), "%buy_price%");
ChatColor cSell = VMUtils.getCodeBeforePlaceholder(ConfigManager.getStringList(lorePath), "%sell_price%");
builder.replace("%buy_price%", "§m" + (isCustomerMenu ? preSell : preBuy) + cBuy + " " + (isCustomerMenu ? currentSell : currentBuy));
builder.replace("%sell_price%", "§m" + (isCustomerMenu ? preBuy : preSell) + cSell + " " + (isCustomerMenu ? currentBuy : currentSell));
} else {
builder.replaceCurrency("%buy_price%", isCustomerMenu ? getSellPrice() : getBuyPrice());
builder.replaceCurrency("%sell_price%", isCustomerMenu ? getBuyPrice() : getSellPrice());
}
}
List<String> lore = builder.build();

if (discount > 0 && discountEnd != null) {
lore.addAll(ConfigManager.getListBuilder("menus.shopfront.discount_lore")
.replace("%discount%", String.valueOf(discount))
.replace("%time%", ConfigManager.getTimeLeft(discountEnd)).build());
}
if (isAdmin && limit > 0) {
int index = lore.indexOf("%limit_lore%");
if (index != -1) {
Expand Down Expand Up @@ -424,6 +464,8 @@ private String getItemName(ItemStack i) {
ItemMeta m = i.getItemMeta();
if (m != null && m.hasDisplayName()) {
return m.getDisplayName();
} else if (plugin.getLocalizedMaterial(i.getType().name()) != null) {
return plugin.getLocalizedMaterial(i.getType().name());
} else if (m != null && VersionUtils.getMCVersion() > 11 && m.hasLocalizedName()) {
return m.getLocalizedName();
} else {
Expand Down
Loading

0 comments on commit 85af0b2

Please sign in to comment.