Adds some code for displaying an item's cost
All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good

This commit is contained in:
2025-08-04 16:55:38 +02:00
parent ad5066af4b
commit 1d17239247
4 changed files with 85 additions and 76 deletions

View File

@@ -65,7 +65,7 @@
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.21.4-R0.1-SNAPSHOT</version> <version>1.21.5-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -12,6 +12,7 @@ import net.knarcraft.blacksmith.util.InputParsingHelper;
import net.knarcraft.blacksmith.util.ItemHelper; import net.knarcraft.blacksmith.util.ItemHelper;
import net.knarcraft.blacksmith.util.TypeValidationHelper; import net.knarcraft.blacksmith.util.TypeValidationHelper;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -101,9 +102,13 @@ public class BlackSmithConfigCommand implements CommandExecutor {
if (enchantment == null) { if (enchantment == null) {
return false; return false;
} }
NamespacedKey enchantmentKey = enchantment.getKeyOrNull();
if (enchantmentKey == null) {
return false;
}
BlacksmithPlugin.getStringFormatter().displaySuccessMessage(sender, BlacksmithPlugin.getStringFormatter().displaySuccessMessage(sender,
BlacksmithTranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), BlacksmithTranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(),
ItemType.ENCHANTMENT, enchantment.getKey().getKey(), ItemType.ENCHANTMENT, enchantmentKey.getKey(),
String.valueOf(settings.getEnchantmentCost(enchantment)))); String.valueOf(settings.getEnchantmentCost(enchantment))));
return true; return true;
} else { } else {

View File

@@ -2,6 +2,8 @@ package net.knarcraft.blacksmith.container;
import net.knarcraft.blacksmith.BlacksmithPlugin; import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.knarcraft.blacksmith.manager.EconomyManager; import net.knarcraft.blacksmith.manager.EconomyManager;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -68,20 +70,46 @@ public record ActionCost(double monetaryCost, int expCost, @Nullable ItemStack i
return new ActionCost(this.monetaryCost, this.expCost, this.itemCost, requiredPermissions); return new ActionCost(this.monetaryCost, this.expCost, this.itemCost, requiredPermissions);
} }
/**
* Displays this action cost as a string
*
* @param player <p>The player to calculate the cost for</p>
* @return <p>The string representation of this action cost</p>
*/
@NotNull @NotNull
public String displayCost() { public String displayCost(@NotNull Player player) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
if (monetaryCost > 0) { if (monetaryCost > 0) {
builder.append(EconomyManager.format(monetaryCost)).append(", "); builder.append(EconomyManager.format(monetaryCost)).append(", ").append("\n");
} }
if (expCost > 0) { if (expCost > 0) {
builder.append(expCost).append("exp, "); builder.append(expCost).append("exp, ").append("\n");
} }
if (itemCost != null) { if (itemCost != null) {
// TODO: Present name, amount and name + lore NamespacedKey itemName = itemCost.getType().getKeyOrNull();
builder.append(itemCost); if (itemName != null) {
builder.append(itemCost.getAmount()).append(" x ").append(itemName);
ItemMeta itemMeta = itemCost.getItemMeta();
if (itemMeta != null && itemMeta.hasDisplayName()) {
builder.append("(").append(itemMeta.getDisplayName()).append(")");
}
if (itemMeta != null && itemMeta.hasLore() && itemMeta.getLore() != null) {
for (String lore : itemMeta.getLore()) {
builder.append("\n").append(lore);
}
}
builder.append("\n");
}
}
if (!requiredPermissions().isEmpty()) {
for (String permission : requiredPermissions()) {
if (player.hasPermission(permission)) {
builder.append(ChatColor.DARK_GREEN).append("O ").append(permission).append("\n");
} else {
builder.append(ChatColor.DARK_RED).append("X ").append(permission).append("\n");
}
}
} }
// TODO: Display required permissions if the player doesn't have them?
return builder.toString(); return builder.toString();
} }

View File

