Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/java/com/yourname/sellplugin/SellPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.yourname.sellplugin.command.SellAllCommand;
import com.yourname.sellplugin.command.SellCommand;
import com.yourname.sellplugin.command.SellMultiCommand;
import com.yourname.sellplugin.command.FastSellAllCommand;
import com.yourname.sellplugin.command.TopSellCommand;
import com.yourname.sellplugin.command.WorthCommand;
import com.yourname.sellplugin.economy.EconomyManager;
import com.yourname.sellplugin.gui.GUIListener;
import com.yourname.sellplugin.listener.WorthPacketListener;
Expand Down Expand Up @@ -47,6 +49,8 @@ public void onEnable() {
getCommand("sellall").setExecutor(new SellAllCommand(this));
getCommand("fastsellall").setExecutor(new FastSellAllCommand(this));
getCommand("topsell").setExecutor(new TopSellCommand(this));
getCommand("sellmulti").setExecutor(new SellMultiCommand(this));
getCommand("sellworth").setExecutor(new WorthCommand(this));
getServer().getPluginManager().registerEvents(new GUIListener(this), this);

worthPacketListener = new WorthPacketListener(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public FastSellAllCommand(SellPlugin plugin) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage("Only players can use this command.");
sender.sendMessage(plugin.getConfigManager().getText("player-only-command", "&cOnly players can use this command."));
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public SellAllCommand(SellPlugin plugin) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage("Only players can use this command.");
sender.sendMessage(plugin.getConfigManager().getText("player-only-command", "&cOnly players can use this command."));
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.yourname.sellplugin.SellPlugin;
import com.yourname.sellplugin.gui.ShopMainGUI;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
Expand All @@ -20,16 +19,16 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
// Handle /sell reload
if (args.length > 0 && args[0].equalsIgnoreCase("reload")) {
if (!sender.hasPermission("sellplugin.reload")) {
sender.sendMessage(ChatColor.RED + "You do not have permission to reload the config.");
sender.sendMessage(plugin.getConfigManager().getText("reload-no-permission", "&cYou do not have permission to reload the config."));
return true;
}
plugin.getConfigManager().reload();
sender.sendMessage(ChatColor.GREEN + "SellPlugin configuration reloaded.");
sender.sendMessage(plugin.getConfigManager().getText("reload-success", "&aSellPlugin configuration reloaded."));
return true;
}

if (!(sender instanceof Player player)) {
sender.sendMessage("Only players can use this command.");
sender.sendMessage(plugin.getConfigManager().getText("player-only-command", "&cOnly players can use this command."));
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.yourname.sellplugin.command;

import com.yourname.sellplugin.SellPlugin;
import com.yourname.sellplugin.gui.SellMultiGUI;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class SellMultiCommand implements CommandExecutor {
private final SellPlugin plugin;

public SellMultiCommand(SellPlugin plugin) {
this.plugin = plugin;
}

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage(plugin.getConfigManager().getText("player-only-command", "&cOnly players can use this command."));
return true;
}

if (!player.hasPermission("sellplugin.use")) {
player.sendMessage(plugin.getConfigManager().getMessage("no-permission"));
return true;
}

new SellMultiGUI(plugin, player).open(player);
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public TopSellCommand(SellPlugin plugin) {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage("Only players can use this command.");
sender.sendMessage(plugin.getConfigManager().getText("player-only-command", "&cOnly players can use this command."));
return true;
}

Expand Down
32 changes: 32 additions & 0 deletions src/main/java/com/yourname/sellplugin/command/WorthCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.yourname.sellplugin.command;

import com.yourname.sellplugin.SellPlugin;
import com.yourname.sellplugin.gui.WorthGUI;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class WorthCommand implements CommandExecutor {
private final SellPlugin plugin;

public WorthCommand(SellPlugin plugin) {
this.plugin = plugin;
}

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage(plugin.getConfigManager().getText("player-only-command", "&cOnly players can use this command."));
return true;
}

if (!player.hasPermission("sellplugin.use")) {
player.sendMessage(plugin.getConfigManager().getMessage("no-permission"));
return true;
}

new WorthGUI(plugin, player, "all", 0).open(player);
return true;
}
}
17 changes: 10 additions & 7 deletions src/main/java/com/yourname/sellplugin/gui/CategoryItemsGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public CategoryItemsGUI(SellPlugin plugin, Player player, String categoryId, int

ConfigManager cfg = plugin.getConfigManager();
String title = cfg.getCategoryDisplayName(categoryId)
+ ChatColor.DARK_GRAY + " – Items";
+ cfg.getText("category-items.title-suffix", "&8 – Items");
this.inv = Bukkit.createInventory(this, 54, title);
populate();
}
Expand Down Expand Up @@ -121,10 +121,13 @@ private void populate() {
// ── Page indicator ─────────────────────────────────────────────────
int totalPages = Math.max(1, (int) Math.ceil((double) itemKeys.size() / ITEMS_PER_PAGE));
List<String> infoLore = Collections.singletonList(
ChatColor.GRAY + "Total items: " + itemKeys.size());
cfg.getText("category-items.total-items", "&7Total items: {count}")
.replace("{count}", String.valueOf(itemKeys.size())));
inv.setItem(SLOT_INFO, makeItem(
cfg.getIconMaterial("page-indicator", Material.PAPER),
ChatColor.WHITE + "Page " + (page + 1) + " / " + totalPages,
cfg.getText("category-items.page-indicator", "&fPage {page} / {total}")
.replace("{page}", String.valueOf(page + 1))
.replace("{total}", String.valueOf(totalPages)),
infoLore));

// ── Next page ──────────────────────────────────────────────────────
Expand All @@ -141,15 +144,15 @@ private void populate() {
double catValue = plugin.getSellManager().calculateCategoryValue(player, categoryId);
int catCount = plugin.getSellManager().countCategoryItems(player, categoryId);
List<String> sellLore = new ArrayList<>();
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("category: ")
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-items.category-label", "category: "))
+ ChatColor.WHITE + ChatColor.stripColor(cfg.getCategoryDisplayName(categoryId)));
if (catCount > 0) {
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("items: ")
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-items.items-label", "items: "))
+ ChatColor.WHITE + NumberFormatter.format(catCount));
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("earn: ")
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-items.earn-label", "earn: "))
+ ChatColor.GREEN + "$" + NumberFormatter.format(catValue));
} else {
sellLore.add(ChatColor.RED + " ▸ " + SmallCaps.convert("no items to sell."));
sellLore.add(ChatColor.RED + " ▸ " + SmallCaps.convert(cfg.getText("category-items.no-items-to-sell", "no items to sell.")));
}
inv.setItem(SLOT_SELL_ALL, makeItem(
cfg.getIconMaterial("sell-category", Material.GOLD_INGOT),
Expand Down
44 changes: 23 additions & 21 deletions src/main/java/com/yourname/sellplugin/gui/CategoryProgressGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,23 @@ private void populate() {

// ── Daily bonus indicator (slot 4, top centre) ─────────────────────
if (dailyBonus > 0) {
String separator = cfg.getText("lore-separator", "&8━━━━━━━━━━━━━━━━━━━");
List<String> boostLore = new ArrayList<>();
boostLore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
boostLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("bonus: ")
boostLore.add(separator);
boostLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.daily-boost-bonus-label", "bonus: "))
+ ChatColor.YELLOW + "+" + String.format("%.2f", dailyBonus) + "x");
boostLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("effective: ")
boostLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.daily-boost-effective-label", "effective: "))
+ ChatColor.GREEN + String.format("%.2fx", mult + dailyBonus));
boostLore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
boostLore.add(ChatColor.GRAY + SmallCaps.convert("resets at midnight."));
boostLore.add(separator);
boostLore.add(ChatColor.GRAY + SmallCaps.convert(cfg.getText("category-progress.daily-boost-resets", "resets at midnight.")));
inv.setItem(4, makeItem(Material.BLAZE_POWDER,
ChatColor.GOLD + "" + ChatColor.BOLD + "\uD83D\uDD25 " + SmallCaps.convert("Daily Boost Active!"),
SmallCaps.convert(cfg.getText("category-progress.daily-boost-title", "&6&l\uD83D\uDD25 Daily Boost Active!")),
boostLore));
}

// ── Back button (bottom-right) ──────────────────────────────────────
List<String> backLore = cfg.getIconLore("back",
Collections.singletonList(ChatColor.GRAY + " ▸ " + SmallCaps.convert("return to the main menu.")));
Collections.singletonList(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.back-lore", "return to the main menu."))));
inv.setItem(SLOT_BACK,
makeItem(cfg.getIconMaterial("back", Material.ARROW),
cfg.getIconName("back", "&c&l" + SmallCaps.convert("back")),
Expand All @@ -159,15 +160,15 @@ private void buildSnakePath(double currentMultiplier, double moneyEarned) {
if (completed) {
paneMat = cfg.getProgressBarCompletedColor();
nameColour = ChatColor.GREEN;
status = SmallCaps.convert("completed");
status = SmallCaps.convert(cfg.getText("category-progress.node-status-completed", "completed"));
} else if (inProgress) {
paneMat = cfg.getProgressBarInProgressColor();
nameColour = ChatColor.YELLOW;
status = SmallCaps.convert("in progress");
status = SmallCaps.convert(cfg.getText("category-progress.node-status-in-progress", "in progress"));
} else {
paneMat = cfg.getProgressBarLockedColor();
nameColour = ChatColor.DARK_GRAY;
status = SmallCaps.convert("locked");
status = SmallCaps.convert(cfg.getText("category-progress.node-status-locked", "locked"));
}

// First node uses the category icon instead of glass
Expand All @@ -176,28 +177,29 @@ private void buildSnakePath(double currentMultiplier, double moneyEarned) {

String label = nameColour + "" + ChatColor.BOLD
+ String.format("%.1fx", milestone)
+ " " + SmallCaps.convert("multiplier");
+ " " + SmallCaps.convert(cfg.getText("category-progress.node-multiplier-suffix", "multiplier"));

String separator = cfg.getText("lore-separator", "&8━━━━━━━━━━━━━━━━━━━");
List<String> lore = new ArrayList<>();
lore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("status: ") + nameColour + status);
lore.add(separator);
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.node-status-label", "status: ")) + nameColour + status);

if (isStart) {
lore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
lore.add(ChatColor.YELLOW + " ✦ " + SmallCaps.convert("click to view items & prices"));
lore.add(separator);
lore.add(ChatColor.YELLOW + " ✦ " + SmallCaps.convert(cfg.getText("category-progress.node-click-to-view", "click to view items & prices")));
}

if (inProgress) {
// Show cumulative money earned vs required to reach next milestone
double moneyRequired = plugin.getMultiplierManager().getCumulativeThreshold(i + 1);
if (moneyRequired > 0) {
double percentage = Math.min(100.0, (moneyEarned / moneyRequired) * 100.0);
lore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("earned: ")
lore.add(separator);
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.node-earned-label", "earned: "))
+ ChatColor.GREEN + "$" + NumberFormatter.format(moneyEarned));
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("required: ")
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.node-required-label", "required: "))
+ ChatColor.GREEN + "$" + NumberFormatter.format(moneyRequired));
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("progress: ")
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.node-progress-label", "progress: "))
+ ChatColor.YELLOW + String.format("%.1f%%", percentage));
}
}
Expand All @@ -207,9 +209,9 @@ private void buildSnakePath(double currentMultiplier, double moneyEarned) {
double moneyNeeded = plugin.getMultiplierManager().getCumulativeThreshold(i);
double remaining = Math.max(0, moneyNeeded - moneyEarned);
if (remaining > 0) {
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("need: ")
lore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("category-progress.node-need-label", "need: "))
+ ChatColor.GREEN + "$" + NumberFormatter.format(remaining)
+ ChatColor.GRAY + " " + SmallCaps.convert("more to unlock"));
+ ChatColor.GRAY + " " + SmallCaps.convert(cfg.getText("category-progress.node-need-suffix", "more to unlock")));
}
}

