Finished adding confirm button

Fixed controlling gui from player inventory
This commit is contained in:
Teriuihi 2022-01-10 22:36:25 +01:00
parent f8dccf5645
commit b7e8ba74b5
7 changed files with 187 additions and 84 deletions

View File

@ -1,63 +1,80 @@
package com.alttd.GUI;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.TradeSelectEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantInventory;
public class GUIListener implements Listener {
private static ItemStack air = new ItemStack(Material.AIR);
/**
* Handles clicking inside a gui
* @param event gui click event
*/
@EventHandler
public void onClick(InventoryClickEvent event){
if (!(event.getWhoClicked() instanceof Player player)){
return;
}
if (!(event.getWhoClicked() instanceof Player player)) return;
GUI gui = GUI.GUIByUUID.get(player.getUniqueId());
if (gui == null || gui.getInventory() == null)
return;
if (!gui.getInventory().equals(event.getInventory()))
return;
if (gui == null) return;
if (gui.getInventory() != null) {
if (!gui.getInventory().equals(event.getInventory())) return;
} else if (gui instanceof GUIMerchant) {
HumanEntity trader = gui.getMerchant().getTrader();
if (trader == null || !trader.equals(player)) return;
} else return;
event.setCancelled(true);
Inventory clickedInventory = event.getClickedInventory();
if (clickedInventory == null || clickedInventory.getType().equals(InventoryType.PLAYER)) return;
GUIAction action = gui.getGuiAction(event.getSlot());
if (action != null){
action.click(player);
}
if (action != null) action.click(player);
}
@EventHandler
public void onTradeSelect(TradeSelectEvent event) {
if (!(event.getWhoClicked() instanceof Player player)){
return;
}
if (!(event.getWhoClicked() instanceof Player player)) return;
GUI gui = GUI.GUIByUUID.get(player.getUniqueId());
if ((!(gui instanceof GUIMerchant guiMerchant)))
return;
if (!gui.getMerchant().equals(event.getMerchant())) {
return;
}
if ((!(gui instanceof GUIMerchant guiMerchant))) return;
if (!gui.getMerchant().equals(event.getMerchant())) return;
event.setCancelled(true);
GUIAction action = guiMerchant.getTradeAction(event.getIndex());
gui.setMerchantInventory(event.getInventory());
if (action != null){
action.click(player);
}
if (action != null) action.click(player);
}
@EventHandler
public void onClose(InventoryCloseEvent event) {
if (!(event.getInventory() instanceof MerchantInventory merchantInventory)) return;
HumanEntity player = event.getPlayer();
GUI gui = GUI.GUIByUUID.get(player.getUniqueId());
if (!(gui instanceof GUIMerchant)) return;
HumanEntity trader = gui.getMerchant().getTrader();
if (trader == null || !trader.equals(player)) return;
merchantInventory.setItem(0, air);
merchantInventory.setItem(1, air);
GUI.GUIByUUID.remove(event.getPlayer().getUniqueId());
}

View File

@ -7,8 +7,10 @@ import com.alttd.config.WorthConfig;
import com.alttd.events.SpawnShopEvent;
import com.alttd.objects.EconUser;
import com.alttd.objects.Price;
import com.alttd.objects.Purchase;
import com.alttd.objects.VillagerType;
import com.alttd.util.Utilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.Template;
import net.kyori.adventure.text.minimessage.template.TemplateResolver;
@ -20,6 +22,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@ -32,7 +35,7 @@ public class BuyGUI extends GUIMerchant {
static {
ItemStack itemStack = new ItemStack(Material.EMERALD_BLOCK);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(MiniMessage.miniMessage().deserialize("<green>Confirm</green>"));
itemMeta.displayName(MiniMessage.miniMessage().deserialize(Config.CONFIRM_BUTTON));
itemStack.setItemMeta(itemMeta);
confirm = itemStack;
}
@ -60,72 +63,93 @@ public class BuyGUI extends GUIMerchant {
}
private void buy(VillagerType villagerType, Player player, Material material, int amount, Price price) {
Economy econ = VillagerUI.getInstance().getEconomy();
double balance = econ.getBalance(player);
int itemPts = (int) (Math.floor(price.getPrice(1) / WorthConfig.POINT_MOD) + 1);
int transPts = itemPts * amount;
EconUser econUser = EconUser.getUser(player.getUniqueId());
int oldPoints = Objects.requireNonNullElse(econUser.getPointsMap().get(villagerType.getName()), 0);
double cost = price.calculatePriceThing(oldPoints, transPts, true, itemPts);
if (balance < cost) {
player.sendMiniMessage(Config.NOT_ENOUGH_MONEY, List.of(
Template.template("money", String.valueOf(Utilities.round(balance, 2))),
Template.template("price", String.valueOf(cost))
));
return;
}
Purchase purchase = new Purchase(material, cost, itemPts, transPts, amount);
ItemStack itemStack = new ItemStack(Material.CANDLE);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(miniMessage.deserialize(String.valueOf(cost)));
itemStack.setItemMeta(itemMeta);
setItem(0, new ItemStack(material), null);
setItem(1, new ItemStack(Material.CANDLE), null);
setItem(2, confirm, player1 ->
buy2(player1, amount, cost, material, econUser, villagerType, transPts, oldPoints, price));
setItem(0, getBuyItemHover(purchase), null);
setItem(1, confirm, player1 ->
buy2(player1, purchase, econUser, villagerType, oldPoints, price));
player.updateInventory();
}
private void buy2(Player player, int amount, double cost, Material material, EconUser econUser, VillagerType villagerType, int transPts, int oldPoints, Price price) {
private void buy2(Player player, Purchase purchase, EconUser econUser, VillagerType villagerType, int oldPoints, Price price) {
Economy econ = VillagerUI.getInstance().getEconomy();
var ref = new Object() {
int space = 0;
};
Arrays.stream(player.getInventory().getContents())
.filter(itemStack -> itemStack == null || itemStack.getType().equals(material))
.forEach(itemStack -> {
if (itemStack == null)
ref.space += material.getMaxStackSize();
else
ref.space += itemStack.getMaxStackSize() - itemStack.getAmount();
});
if (ref.space < amount) {
player.sendMiniMessage(Config.NOT_ENOUGH_SPACE, List.of(
Template.template("space", String.valueOf(ref.space)),
Template.template("amount", String.valueOf(amount))
double balance = econ.getBalance(player);
if (balance < purchase.price()) {
player.sendMiniMessage(Config.NOT_ENOUGH_MONEY, List.of(
Template.template("money", String.valueOf(Utilities.round(balance, 2))),
Template.template("price", String.valueOf(purchase.price()))
));
return;
}
econ.withdrawPlayer(player, cost);
econUser.addPoints(villagerType.getName(), transPts);
player.getInventory().addItem(new ItemStack(material, amount));
var ref = new Object() {
int space = 0;
};
Arrays.stream(player.getInventory().getContents())
.filter(itemStack -> itemStack == null || itemStack.getType().equals(purchase.material()))
.forEach(itemStack -> {
if (itemStack == null)
ref.space += purchase.material().getMaxStackSize();
else
ref.space += itemStack.getMaxStackSize() - itemStack.getAmount();
});
if (ref.space < purchase.amount()) {
player.sendMiniMessage(Config.NOT_ENOUGH_SPACE, List.of(
Template.template("space", String.valueOf(ref.space)),
Template.template("amount", String.valueOf(purchase.amount()))
));
return;
}
econ.withdrawPlayer(player, purchase.price());
econUser.addPoints(villagerType.getName(), purchase.totalPointCost());
player.getInventory().addItem(new ItemStack(purchase.material(), purchase.amount()));
int newPoints = econUser.getPointsMap().get(villagerType.getName());
player.sendMiniMessage(Config.PURCHASED_ITEM, List.of(
Template.template("amount", String.valueOf(amount)),
Template.template("item", StringUtils.capitalize(material.name()
Template.template("amount", String.valueOf(purchase.amount())),
Template.template("item", StringUtils.capitalize(purchase.material().name()
.toLowerCase().replaceAll("_", " "))),
Template.template("price", "-" + cost),
Template.template("points", String.valueOf(transPts)),
Template.template("price", "-" + purchase.price()),
Template.template("points", String.valueOf(purchase.totalPointCost())),
Template.template("total_points", String.valueOf(newPoints)),
Template.template("villager_name", villagerType.getDisplayName())
));
Bukkit.getServer().getPluginManager()
.callEvent(new SpawnShopEvent(player, amount, cost, material,
.callEvent(new SpawnShopEvent(player, purchase,
oldPoints, newPoints, true));
buy(villagerType, player, material, amount, price);
buy(villagerType, player, purchase.material(), purchase.amount(), price);
}
private ItemStack getBuyItemHover(Purchase purchase) {
ItemStack itemStack = new ItemStack(purchase.material());
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(miniMessage.deserialize(Config.TRANSACTION_ITEM_NAME, TemplateResolver.resolving(
Template.template("item_name", purchase.material().name())
)));
List<Component> lore = new ArrayList<>();
for (String entry : Config.TRANSACTION_ITEM_DESCRIPTION) {
lore.add(miniMessage.deserialize(entry, TemplateResolver.resolving(
Template.template("amount", String.valueOf(purchase.amount())),
Template.template("price", String.valueOf(purchase.price())),
Template.template("points", String.valueOf(purchase.totalPointCost()))
)));
}
itemMeta.lore(lore);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
private ItemStack getPriceItem(double price) {

View File

@ -7,8 +7,10 @@ import com.alttd.config.WorthConfig;
import com.alttd.events.SpawnShopEvent;
import com.alttd.objects.EconUser;
import com.alttd.objects.Price;
import com.alttd.objects.Purchase;
import com.alttd.objects.VillagerType;
import com.alttd.util.Utilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.Template;
import net.kyori.adventure.text.minimessage.template.TemplateResolver;
@ -23,6 +25,7 @@ import org.bukkit.inventory.MerchantInventory;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@ -30,6 +33,15 @@ import java.util.Objects;
public class SellGUI extends GUIMerchant {
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private static final ItemStack confirm;
static {
ItemStack itemStack = new ItemStack(Material.EMERALD_BLOCK);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(MiniMessage.miniMessage().deserialize(Config.CONFIRM_BUTTON));
itemStack.setItemMeta(itemMeta);
confirm = itemStack;
}
public SellGUI(VillagerType villagerType, EconUser econUser, boolean bulk) {
super(MiniMessage.miniMessage().deserialize(Config.SELL_WINDOW, TemplateResolver.resolving(
@ -55,44 +67,73 @@ public class SellGUI extends GUIMerchant {
private void sell(VillagerType villagerType, Player player, Material material, int amount, Price price, boolean bulk) {
PlayerInventory inventory = player.getInventory();
if (!inventory.containsAtLeast(new ItemStack(material), bulk ? 1 : amount)) {
player.sendMiniMessage(Config.NOT_ENOUGH_ITEMS, List.of(
Template.template("type", material.name()),
Template.template("amount", String.valueOf(bulk ? 1 : amount))));
return;
}
if (bulk)
amount = Arrays.stream(inventory.getContents())
.filter(Objects::nonNull)
.filter(itemStack -> itemStack.getType().equals(material))
.mapToInt(ItemStack::getAmount).sum();
Economy econ = VillagerUI.getInstance().getEconomy();
EconUser econUser = EconUser.getUser(player.getUniqueId());
int oldPoints = Objects.requireNonNullElse(econUser.getPointsMap().get(villagerType.getName()), 0);
int itemPts = (int) (Math.floor(price.getPrice(1) / WorthConfig.POINT_MOD) + 1);
int transPts = (itemPts * amount) * -1;
double cost = price.calculatePriceThing(oldPoints, transPts, false, itemPts);
econ.depositPlayer(player, cost);
econUser.addPoints(villagerType.getName(), transPts);
Purchase purchase = new Purchase(material, cost, itemPts, transPts, amount);
setItem(0, getSellItemHover(purchase), null);
setItem(1, confirm, player1 ->
sell2(player1, purchase, econUser, villagerType, oldPoints, price, bulk));
player.updateInventory();
}
removeItems(inventory, material, amount);
private void sell2(Player player, Purchase purchase, EconUser econUser, VillagerType villagerType, int oldPoints, Price price, boolean bulk) {
PlayerInventory inventory = player.getInventory();
if (!inventory.containsAtLeast(new ItemStack(purchase.material()), purchase.amount())) {
player.sendMiniMessage(Config.NOT_ENOUGH_ITEMS, List.of(
Template.template("type", purchase.material().name()),
Template.template("amount", String.valueOf(purchase.amount()))));
return;
}
Economy econ = VillagerUI.getInstance().getEconomy();
econ.depositPlayer(player, purchase.price());
econUser.addPoints(villagerType.getName(), purchase.totalPointCost());
removeItems(inventory, purchase.material(), purchase.amount());
int newPoints = econUser.getPointsMap().get(villagerType.getName());
player.sendMiniMessage(Config.SOLD_ITEM, List.of(
Template.template("amount", String.valueOf(amount)),
Template.template("item", StringUtils.capitalize(material.name()
Template.template("amount", String.valueOf(purchase.amount())),
Template.template("item", StringUtils.capitalize(purchase.material().name()
.toLowerCase().replaceAll("_", " "))),
Template.template("price", String.valueOf(cost)),
Template.template("points", String.valueOf(transPts)),
Template.template("price", String.valueOf(purchase.price())),
Template.template("points", String.valueOf(purchase.totalPointCost())),
Template.template("total_points", String.valueOf(newPoints)),
Template.template("villager_name", villagerType.getDisplayName())
));
Bukkit.getServer().getPluginManager()
.callEvent(new SpawnShopEvent(player, amount, cost, material,
oldPoints, newPoints, false));
.callEvent(new SpawnShopEvent(player, purchase, oldPoints, newPoints, false));
sell(villagerType, player, purchase.material(), bulk ? 1 : purchase.amount(), price, bulk);
}
private ItemStack getSellItemHover(Purchase purchase) {
ItemStack itemStack = new ItemStack(purchase.material());
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(miniMessage.deserialize(Config.TRANSACTION_ITEM_NAME, TemplateResolver.resolving(
Template.template("item_name", purchase.material().name())
)));
List<Component> lore = new ArrayList<>();
for (String entry : Config.TRANSACTION_ITEM_DESCRIPTION) {
lore.add(miniMessage.deserialize(entry, TemplateResolver.resolving(
Template.template("amount", String.valueOf(purchase.amount())),
Template.template("price", String.valueOf(purchase.price())),
Template.template("points", String.valueOf(purchase.totalPointCost()))
)));
}
itemMeta.lore(lore);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
private void removeItems(Inventory inventory, Material material, int amount) {

View File

@ -104,6 +104,11 @@ abstract class AbstractConfig {
return yaml.getList(path, yaml.getList(path));
}
List<String> getStringList(String path, List<String> def) {
yaml.addDefault(path, def);
return yaml.getStringList(path);
}
@NonNull
<T> Map<String, T> getMap(final @NonNull String path, final @Nullable Map<String, T> def) {
final ImmutableMap.Builder<String, T> builder = ImmutableMap.builder();

View File

@ -8,6 +8,7 @@ import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public final class Config extends AbstractConfig {
@ -76,9 +77,18 @@ public final class Config extends AbstractConfig {
}
public static String VILLAGER_NAME = "<green><name></green>";
public static String CONFIRM_BUTTON = "<green>Confirm</green>";
public static String TRANSACTION_ITEM_NAME = "<green><item_name></green>";
public static List<String> TRANSACTION_ITEM_DESCRIPTION = List.of(
"<gold>Amount: <dark_aqua><amount></dark_aqua></gold>",
"<gold>Price: <dark_aqua><price></dark_aqua></gold>",
"<gold>Points: <dark_aqua><points></dark_aqua></gold>");
private static void loadIDKYET() {//TODO rename
VILLAGER_NAME = config.getString("idkyet.villager-name", VILLAGER_NAME); //TODO change path
private static void guiText() {
VILLAGER_NAME = config.getString("gui-text.villager-name", VILLAGER_NAME);
CONFIRM_BUTTON = config.getString("gui-text.confirm-button", CONFIRM_BUTTON);
TRANSACTION_ITEM_NAME = config.getString("gui-text.transaction-item-name", TRANSACTION_ITEM_NAME);
TRANSACTION_ITEM_DESCRIPTION = config.getStringList("gui-text.transaction-item-description", TRANSACTION_ITEM_DESCRIPTION);
}
public static String NOT_ENOUGH_MONEY = "<red>You only have $<money>, you need at least $<price> for this purchase.</red>";

View File

@ -1,5 +1,6 @@
package com.alttd.events;
import com.alttd.objects.Purchase;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
@ -16,12 +17,11 @@ public final class SpawnShopEvent extends Event {
private final boolean buy;
private static final HandlerList handlers = new HandlerList();
public SpawnShopEvent(Player player, int amount, double price, Material item,
int pointsBefore, int pointsAfter, boolean buy) {
public SpawnShopEvent(Player player, Purchase purchase, int pointsBefore, int pointsAfter, boolean buy) {
this.player = player;
this.amount = amount;
this.price = price;
this.item = item;
this.amount = purchase.amount();
this.price = purchase.price();
this.item = purchase.material();
this.pointsBefore = pointsBefore;
this.pointsAfter = pointsAfter;
this.buy = buy;

View File

@ -0,0 +1,6 @@
package com.alttd.objects;
import org.bukkit.Material;
public record Purchase(Material material, double price, int singlePointCost, int totalPointCost, int amount) {
}