@@ -1,13 +1,11 @@
package net.knarcraft.blacksmith.command; package net.knarcraft.blacksmith.util;
import net.knarcraft.blacksmith.BlacksmithPlugin; import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.knarcraft.blacksmith.container.ActionCost; import net.knarcraft.blacksmith.container.ActionCost;
import net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage; import net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage;
import net.knarcraft.blacksmith.property.CostType; import net.knarcraft.blacksmith.property.CostType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.Permission; import org.bukkit.permissions.Permission;
@@ -23,49 +21,48 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringJoiner; import java.util.StringJoiner;
public class CostCommand implements TabExecutor { /**
* A helper class for setting action costs
*/
public final class CostHelper {
private static List<String> plugins; private static List<String> plugins;
private static Map<String, List<String>> permissions; private static Map<String, List<String>> permissions;
@Override private CostHelper() {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] arguments) {
//TODO: Whenever a cost is specified (not for the per-material and per-enchantment costs), allow either a simple
// cost or an ActionCost. When loading costs, first try and parse a double. If not, parse an ActionCost object.
// TODO: The command should look like "blacksmithEdit <option> <simple|advanced> <double|economy|item|permission|exp>
// <double|blank/null|comma-separated-string|integer>"
if (!(commandSender instanceof Player player)) {
commandSender.sendMessage("This command can only be used by players");
return false;
}
//TODO: Check arguments size
if (arguments.length < 2) {
return false;
}
ActionCost oldCost = new ActionCost(0, 0, null, Set.of());
ActionCost actionCost;
switch (arguments[0].toLowerCase()) {
case "simple":
// TODO: Do something with the cost
double cost = parseSimpleCost(commandSender, arguments[1]);
break;
case "advanced":
actionCost = modifyActionCost(arguments, oldCost, player);
break;
default:
return false;
}
return false;
} }
@Override /**
public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, * Parses a simple double cost
@NotNull String s, @NotNull String[] arguments) { *
* @param commandSender <p>The command sender to notify of any problems</p>
* @param costString <p>The string to parse into a cost</p>
* @return <p>The parsed cost</p>
* @throws IllegalArgumentException <p>If the specified cost is invalid</p>
*/
public static double parseSimpleCost(@NotNull CommandSender commandSender,
@NotNull String costString) throws IllegalArgumentException {
try {
double cost = Double.parseDouble(costString);
if (cost < 0) {
throw new NumberFormatException();
}
return cost;
} catch (NumberFormatException exception) {
BlacksmithPlugin.getStringFormatter().displayErrorMessage(commandSender,
BlacksmithTranslatableMessage.DOUBLE_COST_REQUIRED);
throw new IllegalArgumentException("Invalid cost given");
}
}
/**
* Shows tab-completion actions for altering a cost
*
* @param arguments <p>The arguments given by the user</p>
* @return <p>The available tab-complete options</p>
*/
public static @Nullable List<String> tabCompleteCost(@NotNull String[] arguments) {
if (plugins == null) { if (plugins == null) {
loadAvailablePermissions(); loadAvailablePermissions();
} }
@@ -107,7 +104,9 @@ public class CostCommand implements TabExecutor {
* @param player <p>The player attempting to alter the action cost</p> * @param player <p>The player attempting to alter the action cost</p>
* @return <p>The modified action cost, or null if something went wrong</p> * @return <p>The modified action cost, or null if something went wrong</p>
*/ */
private ActionCost modifyActionCost(@NotNull String[] arguments, @NotNull ActionCost oldCost, @NotNull Player player) { @Nullable
public static ActionCost modifyActionCost(@NotNull String[] arguments, @NotNull ActionCost oldCost,
@NotNull Player player) {
CostType costType; CostType costType;
if (arguments.length > 2) { if (arguments.length > 2) {
costType = CostType.parse(arguments[2]); costType = CostType.parse(arguments[2]);
@@ -156,7 +155,7 @@ public class CostCommand implements TabExecutor {
* @return <p>The new action cost, or null if the process failed.</p> * @return <p>The new action cost, or null if the process failed.</p>
*/ */
@Nullable @Nullable
private ActionCost parseCost(@NotNull CostType costType, @NotNull String[] arguments, @NotNull ActionCost oldCost, private static ActionCost parseCost(@NotNull CostType costType, @NotNull String[] arguments, @NotNull ActionCost oldCost,
@NotNull Player player) { @NotNull Player player) {
switch (costType) { switch (costType) {
case ECONOMY: case ECONOMY:
@@ -188,36 +187,13 @@ public class CostCommand implements TabExecutor {
} }
} }
/**
* Parses a simple double cost
*
* @param commandSender <p>The command sender to notify of any problems</p>
* @param costString <p>The string to parse into a cost</p>
* @return <p>The parsed cost</p>
* @throws IllegalArgumentException <p>If the specified cost is invalid</p>
*/
private double parseSimpleCost(@NotNull CommandSender commandSender,
@NotNull String costString) throws IllegalArgumentException {
try {
double cost = Double.parseDouble(costString);
if (cost < 0) {
throw new NumberFormatException();
}
return cost;
} catch (NumberFormatException exception) {
BlacksmithPlugin.getStringFormatter().displayErrorMessage(commandSender,
BlacksmithTranslatableMessage.DOUBLE_COST_REQUIRED);
throw new IllegalArgumentException("Invalid cost given");
}
}
/** /**
* Gets the tab complete value for the permission typed * Gets the tab complete value for the permission typed
* *
* @param typedNode <p>The full permission node typed by the player</p> * @param typedNode <p>The full permission node typed by the player</p>
* @return <p>All known valid auto-complete options</p> * @return <p>All known valid auto-complete options</p>
*/ */
private @NotNull List<String> tabCompletePermission(@NotNull String typedNode) { private static @NotNull List<String> tabCompletePermission(@NotNull String typedNode) {
StringBuilder permissionListString = new StringBuilder(); StringBuilder permissionListString = new StringBuilder();
if (typedNode.contains(",")) { if (typedNode.contains(",")) {
String[] permissionList = typedNode.split(","); String[] permissionList = typedNode.split(",");
@@ -266,7 +242,7 @@ public class CostCommand implements TabExecutor {
* @param typedText <p>The text the player has started typing</p> * @param typedText <p>The text the player has started typing</p>
* @return <p>The given string values which start with the player's typed text</p> * @return <p>The given string values which start with the player's typed text</p>
*/ */
private @NotNull List<String> filterMatching(@NotNull List<String> values, @NotNull String typedText) { private static @NotNull List<String> filterMatching(@NotNull List<String> values, @NotNull String typedText) {
List<String> configValues = new ArrayList<>(); List<String> configValues = new ArrayList<>();
for (String value : values) { for (String value : values) {
if (value.toLowerCase().startsWith(typedText.toLowerCase())) { if (value.toLowerCase().startsWith(typedText.toLowerCase())) {