Expand Down
17 changes: 9 additions & 8 deletions src/main/java/com/yourname/sellplugin/gui/ConfirmSellAllGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class ConfirmSellAllGUI implements InventoryHolder {
public ConfirmSellAllGUI(SellPlugin plugin, Player player) {
ConfigManager cfg = plugin.getConfigManager();
String title = ChatColor.DARK_GRAY + "" + ChatColor.BOLD
+ SmallCaps.convert("confirm sell all");
+ SmallCaps.convert(cfg.getText("confirm-sell-all.title", "confirm sell all"));
this.inv = Bukkit.createInventory(this, SIZE, title);
populate(plugin, cfg, player);
}
Expand All @@ -50,13 +50,14 @@ private void populate(SellPlugin plugin, ConfigManager cfg, Player player) {
int itemCount = preview.itemCount;
double value = preview.value;

String separator = cfg.getText("lore-separator", "&8━━━━━━━━━━━━━━━━━━━");
List<String> infoLore = new ArrayList<>();
infoLore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
infoLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("items: ")
infoLore.add(separator);
infoLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("confirm-sell-all.items-label", "items: "))
+ ChatColor.WHITE + NumberFormatter.format(itemCount));
infoLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("value: ")
infoLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("confirm-sell-all.value-label", "value: "))
+ ChatColor.GREEN + "$" + NumberFormatter.format(value));
infoLore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
infoLore.add(separator);

