Add bounty increase workflow and refine bounty head messaging #14
No files matched your search
@@ -20,6 +20,7 @@ import com.tcoded.playerbountiesplus.hook.logging.CoreProtectHook;
|
||||
import com.tcoded.playerbountiesplus.hook.currency.EconomyHook;
|
||||
import com.tcoded.playerbountiesplus.hook.team.TeamHook;
|
||||
import com.tcoded.playerbountiesplus.listener.BountyHeadListener;
|
||||
import com.tcoded.playerbountiesplus.listener.BountyIncreasePromptListener;
|
||||
import com.tcoded.playerbountiesplus.listener.DeathListener;
|
||||
import com.tcoded.playerbountiesplus.listener.GuiProtectionListener;
|
||||
import com.tcoded.playerbountiesplus.manager.BountyDataManager;
|
||||
@@ -65,6 +66,8 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
// CoreProtect API hook.
|
||||
private CoreProtectHook coreProtectHook;
|
||||
|
||||
private BountyIncreasePromptListener bountyIncreasePromptListener;
|
||||
|
||||
public PlayerBountiesOG() {
|
||||
|
||||
instance = this;
|
||||
@@ -157,8 +160,11 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
// Listeners.
|
||||
this.getServer().getPluginManager().registerEvents(new DeathListener(this, this.diamondBankAPI, this.luckPerms),
|
||||
this);
|
||||
this.bountyIncreasePromptListener = new BountyIncreasePromptListener(this);
|
||||
|
||||
this.getServer().getPluginManager().registerEvents(
|
||||
new BountyHeadListener(this, this.diamondBankAPI, this.luckPerms, this.coreProtectHook), this);
|
||||
this.getServer().getPluginManager().registerEvents(this.bountyIncreasePromptListener, this);
|
||||
this.getServer().getPluginManager().registerEvents(new GuiProtectionListener(this), this);
|
||||
|
||||
final List<Plugin> plugins = ImmutableList.copyOf(this.getServer().getPluginManager().getPlugins());
|
||||
@@ -230,6 +236,12 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
|
||||
}
|
||||
|
||||
public BountyIncreasePromptListener getBountyIncreasePromptListener() {
|
||||
|
||||
return this.bountyIncreasePromptListener;
|
||||
|
||||
}
|
||||
|
||||
// Utilities.
|
||||
private static void findPluginWithQuery(List<Plugin> plugins, String pluginNameQuery, String... excludeStrings) {
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.command.bounty.BountyCheckCmd;
|
||||
import com.tcoded.playerbountiesplus.command.bounty.BountyAddCmd;
|
||||
import com.tcoded.playerbountiesplus.command.bounty.BountySetCmd;
|
||||
import com.tcoded.playerbountiesplus.command.bounty.BountyTopCmd;
|
||||
|
||||
@@ -69,6 +70,12 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
}
|
||||
|
||||
case "add" -> {
|
||||
|
||||
return BountyAddCmd.handleCmd(plugin, sender, cmd, cmdName, args);
|
||||
|
||||
}
|
||||
|
||||
case "top" -> {
|
||||
|
||||
return BountyTopCmd.handleCmd(plugin, diamondBankAPI, sender, cmd, cmdName, args);
|
||||
@@ -99,7 +106,7 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
if (args.length == 1) {
|
||||
|
||||
return Lists.newArrayList("set", "top", "check").stream()
|
||||
return Lists.newArrayList("set", "add", "top", "check").stream()
|
||||
.filter(action -> StringUtils.startsWith(action, StringUtils.lowerCase(args[0])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -112,6 +119,10 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
.onTabComplete(sender, args).stream().filter(suggestion -> StringUtils
|
||||
.startsWith(StringUtils.lowerCase(suggestion), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
case "add" -> BountyAddCmd
|
||||
.onTabComplete(sender, args).stream().filter(suggestion -> StringUtils
|
||||
.startsWith(StringUtils.lowerCase(suggestion), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
case "check" -> BountyCheckCmd
|
||||
.onTabComplete(sender, args).stream().filter(suggestion -> StringUtils
|
||||
.startsWith(StringUtils.lowerCase(suggestion), StringUtils.lowerCase(args[1])))
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
package com.tcoded.playerbountiesplus.command.bounty;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.manager.BountyDataManager;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
||||
import net.luckperms.api.model.user.User;
|
||||
import net.trueog.diamondbankog.DiamondBankException.EconomyDisabledException;
|
||||
import net.trueog.diamondbankog.DiamondBankException.InsufficientFundsException;
|
||||
import net.trueog.diamondbankog.DiamondBankException.InvalidPlayerException;
|
||||
import net.trueog.diamondbankog.DiamondBankException.PlayerNotOnlineException;
|
||||
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class BountyAddCmd {
|
||||
|
||||
public static boolean handleCmd(PlayerBountiesOG plugin, CommandSender sender, Command cmd, String cmdName,
|
||||
String[] args)
|
||||
{
|
||||
|
||||
if (!(sender instanceof Player player)) {
|
||||
|
||||
UtilitiesOG.logToConsole(PlayerBountiesOG.getPrefix(), "&cERROR: Only players can use this command.");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (!sender.hasPermission("playerbountiesplus.command.bounty.add")) {
|
||||
|
||||
final String noPerm = plugin.getLang().getColored("command.no-permission");
|
||||
final String noPermDetailed = plugin.getLang().getColored("command.no-permission-detailed")
|
||||
.replace("{no-permission-msg}", noPerm)
|
||||
.replace("{permission}", "playerbountiesplus.command.bounty.add");
|
||||
UtilitiesOG.trueogMessage(player, noPermDetailed);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (args.length < 3) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, plugin.getLang().getColored("command.bounty.add.missing-args"));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final String targetNameArg = args[1];
|
||||
final double amount;
|
||||
try {
|
||||
|
||||
amount = parseAmount(args[2]);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, plugin.getLang().getColored("command.bounty.add.amount-nan"));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final OfflinePlayer target = Bukkit.getOfflinePlayer(targetNameArg);
|
||||
if (target.getUniqueId() == null) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, plugin.getLang().getColored("command.bounty.add.player-not-found"));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return addBounty(plugin, player, target.getUniqueId(), target.getName(), amount, true);
|
||||
|
||||
}
|
||||
|
||||
public static boolean addBounty(PlayerBountiesOG plugin, Player setter, UUID targetUuid, String targetName,
|
||||
double parsedAmount, boolean saveData)
|
||||
{
|
||||
|
||||
final String safeTargetName = StringUtils.defaultIfBlank(targetName,
|
||||
Bukkit.getOfflinePlayer(targetUuid).getName());
|
||||
if (safeTargetName == null || safeTargetName.isBlank()) {
|
||||
|
||||
UtilitiesOG.trueogMessage(setter, plugin.getLang().getColored("command.bounty.add.player-not-found"));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final DiamondBankAPIJava diamondBankAPI = resolveDiamondBankApi(plugin);
|
||||
|
||||
final double minimum = plugin.getConfig().getDouble("bounty-minimum", 1.0);
|
||||
if (parsedAmount < minimum) {
|
||||
|
||||
UtilitiesOG.trueogMessage(setter, plugin.getLang().getColored("command.bounty.set.under-minimum")
|
||||
.replace("{minimum}", String.valueOf(minimum)));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final double maximum = plugin.getConfig().getDouble("bounty-maximum", 1000000.0);
|
||||
if (parsedAmount > maximum) {
|
||||
|
||||
UtilitiesOG.trueogMessage(setter,
|
||||
plugin.getLang().getColored("command.bounty.set.over-maximum").replace("{maximum}",
|
||||
String.valueOf(maximum)));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final long addedShards = diamondBankAPI.diamondsToShards((float) parsedAmount);
|
||||
if (addedShards <= 0L) {
|
||||
|
||||
UtilitiesOG.trueogMessage(setter, plugin.getLang().getColored("command.bounty.set.internal-invalid-value"));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (!chargeSetter(plugin, setter, diamondBankAPI, safeTargetName, addedShards)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final BountyDataManager bountyDataManager = plugin.getBountyDataManager();
|
||||
final long existingShards = diamondBankAPI.diamondsToShards((float) bountyDataManager.getBounty(targetUuid));
|
||||
final long totalShards = existingShards + addedShards;
|
||||
final double totalBounty = Double.parseDouble(diamondBankAPI.shardsToDiamonds(totalShards));
|
||||
|
||||
bountyDataManager.setBounty(targetUuid, totalBounty);
|
||||
|
||||
final LuckPerms luckPerms = resolveLuckPerms(plugin);
|
||||
final String setterDisplay = formatLuckPermsDisplay(luckPerms, setter);
|
||||
final String targetDisplay = resolveLuckPermsDisplayName(luckPerms, targetUuid, safeTargetName);
|
||||
final String addedDisplay = diamondBankAPI.shardsToDiamonds(addedShards);
|
||||
final String totalDisplay = diamondBankAPI.shardsToDiamonds(totalShards);
|
||||
|
||||
UtilitiesOG.trueogMessage(setter, plugin.getLang().getColored("command.bounty.add.success")
|
||||
.replace("{amount}", addedDisplay).replace("{target}", targetDisplay).replace("{total}", totalDisplay));
|
||||
|
||||
if (plugin.getConfig().getBoolean("bounty-placed-announce", true)) {
|
||||
|
||||
final String announce = plugin.getLang().getColored("command.bounty.add.announce").replace("{amount}",
|
||||
addedDisplay).replace("{target}", targetDisplay).replace("{total}", totalDisplay)
|
||||
.replace("{player}", setterDisplay);
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(player -> UtilitiesOG.trueogMessage(player, PlayerBountiesOG.getPrefix()
|
||||
+ "&a" + announce));
|
||||
|
||||
}
|
||||
|
||||
if (saveData) {
|
||||
|
||||
bountyDataManager.saveBountiesAsync();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private static boolean chargeSetter(PlayerBountiesOG plugin, Player setter, DiamondBankAPIJava diamondBankAPI,
|
||||
String targetName, long addedShards)
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
diamondBankAPI.consumeFromPlayer(setter.getUniqueId(), addedShards,
|
||||
"Player " + setter.getName() + " contributed " + diamondBankAPI.shardsToDiamonds(addedShards)
|
||||
+ " Diamonds toward a bounty on " + targetName + ".",
|
||||
"Plugin: PlayerBounties-OG");
|
||||
|
||||
return true;
|
||||
|
||||
} catch (EconomyDisabledException economyDisabledException) {
|
||||
|
||||
PlayerBountiesOG.disableSelf(
|
||||
"[PlayerBounties-OG] DiamondBank-OG economy disabled: " + economyDisabledException.getMessage());
|
||||
return false;
|
||||
|
||||
} catch (InvalidPlayerException invalidPlayerException) {
|
||||
|
||||
plugin.getLogger().warning("Invalid player for consumeFromPlayer: " + setter.getName());
|
||||
UtilitiesOG.trueogMessage(setter,
|
||||
"&cERROR: your player account could not be found by DiamondBank-OG. Contact an administrator!");
|
||||
return false;
|
||||
|
||||
} catch (InsufficientFundsException insufficientFundsException) {
|
||||
|
||||
UtilitiesOG.trueogMessage(setter, plugin.getLang().getColored("command.bounty.set.not-enough-money"));
|
||||
return false;
|
||||
|
||||
}
|
||||
// TODO: Remove PlayerNotOnlineException catch block after next DiamondBank-OG update.
|
||||
catch (PlayerNotOnlineException temporaryPlayerNotOnlineError) {
|
||||
|
||||
plugin.getLogger().warning("Player " + setter.getName()
|
||||
+ " not online when attempting to consumeFromPlayer. This error is expected to be removed in the next DiamondBank-OG update.");
|
||||
temporaryPlayerNotOnlineError.printStackTrace();
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static double parseAmount(String amountInput) {
|
||||
|
||||
if (!amountInput.matches("^\\d+(?:\\.\\d)?$")) {
|
||||
|
||||
throw new NumberFormatException("Invalid amount format");
|
||||
|
||||
}
|
||||
|
||||
return Double.parseDouble(amountInput);
|
||||
|
||||
}
|
||||
|
||||
private static DiamondBankAPIJava resolveDiamondBankApi(PlayerBountiesOG plugin) {
|
||||
|
||||
final RegisteredServiceProvider<DiamondBankAPIJava> provider = plugin.getServer().getServicesManager()
|
||||
.getRegistration(DiamondBankAPIJava.class);
|
||||
|
||||
if (provider == null) {
|
||||
|
||||
throw new IllegalStateException("DiamondBank-OG API is null");
|
||||
|
||||
}
|
||||
|
||||
return provider.getProvider();
|
||||
|
||||
}
|
||||
|
||||
private static LuckPerms resolveLuckPerms(PlayerBountiesOG plugin) {
|
||||
|
||||
final RegisteredServiceProvider<LuckPerms> provider = plugin.getServer().getServicesManager()
|
||||
.getRegistration(LuckPerms.class);
|
||||
|
||||
if (provider == null) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return provider.getProvider();
|
||||
|
||||
}
|
||||
|
||||
private static String resolveLuckPermsDisplayName(LuckPerms luckPerms, UUID playerId, String playerName) {
|
||||
|
||||
final String safeName = StringUtils.defaultIfBlank(playerName, "Unknown Player");
|
||||
if (luckPerms == null) {
|
||||
|
||||
return "&f" + safeName;
|
||||
|
||||
}
|
||||
|
||||
final User user = luckPerms.getUserManager().getUser(playerId);
|
||||
if (user == null) {
|
||||
|
||||
return "&f" + safeName;
|
||||
|
||||
}
|
||||
|
||||
final CachedMetaData meta = user.getCachedData().getMetaData();
|
||||
final String prefix = StringUtils.trim(StringUtils.defaultString(meta.getPrefix()).replace('§', '&'));
|
||||
final String suffix = StringUtils.trim(StringUtils.defaultString(meta.getSuffix()).replace('§', '&'));
|
||||
final boolean metaContainsName = containsVisibleName(prefix, safeName) || containsVisibleName(suffix, safeName);
|
||||
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (!prefix.isBlank()) {
|
||||
|
||||
out.append(prefix).append(' ');
|
||||
|
||||
}
|
||||
|
||||
if (!metaContainsName) {
|
||||
|
||||
out.append(safeName);
|
||||
|
||||
}
|
||||
|
||||
if (!suffix.isBlank()) {
|
||||
|
||||
out.append(' ').append(suffix);
|
||||
|
||||
}
|
||||
|
||||
return sanitizeDisplay(out.toString(), safeName);
|
||||
|
||||
}
|
||||
|
||||
private static String formatLuckPermsDisplay(LuckPerms luckPerms, Player player) {
|
||||
|
||||
return resolveLuckPermsDisplayName(luckPerms, player.getUniqueId(), player.getName());
|
||||
|
||||
}
|
||||
|
||||
private static String sanitizeDisplay(String formatted, String fallbackName) {
|
||||
|
||||
final String cleaned = StringUtils.trimToEmpty(formatted).replaceAll("(?i)(?:\\s*(?:<reset>|[&§]r))+$", "")
|
||||
.replaceAll("\\s*>$", "");
|
||||
|
||||
if (cleaned.isBlank()) {
|
||||
|
||||
return fallbackName;
|
||||
|
||||
}
|
||||
|
||||
return cleaned;
|
||||
|
||||
}
|
||||
|
||||
private static boolean containsVisibleName(String text, String playerName) {
|
||||
|
||||
if (text == null || playerName == null || playerName.isBlank()) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
final String normalizedText = stripFormatting(text).toLowerCase(Locale.ROOT);
|
||||
final String normalizedName = playerName.toLowerCase(Locale.ROOT);
|
||||
|
||||
return normalizedText.contains(normalizedName);
|
||||
|
||||
}
|
||||
|
||||
private static String stripFormatting(String input) {
|
||||
|
||||
if (input == null || input.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return input.replaceAll("(?i)[&§][0-9A-FK-ORX]", "").replaceAll("<[^>]+>", "").trim();
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> onTabComplete(@NotNull CommandSender sender, @NotNull String[] args) {
|
||||
|
||||
if (args.length == 2) {
|
||||
|
||||
return sender.getServer().getOnlinePlayers().stream().map(Player::getName)
|
||||
.filter(name -> StringUtils.startsWith(StringUtils.lowerCase(name), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} else if (args.length == 3) {
|
||||
|
||||
return Collections.singletonList("<amount>");
|
||||
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -314,17 +314,17 @@ public class BountySetCmd {
|
||||
|
||||
if (prefix.isBlank()) {
|
||||
|
||||
return player.getName();
|
||||
return player.getName().replaceAll("\\s*>$", "");
|
||||
|
||||
}
|
||||
|
||||
if (leadingColorCodes.isBlank()) {
|
||||
|
||||
return prefix + " " + player.getName();
|
||||
return (prefix + " " + player.getName()).replaceAll("\\s*>$", "");
|
||||
|
||||
}
|
||||
|
||||
return prefix + " " + leadingColorCodes + player.getName();
|
||||
return (prefix + " " + leadingColorCodes + player.getName()).replaceAll("\\s*>$", "");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ public class BountyTopCmd {
|
||||
private static String sanitizeDisplay(String formatted, String fallbackName) {
|
||||
|
||||
final String cleaned = StringUtils.trimToEmpty(formatted).replaceAll("(?i)(?:\\s*(?:<reset>|[&§]r))+$", "")
|
||||
.replaceAll("\\s+>", " >").replaceAll("\\s*>$", "");
|
||||
.replaceAll("\\s*>$", "");
|
||||
|
||||
if (cleaned.isBlank()) {
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -16,6 +18,7 @@ import net.trueog.diamondbankog.api.DiamondBankAPIJava;
|
||||
import net.trueog.gxui.GUIBase;
|
||||
import net.trueog.gxui.GUIButton;
|
||||
import net.trueog.gxui.GUIItem;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class MainBountyGui extends GUIBase {
|
||||
|
||||
@@ -246,6 +249,8 @@ public class MainBountyGui extends GUIBase {
|
||||
final ArrayList<String> lore = new ArrayList<>();
|
||||
|
||||
lore.add("&eBounty: &b" + formatBounty(entry.bountyDiamonds()));
|
||||
lore.add("&7Click to increase this player's bounty.");
|
||||
lore.add("&8You will be prompted in chat for the amount.");
|
||||
lore.add("");
|
||||
lore.add("&6Claiming the bounty will give you a 50% chance of beheading your victim!");
|
||||
|
||||
@@ -261,12 +266,66 @@ public class MainBountyGui extends GUIBase {
|
||||
}
|
||||
|
||||
item.lore(lore);
|
||||
item.setButton(new GUIButton()
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean leftClick() {
|
||||
|
||||
return promptIncrease(entry);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean leftClickShift() {
|
||||
|
||||
return promptIncrease(entry);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rightClick() {
|
||||
|
||||
return promptIncrease(entry);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rightClickShift() {
|
||||
|
||||
return promptIncrease(entry);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
item.setPlayErrorSound(false);
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
private boolean promptIncrease(BountyGuiEntry entry) {
|
||||
|
||||
if (entry.targetUuid() == null) {
|
||||
|
||||
UtilitiesOG.trueogMessage(viewer, plugin.getLang().getColored("command.bounty.add.player-not-found"));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final String targetName = StringUtils.defaultIfBlank(entry.targetName(), "Unknown Player");
|
||||
plugin.getBountyIncreasePromptListener().prompt(viewer.getUniqueId(), entry.targetUuid(), targetName);
|
||||
|
||||
final String promptMessage = plugin.getLang().getColored("command.bounty.add.prompt")
|
||||
.replace("{target}", safeDisplayName(entry.displayName()));
|
||||
UtilitiesOG.trueogMessage(viewer, promptMessage);
|
||||
|
||||
viewer.closeInventory();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private String formatBounty(double bountyDiamonds) {
|
||||
|
||||
final long shards = diamondBankAPI.diamondsToShards(bountyDiamonds);
|
||||
|
||||
@@ -17,7 +17,9 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
@@ -184,6 +186,40 @@ public class BountyHeadListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryHover(InventoryClickEvent event) {
|
||||
|
||||
if (!(event.getWhoClicked() instanceof Player player)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final ItemStack currentItem = event.getCurrentItem();
|
||||
if (currentItem == null || !isHeadMaterial(currentItem.getType())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
sendBountyHeadActionbar(player, currentItem.getItemMeta());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onHotbarScroll(PlayerItemHeldEvent event) {
|
||||
|
||||
final ItemStack newSlotItem = event.getPlayer().getInventory().getItem(event.getNewSlot());
|
||||
if (newSlotItem == null || !isHeadMaterial(newSlotItem.getType())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
sendBountyHeadActionbar(event.getPlayer(), newSlotItem.getItemMeta());
|
||||
|
||||
}
|
||||
|
||||
private void sendBountyHeadActionbar(Player player, ItemMeta itemMeta) {
|
||||
|
||||
if (itemMeta == null) {
|
||||
@@ -211,14 +247,14 @@ public class BountyHeadListener implements Listener {
|
||||
final UUID uuid = parseUuid(targetUuid);
|
||||
final String playerDisplay = formatLuckPermsDisplay(uuid, targetName);
|
||||
final String diamonds = formatDiamonds(bountyAmount);
|
||||
player.sendActionBar(
|
||||
UtilitiesOG.trueogColorize("&cBounty Head: " + playerDisplay + " &7- &b" + diamonds + " &bDiamonds"));
|
||||
player.sendActionBar(UtilitiesOG.trueogColorize("&c" + playerDisplay + "'s Head &7- &b" + diamonds
|
||||
+ " &bDiamonds"));
|
||||
|
||||
}
|
||||
|
||||
private void applyBountyData(SkullMeta meta, String targetName, String targetUuid, double bountyAmount) {
|
||||
|
||||
meta.displayName(UtilitiesOG.trueogColorize("&c" + targetName + "'s Bounty Head"));
|
||||
meta.displayName(UtilitiesOG.trueogColorize("&c" + targetName + "'s Head"));
|
||||
|
||||
final UUID uuid = parseUuid(targetUuid);
|
||||
final String playerDisplay = formatLuckPermsDisplay(uuid, targetName);
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.tcoded.playerbountiesplus.listener;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.command.bounty.BountyAddCmd;
|
||||
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class BountyIncreasePromptListener implements Listener {
|
||||
|
||||
private final PlayerBountiesOG plugin;
|
||||
private final Map<UUID, PendingIncreasePrompt> pendingPrompts = new ConcurrentHashMap<>();
|
||||
|
||||
public BountyIncreasePromptListener(PlayerBountiesOG plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
public void prompt(UUID setterUuid, UUID targetUuid, String targetName) {
|
||||
|
||||
pendingPrompts.put(setterUuid, new PendingIncreasePrompt(targetUuid, targetName));
|
||||
|
||||
}
|
||||
|
||||
public boolean hasPrompt(UUID setterUuid) {
|
||||
|
||||
return pendingPrompts.containsKey(setterUuid);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onChat(AsyncPlayerChatEvent event) {
|
||||
|
||||
final PendingIncreasePrompt prompt = pendingPrompts.get(event.getPlayer().getUniqueId());
|
||||
if (prompt == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
final String input = StringUtils.trimToEmpty(event.getMessage());
|
||||
if (input.equalsIgnoreCase("cancel")) {
|
||||
|
||||
pendingPrompts.remove(event.getPlayer().getUniqueId());
|
||||
UtilitiesOG.trueogMessage(event.getPlayer(), plugin.getLang().getColored("command.bounty.add.cancelled"));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final double amount;
|
||||
try {
|
||||
|
||||
if (!input.matches("^\\d+(?:\\.\\d)?$")) {
|
||||
|
||||
throw new NumberFormatException("Invalid amount format");
|
||||
|
||||
}
|
||||
|
||||
amount = Double.parseDouble(input);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
|
||||
UtilitiesOG.trueogMessage(event.getPlayer(), plugin.getLang().getColored("command.bounty.add.amount-nan"));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
pendingPrompts.remove(event.getPlayer().getUniqueId());
|
||||
plugin.getServer().getScheduler().runTask(plugin,
|
||||
() -> BountyAddCmd.addBounty(plugin, event.getPlayer(), prompt.targetUuid(), prompt.targetName(), amount,
|
||||
true));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
|
||||
pendingPrompts.remove(event.getPlayer().getUniqueId());
|
||||
|
||||
}
|
||||
|
||||
private static record PendingIncreasePrompt(UUID targetUuid, String targetName) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -256,7 +256,7 @@ public class DeathListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
return StringUtils.trim(out.toString()).replaceAll("\\s*>$", "");
|
||||
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ public class DeathListener implements Listener {
|
||||
|
||||
final PlayerProfile profile = Bukkit.createProfile(victim.getUniqueId());
|
||||
headMeta.setPlayerProfile(profile);
|
||||
headMeta.displayName(UtilitiesOG.trueogColorize("&c" + victim.getName() + "'s Bounty Head"));
|
||||
headMeta.displayName(UtilitiesOG.trueogColorize("&c" + victim.getName() + "'s Head"));
|
||||
final String bountyDisplay = formatDiamonds(bounty);
|
||||
headMeta.lore(java.util.List.of(
|
||||
Component.text("Target: ", NamedTextColor.GRAY)
|
||||
@@ -400,7 +400,7 @@ public class DeathListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
return StringUtils.trim(out.toString()).replaceAll("\\s*>$", "");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ command:
|
||||
player-not-found: "&cThat player is not online or doesn't exist!"
|
||||
success: "&a{target} currently has a bounty of {bounty}."
|
||||
bounty:
|
||||
no-action: "&cYou need to specify an action! /bounty <set/top/check>"
|
||||
no-action: "&cYou need to specify an action! /bounty <set/add/top/check>"
|
||||
invalid-action: "&cThat's not a valid action!"
|
||||
set:
|
||||
missing-args: "&cYou need to specify a player and an amount! /bounty set <player> <amount>"
|
||||
@@ -49,6 +49,14 @@ command:
|
||||
success: "&cYou placed a bounty of {bounty} on {target}'s head!"
|
||||
announce: "\nA bounty of {bounty} was placed on {target}'s &ahead by&r {player}!{extra}\n"
|
||||
announce-extra: " (Total: {total})"
|
||||
add:
|
||||
missing-args: "&cYou need to specify a player and an amount! /bounty add <player> <amount>"
|
||||
amount-nan: "&cThat's not a valid number!"
|
||||
player-not-found: "&cThat player could not be found!"
|
||||
success: "&aYou increased {target}'s bounty by {amount}. Total: {total}."
|
||||
announce: "\n{player} increased {target}'s bounty by {amount}&a! &7(Total: &b{total}&7)\n"
|
||||
prompt: "&eType how many diamonds to add to {target}'s bounty in chat. Type &ccancel &eto abort."
|
||||
cancelled: "&cBounty increase cancelled."
|
||||
check:
|
||||
no-player-specified: "&cYou need to specify a player! /bounty check <player>"
|
||||
player-not-found: "&cThat player is not online or doesn't exist!"
|
||||
|
||||
@@ -36,5 +36,7 @@ permissions:
|
||||
playerbountiesplus.command.admin.bounty.delete: {}
|
||||
playerbountiesplus.command.bounty.set:
|
||||
default: true
|
||||
playerbountiesplus.command.bounty.add:
|
||||
default: true
|
||||
playerbountiesplus.event.claim:
|
||||
default: true
|
||||
Reference in new issue
Block a user