Clearer duel selection options

This commit is contained in:
NotAlexNoyle committed 2026-07-01 15:08:21 -04:00
1 parent ecb13f1428
commit 828239ccc5
14 files changed
+288 -44

No files matched your search

+1
View File
@@ -108,6 +108,7 @@ project(":duels-plugin") {
compileOnly("org.spigotmc:spigot-api:1.14.4-R0.1-SNAPSHOT")
compileOnly("com.mojang:authlib:1.5.21")
compileOnly("me.clip:placeholderapi:2.11.6")
compileOnly("net.luckperms:api:5.4")
compileOnly("com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT")
compileOnly("net.essentialsx:EssentialsX:2.19.2") {
@@ -185,6 +185,13 @@ public class DuelCommand extends BaseCommand {
return true;
}
// Reject a bet the opponent cannot cover so the match is not doomed to fail on start.
if (!diamondBank.has(amount, target)) {
lang.sendMessage(sender, "ERROR.command.opponent-not-enough-money",
"name", target.getName(), "max", diamondBank.getDiamonds(target), "bet_amount", amount);
return true;
}
settings.setBet(amount);
}
@@ -15,6 +15,7 @@ import me.realized.duels.gui.settings.buttons.MirrorTheirInventoryButton;
import me.realized.duels.gui.settings.buttons.OwnInventoryButton;
import me.realized.duels.gui.settings.buttons.RequestDetailsButton;
import me.realized.duels.gui.settings.buttons.RequestSendButton;
import me.realized.duels.gui.settings.buttons.ShuffleAllButton;
import me.realized.duels.util.compat.Items;
import me.realized.duels.util.gui.SinglePageGui;
import me.realized.duels.util.inventory.Slots;
@@ -22,16 +23,16 @@ import org.bukkit.inventory.ItemStack;
public class SettingsGui extends SinglePageGui<DuelsPlugin> {
// Option buttons are centered in the middle row (slots 9-16). Center is slot 13.
// Option buttons flank the middle row around the center slot 13, which is reserved for Shuffle All.
// The bottom row is reserved for SEND / CANCEL, so options never collide with them.
private static final int[][] PATTERNS = {
{13},
{12},
{12, 14},
{12, 13, 14},
{11, 12, 14},
{11, 12, 14, 15},
{11, 12, 13, 14, 15},
{10, 11, 12, 14, 15},
{10, 11, 12, 14, 15, 16},
{10, 11, 12, 13, 14, 15, 16}
{9, 10, 11, 12, 14, 15, 16}
};
public SettingsGui(final DuelsPlugin plugin) {
@@ -71,7 +72,7 @@ public class SettingsGui extends SinglePageGui<DuelsPlugin> {
buttons.add(new ItemBettingButton(plugin));
}
// Middle row: option buttons, centered. PATTERNS supports up to 7 options (the max possible).
// Middle row: option buttons flanking the center. PATTERNS supports up to 7 options (the max possible).
if (!buttons.isEmpty()) {
final int[] pattern = PATTERNS[buttons.size() - 1];
@@ -80,6 +81,9 @@ public class SettingsGui extends SinglePageGui<DuelsPlugin> {
}
}
// Center of the window: Shuffle All (randomizes every option except the Diamond bet).
set(13, new ShuffleAllButton(plugin));
// Bottom row: SEND on the left half, CANCEL on the right half, divider in the center.
set(18, 22, 1, new RequestSendButton(plugin));
set(23, 27, 1, new CancelButton(plugin));
@@ -3,6 +3,7 @@ package me.realized.duels.gui.settings.buttons;
import me.realized.duels.DuelsPlugin;
import me.realized.duels.Permissions;
import me.realized.duels.gui.BaseButton;
import me.realized.duels.hook.hooks.LuckPermsHook;
import me.realized.duels.setting.Settings;
import me.realized.duels.util.compat.Items;
import me.realized.duels.util.inventory.ItemBuilder;
@@ -21,12 +22,15 @@ public class MirrorMyInventoryButton extends BaseButton {
return;
}
// Display the request sender's (challenger's) head so it is obvious whose inventory is cloned.
// Display the request sender's (challenger's) head and rank-colored name so it is obvious whose inventory is cloned.
setOwner(player);
final String name = LuckPermsHook.coloredName(plugin, player);
setDisplayName(lang.getMessage("GUI.settings.buttons.use-mirror-my-inventory.name", "name", name));
final Settings settings = settingManager.getSafely(player);
final String value = settings.isMirrorMyInventory() ? lang.getMessage("GENERAL.enabled") : lang.getMessage("GENERAL.disabled");
final String lore = plugin.getLang().getMessage("GUI.settings.buttons.use-mirror-my-inventory.lore", "mirror_my_inventory", value);
final String lore = plugin.getLang().getMessage("GUI.settings.buttons.use-mirror-my-inventory.lore", "name", name, "mirror_my_inventory", value);
setLore(lore.split("\n"));
}
@@ -3,6 +3,7 @@ package me.realized.duels.gui.settings.buttons;
import me.realized.duels.DuelsPlugin;
import me.realized.duels.Permissions;
import me.realized.duels.gui.BaseButton;
import me.realized.duels.hook.hooks.LuckPermsHook;
import me.realized.duels.setting.Settings;
import me.realized.duels.util.compat.Items;
import me.realized.duels.util.inventory.ItemBuilder;
@@ -25,18 +26,19 @@ public class MirrorTheirInventoryButton extends BaseButton {
final Settings settings = settingManager.getSafely(player);
// Display the opponent's head so it is obvious whose inventory is cloned.
// Display the opponent's head and rank-colored name so it is obvious whose inventory is cloned.
final UUID targetId = settings.getTarget();
final Player target = targetId != null ? Bukkit.getPlayer(targetId) : null;
final String name = target != null ? LuckPermsHook.coloredName(plugin, target) : lang.getMessage("GENERAL.none");
if (targetId != null) {
final Player target = Bukkit.getPlayer(targetId);
if (target != null) {
setOwner(target);
}
if (target != null) {
setOwner(target);
}
setDisplayName(lang.getMessage("GUI.settings.buttons.use-mirror-their-inventory.name", "name", name));
final String value = settings.isMirrorTheirInventory() ? lang.getMessage("GENERAL.enabled") : lang.getMessage("GENERAL.disabled");
final String lore = plugin.getLang().getMessage("GUI.settings.buttons.use-mirror-their-inventory.lore", "mirror_their_inventory", value);
final String lore = plugin.getLang().getMessage("GUI.settings.buttons.use-mirror-their-inventory.lore", "name", name, "mirror_their_inventory", value);
setLore(lore.split("\n"));
}
@@ -2,6 +2,7 @@ package me.realized.duels.gui.settings.buttons;
import me.realized.duels.DuelsPlugin;
import me.realized.duels.gui.BaseButton;
import me.realized.duels.hook.hooks.LuckPermsHook;
import me.realized.duels.setting.Settings;
import me.realized.duels.util.compat.Items;
import me.realized.duels.util.inventory.ItemBuilder;
@@ -27,7 +28,8 @@ public class RequestDetailsButton extends BaseButton {
}
final String lore = lang.getMessage("GUI.settings.buttons.details.lore",
"opponent", target.getName(),
"opponent", LuckPermsHook.coloredName(plugin, target),
"challenger", LuckPermsHook.coloredName(plugin, player),
"kit", settings.getKit() != null ? settings.getKit().getName() : lang.getMessage("GENERAL.not-selected"),
"own_inventory", settings.isOwnInventory() ? lang.getMessage("GENERAL.enabled") : lang.getMessage("GENERAL.disabled"),
"mirror_my_inventory", settings.isMirrorMyInventory() ? lang.getMessage("GENERAL.enabled") : lang.getMessage("GENERAL.disabled"),
@@ -0,0 +1,96 @@
package me.realized.duels.gui.settings.buttons;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import me.realized.duels.DuelsPlugin;
import me.realized.duels.Permissions;
import me.realized.duels.api.kit.Kit;
import me.realized.duels.gui.BaseButton;
import me.realized.duels.kit.KitImpl;
import me.realized.duels.setting.Settings;
import me.realized.duels.util.inventory.ItemBuilder;
import org.bukkit.Material;
import org.bukkit.entity.Player;
public class ShuffleAllButton extends BaseButton {
public ShuffleAllButton(final DuelsPlugin plugin) {
super(plugin, ItemBuilder.of(Material.NETHER_STAR).name(plugin.getLang().getMessage("GUI.settings.buttons.shuffle-all.name")).build());
}
@Override
public void update(final Player player) {
setLore(lang.getMessage("GUI.settings.buttons.shuffle-all.lore").split("\n"));
}
@Override
public void onClick(final Player player) {
final Settings settings = settingManager.getSafely(player);
final ThreadLocalRandom random = ThreadLocalRandom.current();
// Randomly pick one of the enabled and permitted inventory/kit modes. They are mutually exclusive.
final List<Runnable> modes = new ArrayList<>();
if (config.isKitSelectingEnabled() && allowed(player, config.isKitSelectingUsePermission(), Permissions.KIT_SELECTING)) {
final KitImpl kit = randomKit(player, random);
if (kit != null) {
modes.add(() -> settings.setKit(kit));
}
}
if (config.isOwnInventoryEnabled() && allowed(player, config.isOwnInventoryUsePermission(), Permissions.OWN_INVENTORY)) {
modes.add(() -> settings.setOwnInventory(true));
}
if (config.isMirrorInventoryEnabled() && allowed(player, config.isMirrorInventoryUsePermission(), Permissions.MIRROR_INVENTORY)) {
modes.add(() -> settings.setMirrorMyInventory(true));
modes.add(() -> settings.setMirrorTheirInventory(true));
}
if (!modes.isEmpty()) {
modes.get(random.nextInt(modes.size())).run();
}
// Random arena for the chosen mode (null = Random, chosen when the match starts).
if (config.isArenaSelectingEnabled() && allowed(player, config.isArenaSelectingUsePermission(), Permissions.ARENA_SELECTING)) {
settings.setArena(arenaManager.randomArena(settings.getKit()));
}
// Random item betting toggle. Diamond betting is intentionally left untouched.
if (config.isItemBettingEnabled() && allowed(player, config.isItemBettingUsePermission(), Permissions.ITEM_BETTING)) {
settings.setItemBetting(random.nextBoolean());
}
settings.updateGui(player);
lang.sendMessage(player, "GUI.settings.buttons.shuffle-all.shuffled");
}
private boolean allowed(final Player player, final boolean usePermission, final String permission) {
return !usePermission || player.hasPermission(permission) || player.hasPermission(Permissions.SETTING_ALL);
}
private KitImpl randomKit(final Player player, final ThreadLocalRandom random) {
final List<KitImpl> usable = new ArrayList<>();
for (final Kit kit : kitManager.getKits()) {
final KitImpl impl = (KitImpl) kit;
if (canUseKit(player, impl)) {
usable.add(impl);
}
}
return usable.isEmpty() ? null : usable.get(random.nextInt(usable.size()));
}
private boolean canUseKit(final Player player, final KitImpl kit) {
if (!kit.isUsePermission()) {
return true;
}
final String permission = String.format(Permissions.KIT, kit.getName().replace(" ", "-").toLowerCase());
return player.hasPermission(Permissions.KIT_ALL) || player.hasPermission(permission);
}
}
@@ -9,6 +9,7 @@ import me.realized.duels.hook.hooks.EternalCombatHook;
import me.realized.duels.hook.hooks.FactionsHook;
import me.realized.duels.hook.hooks.GameModeInventoriesHook;
import me.realized.duels.hook.hooks.LeaderHeadsHook;
import me.realized.duels.hook.hooks.LuckPermsHook;
import me.realized.duels.hook.hooks.MVdWPlaceholderHook;
import me.realized.duels.hook.hooks.McMMOHook;
import me.realized.duels.hook.hooks.PlaceholderHook;
@@ -30,6 +31,7 @@ public class HookManager extends AbstractHookManager<DuelsPlugin> {
register(FactionsHook.NAME, FactionsHook.class);
register(GameModeInventoriesHook.NAME, GameModeInventoriesHook.class);
register(LeaderHeadsHook.NAME, LeaderHeadsHook.class);
register(LuckPermsHook.NAME, LuckPermsHook.class);
register(McMMOHook.NAME, McMMOHook.class);
register(MVdWPlaceholderHook.NAME, MVdWPlaceholderHook.class);
register(PlaceholderHook.NAME, PlaceholderHook.class);
@@ -67,6 +67,18 @@ public class DiamondBankHook extends PluginHook<DuelsPlugin> {
}
}
/**
* @return the whole number of Diamonds the given player can currently spend (bank + inventory), or 0 on failure.
*/
public int getDiamonds(final Player player) {
try {
return ((Number) invoke(shardsToDiamonds, totalShards(player))).intValue();
} catch (ReflectiveOperationException | RuntimeException ex) {
Log.warn("Failed to read DiamondBank-OG balance: " + ex.getMessage());
return 0;
}
}
public boolean add(final int amount, final Player... players) {
try {
final long shards = toShards(amount);
@@ -0,0 +1,55 @@
package me.realized.duels.hook.hooks;
import me.realized.duels.DuelsPlugin;
import me.realized.duels.util.StringUtil;
import me.realized.duels.util.hook.PluginHook;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.LuckPermsProvider;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class LuckPermsHook extends PluginHook<DuelsPlugin> {
public static final String NAME = "LuckPerms";
private final LuckPerms api;
public LuckPermsHook(final DuelsPlugin plugin) {
super(plugin, NAME);
this.api = LuckPermsProvider.get();
}
/**
* @return the player's name colored with the formatting of their LuckPerms prefix (e.g. their rank color).
*/
public String getColoredName(final Player player) {
return getColor(player) + player.getName();
}
private String getColor(final Player player) {
try {
final String prefix = api.getPlayerAdapter(Player.class).getMetaData(player).getPrefix();
if (prefix == null || prefix.isEmpty()) {
return "";
}
// Apply whatever color/format the prefix ends with to the name (e.g. "&c[Admin] " -> a red name).
return ChatColor.getLastColors(StringUtil.color(prefix));
} catch (final Exception ex) {
return "";
}
}
/**
* Returns the player's rank-colored name if LuckPerms is hooked, otherwise their plain name. Null-safe.
*/
public static String coloredName(final DuelsPlugin plugin, final Player player) {
if (player == null) {
return "";
}
final LuckPermsHook hook = plugin.getHookManager().getHook(LuckPermsHook.class);
return hook != null ? hook.getColoredName(player) : player.getName();
}
}
@@ -7,6 +7,7 @@ import me.realized.duels.DuelsPlugin;
import me.realized.duels.api.event.request.RequestSendEvent;
import me.realized.duels.config.Config;
import me.realized.duels.config.Lang;
import me.realized.duels.hook.hooks.LuckPermsHook;
import me.realized.duels.setting.Settings;
import me.realized.duels.util.Loadable;
import me.realized.duels.util.TextBuilder;
@@ -20,11 +21,13 @@ import org.bukkit.event.player.PlayerQuitEvent;
public class RequestManager implements Loadable, Listener {
private final DuelsPlugin plugin;
private final Config config;
private final Lang lang;
private final Map<UUID, Map<UUID, RequestImpl>> requests = new HashMap<>();
public RequestManager(final DuelsPlugin plugin) {
this.plugin = plugin;
this.config = plugin.getConfiguration();
this.lang = plugin.getLang();
Bukkit.getPluginManager().registerEvents(this, plugin);
@@ -66,13 +69,15 @@ public class RequestManager implements Loadable, Listener {
final String arena = settings.getArena() != null ? settings.getArena().getName() : lang.getMessage("GENERAL.random");
final int betAmount = settings.getBet();
final String itemBetting = settings.isItemBetting() ? lang.getMessage("GENERAL.enabled") : lang.getMessage("GENERAL.disabled");
final String challengerName = LuckPermsHook.coloredName(plugin, sender);
final String opponentName = LuckPermsHook.coloredName(plugin, target);
lang.sendMessage(sender, "COMMAND.duel.request.send.sender",
"name", target.getName(), "kit", kit,
"name", opponentName, "challenger", challengerName, "opponent", opponentName, "kit", kit,
"own_inventory", ownInventory, "mirror_my_inventory", mirrorMyInventory, "mirror_their_inventory", mirrorTheirInventory,
"arena", arena, "bet_amount", betAmount, "item_betting", itemBetting);
lang.sendMessage(target, "COMMAND.duel.request.send.receiver",
"name", sender.getName(), "kit", kit,
"name", challengerName, "challenger", challengerName, "opponent", opponentName, "kit", kit,
"own_inventory", ownInventory, "mirror_my_inventory", mirrorMyInventory, "mirror_their_inventory", mirrorTheirInventory,
"arena", arena, "bet_amount", betAmount, "item_betting", itemBetting);
@@ -22,6 +22,8 @@ public class SettingsManager implements Loadable, Listener {
private final DuelsPlugin plugin;
private final Map<UUID, Settings> cache = new HashMap<>();
private final Set<UUID> awaitingBetInput = ConcurrentHashMap.newKeySet();
// Players who have already used their single "too high" retry for the current bet-input sequence.
private final Set<UUID> betInputRetried = ConcurrentHashMap.newKeySet();
public SettingsManager(final DuelsPlugin plugin) {
this.plugin = plugin;
@@ -35,6 +37,7 @@ public class SettingsManager implements Loadable, Listener {
public void handleUnload() {
cache.clear();
awaitingBetInput.clear();
betInputRetried.clear();
}
// Only one Settings instance stays in memory while player is online; no need for manual removal of gui from GuiListener
@@ -43,9 +46,18 @@ public class SettingsManager implements Loadable, Listener {
}
public void requestBetInput(final Player player) {
// Clicking the bet button starts a fresh sequence, so the one-time retry is available again.
betInputRetried.remove(player.getUniqueId());
awaitingBetInput.add(player.getUniqueId());
player.closeInventory();
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.prompt");
final Settings settings = getSafely(player);
final Player target = settings.getTarget() != null ? Bukkit.getPlayer(settings.getTarget()) : null;
final DiamondBankHook diamondBank = plugin.getHookManager().getHook(DiamondBankHook.class);
// The maximum bet is limited by the opponent's balance, since a bet they cannot cover is rejected.
final int max = (target != null && diamondBank != null) ? diamondBank.getDiamonds(target) : 0;
final String name = target != null ? target.getName() : plugin.getLang().getMessage("GENERAL.none");
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.prompt", "name", name, "max", max);
}
@EventHandler(priority = EventPriority.LOWEST)
@@ -67,6 +79,7 @@ public class SettingsManager implements Loadable, Listener {
final UUID uuid = event.getPlayer().getUniqueId();
cache.remove(uuid);
awaitingBetInput.remove(uuid);
betInputRetried.remove(uuid);
}
private void handleBetInput(final UUID uuid, final String message) {
@@ -79,6 +92,7 @@ public class SettingsManager implements Loadable, Listener {
final Settings settings = getSafely(player);
if (message.equalsIgnoreCase("cancel")) {
betInputRetried.remove(uuid);
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.cancelled");
settings.openGui(player);
return;
@@ -87,21 +101,49 @@ public class SettingsManager implements Loadable, Listener {
final int bet = NumberUtil.parseInt(message).orElse(-1);
if (bet < 0) {
betInputRetried.remove(uuid);
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.invalid");
settings.openGui(player);
return;
}
final DiamondBankHook diamondBank = plugin.getHookManager().getHook(DiamondBankHook.class);
if (bet > 0) {
final DiamondBankHook diamondBank = plugin.getHookManager().getHook(DiamondBankHook.class);
if (bet > 0 && (diamondBank == null || !diamondBank.has(bet, player))) {
plugin.getLang().sendMessage(player, "ERROR.command.not-enough-money");
settings.openGui(player);
return;
if (diamondBank == null || !diamondBank.has(bet, player)) {
betTooHigh(player, () -> plugin.getLang().sendMessage(player, "ERROR.command.not-enough-money"));
return;
}
final Player target = settings.getTarget() != null ? Bukkit.getPlayer(settings.getTarget()) : null;
// Reject a bet the opponent cannot cover so the match is not doomed to fail on start.
if (target != null && !diamondBank.has(bet, target)) {
betTooHigh(player, () -> plugin.getLang().sendMessage(player, "ERROR.command.opponent-not-enough-money",
"name", target.getName(), "max", diamondBank.getDiamonds(target), "bet_amount", bet));
return;
}
}
betInputRetried.remove(uuid);
settings.setBet(bet);
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.set", "bet_amount", bet);
settings.openGui(player);
}
// A bet that exceeds either balance gives the player one more chance to type an amount in chat.
// Once that single retry is used, they must send a new duel request rather than reopening the GUI.
private void betTooHigh(final Player player, final Runnable reasonMessage) {
final UUID uuid = player.getUniqueId();
reasonMessage.run();
if (betInputRetried.add(uuid)) {
awaitingBetInput.add(uuid);
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.retry");
return;
}
betInputRetried.remove(uuid);
plugin.getLang().sendMessage(player, "GUI.settings.buttons.diamond-bet.retry-failed");
}
}
+30 -18
View File
@@ -63,7 +63,7 @@ ERROR:
target: '{PREFIX} &c%name% is already in a duel.'
already-in-queue: '{PREFIX} &cYou cannot do this while in a queue.'
prevent-teleportation: '{PREFIX} &cCannot teleport to a player in a duel.'
mode-unselected: '{PREFIX} &cChoose a kit or enable one of: Each Uses Own Inventory, Both Use My Inventory, Both Use Their Inventory.'
mode-unselected: '{PREFIX} &cChoose a kit or enable an inventory option (each their own, yours, or your opponent''s).'
mode-fixed: '{PREFIX} &cYou are not allowed to change inventory mode here.'
spectate:
already-spectating:
@@ -95,6 +95,7 @@ ERROR:
invalid-option: '{PREFIX} &c''%option%'' is not a valid option. Available options are: %available_options%'
invalid-action: '{PREFIX} &c''%action%'' is not a valid action. Available actions are: %available_actions%'
not-enough-money: '{PREFIX} &cYou do not have enough Diamonds to bet!'
opponent-not-enough-money: '{PREFIX} &c%name% only has %max% Diamond(s) and cannot cover a bet of &B%bet_amount% Diamond(s)&c.'
lobby-save-failure: '{PREFIX} &cCould not save lobby location. Please check the console for more information.'
name-not-alphanumeric: '{PREFIX} &c''%name%'' is not alphanumeric.'
@@ -114,21 +115,21 @@ COMMAND:
send:
sender:
- '{LINE}'
- '&7Duel request sent to &4%name%&7.'
- '&7Duel request sent to %opponent%&7.'
- '&6- &7Kit: &d%kit%'
- '&6- &7Each Uses Own Inventory: &r%own_inventory%'
- '&6- &7Both Use My Inventory: &r%mirror_my_inventory%'
- '&6- &7Both Use Their Inventory: &r%mirror_their_inventory%'
- '&6- &7Both Use %challenger%&7''s Inventory: &r%mirror_my_inventory%'
- '&6- &7Both Use %opponent%&7''s Inventory: &r%mirror_their_inventory%'
- '&6- &7Arena: &e%arena%'
- '&6- &7Bet: &B%bet_amount% Diamond(s)'
- '{LINE}'
receiver:
- '{LINE}'
- '&7Duel request received from &4%name%&7.'
- '&7Duel request received from %challenger%&7.'
- '&6- &7Kit: &d%kit%'
- '&6- &7Each Uses Own Inventory: &r%own_inventory%'
- '&6- &7Both Use My Inventory: &r%mirror_my_inventory%'
- '&6- &7Both Use Their Inventory: &r%mirror_their_inventory%'
- '&6- &7Both Use %challenger%&7''s Inventory: &r%mirror_my_inventory%'
- '&6- &7Both Use %opponent%&7''s Inventory: &r%mirror_their_inventory%'
- '&6- &7Arena: &e%arena%'
- '&6- &7Bet: &B%bet_amount% Diamond(s)'
clickable-text:
@@ -293,7 +294,7 @@ COMMAND:
DUEL:
start-failure:
mode-unselected: '{FAIL_PREFIX} &cChoose a kit or enable one of: Each Uses Own Inventory, Both Use My Inventory, Both Use Their Inventory.'
mode-unselected: '{FAIL_PREFIX} &cChoose a kit or enable an inventory option (each their own, yours, or your opponent''s).'
player-is-dead: '{FAIL_PREFIX} You or your opponent is not alive!'
in-blacklisted-world: '{FAIL_PREFIX} You or your opponent is in a blacklisted world!'
is-tagged: '{FAIL_PREFIX} You or your opponent is in combat!'
@@ -357,11 +358,11 @@ GUI:
details:
name: '&9Request Details'
lore:
- '&7Opponent: &4%opponent%'
- '&7Opponent: %opponent%'
- '&7Kit: &d%kit%'
- '&7Each Uses Own Inventory: &r%own_inventory%'
- '&7Both Use My Inventory: &r%mirror_my_inventory%'
- '&7Both Use Their Inventory: &r%mirror_their_inventory%'
- '&7Both Use %challenger%&7''s Inventory: &r%mirror_my_inventory%'
- '&7Both Use %opponent%&7''s Inventory: &r%mirror_their_inventory%'
- '&7Arena: &e%arena%'
- '&7Bet: &B%bet_amount% Diamond(s)'
kit-selector:
@@ -389,11 +390,11 @@ GUI:
- '&cYou do not have permission to'
- '&cuse this option.'
use-mirror-my-inventory:
name: '&bBoth Use My Inventory &7(Your Head)'
name: '&bBoth Use %name%&b''s Inventory'
lore:
- '&7Both duelists fight with a CLONE of'
- '&7YOUR inventory and armor (the challenger).'
- '&7You both get the same gear: yours.'
- '&7%name%&7''s inventory and armor (you, the challenger).'
- '&7You both get the same gear.'
- '&7Originals are restored after the match.'
- ' '
- '&7Currently: &r%mirror_my_inventory%'
@@ -402,11 +403,11 @@ GUI:
- '&cYou do not have permission to'
- '&cuse this option.'
use-mirror-their-inventory:
name: '&eBoth Use Their Inventory &7(Opponent Head)'
name: '&eBoth Use %name%&e''s Inventory'
lore:
- '&7Both duelists fight with a CLONE of'
- '&7the OPPONENT''s inventory and armor.'
- '&7You both get the same gear: theirs.'
- '&7%name%&7''s inventory and armor (your opponent).'
- '&7You both get the same gear.'
- '&7Originals are restored after the match.'
- ' '
- '&7Currently: &r%mirror_their_inventory%'
@@ -429,8 +430,10 @@ GUI:
- '&7Bet: &B%bet_amount% Diamond(s)'
- ' '
- '&aClick to enter a bet amount.'
prompt: '{PREFIX} &7Type the Diamond bet amount in chat, or type &ccancel &7to keep the current amount.'
prompt: '{PREFIX} &7Type the Diamond bet amount in chat, or type &ccancel &7to keep the current amount. &7Max bet vs &4%name%&7: &B%max% Diamond(s) &7(their balance).'
invalid: '{PREFIX} &cPlease enter a whole number of Diamonds.'
retry: '{PREFIX} &7Type a lower Diamond bet in chat, or type &ccancel&7. &cThis is your last try before you must send a new duel request.'
retry-failed: '{PREFIX} &cThat bet is still too high. Send a new duel request to try betting again.'
cancelled: '{PREFIX} &7Diamond bet unchanged.'
set: '{PREFIX} &7Diamond bet set to &B%bet_amount% Diamond(s)&7.'
lore-no-permission:
@@ -445,6 +448,15 @@ GUI:
lore-no-permission:
- '&cYou do not have permission to'
- '&cuse this option.'
shuffle-all:
name: '&d&lShuffle All'
lore:
- '&7Randomly picks an inventory mode,'
- '&7arena, and item betting for you.'
- '&7Your Diamond bet is left unchanged.'
- ' '
- '&aClick to shuffle!'
shuffled: '{PREFIX} &7Randomized all settings except your Diamond bet.'
send:
name: '&a&lSEND REQUEST'
cancel:
+1 -1
View File
@@ -1,7 +1,7 @@
name: Duels-OG
main: me.realized.duels.DuelsPlugin
version: @VERSION@
softdepend: [BetterChairs-OG, CombatLogX, CombatTagPlus, DiamondBank-OG, Essentials, EternalCombat, Factions, GameModeInventories-OG, LeaderHeads, mcMMO, MVdWPlaceholderAPI, MyWorlds, PlaceholderAPI, ProtocolLib, PvPManager, SimpleClans, WorldGuard]
softdepend: [BetterChairs-OG, CombatLogX, CombatTagPlus, DiamondBank-OG, Essentials, EternalCombat, Factions, GameModeInventories-OG, LeaderHeads, LuckPerms, mcMMO, MVdWPlaceholderAPI, MyWorlds, PlaceholderAPI, ProtocolLib, PvPManager, SimpleClans, WorldGuard]
# MyWorlds added as soft-depend due to locations being null when Duels is loaded before managed worlds.
# Add any world management plugins to softdepend list if arena doesn't load properly in the generated world.
api-version: 1.14