inv.setItem(13, makeItem(
cfg.getIconMaterial("sell-all-info", Material.CHEST),
Expand All @@ -65,9 +66,9 @@ private void populate(SellPlugin plugin, ConfigManager cfg, Player player) {

// Confirm button
List<String> confirmLore = new ArrayList<>();
confirmLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("sell all items from your inventory."));
confirmLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert(cfg.getText("confirm-sell-all.confirm-lore", "sell all items from your inventory.")));
if (itemCount > 0) {
confirmLore.add(ChatColor.GREEN + " ▸ " + SmallCaps.convert("you will earn: $") + NumberFormatter.format(value));
confirmLore.add(ChatColor.GREEN + " ▸ " + SmallCaps.convert(cfg.getText("confirm-sell-all.confirm-earn", "you will earn: $")) + NumberFormatter.format(value));
}
inv.setItem(SLOT_CONFIRM, makeItem(
cfg.getIconMaterial("confirm", Material.LIME_STAINED_GLASS_PANE),
Expand All @@ -76,7 +77,7 @@ private void populate(SellPlugin plugin, ConfigManager cfg, Player player) {

// Cancel button
List<String> cancelLore = cfg.getIconLore("cancel",
Collections.singletonList(ChatColor.GRAY + SmallCaps.convert("go back without selling.")));
Collections.singletonList(ChatColor.GRAY + SmallCaps.convert(cfg.getText("confirm-sell-all.cancel-lore", "go back without selling."))));
inv.setItem(SLOT_CANCEL, makeItem(
cfg.getIconMaterial("cancel", Material.RED_STAINED_GLASS_PANE),
cfg.getIconName("cancel", "&c&l" + SmallCaps.convert("cancel")),
Expand Down
Loading
Loading