Adds tons of changes to messages

This commit is contained in:
Kristian Knarvik 2022-09-29 01:49:12 +02:00
parent 3cfa7a2a0a
commit a6e9163dbd
18 changed files with 458 additions and 95 deletions

View File

@ -4,7 +4,12 @@ import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.knarcraft.blacksmith.config.GlobalSetting; import net.knarcraft.blacksmith.config.GlobalSetting;
import net.knarcraft.blacksmith.config.GlobalSettings; import net.knarcraft.blacksmith.config.GlobalSettings;
import net.knarcraft.blacksmith.config.NPCSetting; import net.knarcraft.blacksmith.config.NPCSetting;
import org.bukkit.ChatColor; import net.knarcraft.blacksmith.config.SettingValueType;
import net.knarcraft.blacksmith.manager.ItemType;
import net.knarcraft.blacksmith.manager.Message;
import net.knarcraft.blacksmith.util.InputParsingHelper;
import net.knarcraft.blacksmith.util.MessageFormatter;
import net.knarcraft.blacksmith.util.TypeValidationHelper;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -13,6 +18,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static net.knarcraft.blacksmith.util.MessageFormatter.displayErrorMessage;
import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;
/** /**
* The command used for changing global configuration options * The command used for changing global configuration options
*/ */
@ -33,7 +41,7 @@ public class BlackSmithConfigCommand implements CommandExecutor {
//Changing reforge-able items' default isn't recommended //Changing reforge-able items' default isn't recommended
if (commandName.equalsIgnoreCase(NPCSetting.REFORGE_ABLE_ITEMS.getCommandName())) { if (commandName.equalsIgnoreCase(NPCSetting.REFORGE_ABLE_ITEMS.getCommandName())) {
sender.sendMessage(ChatColor.DARK_RED + "Changing reforge-able items globally will make every new " + displayErrorMessage(sender, "Changing reforge-able items globally will make every new " +
"blacksmith unable to re-forge anything not in the list, unless it's changed for the " + "blacksmith unable to re-forge anything not in the list, unless it's changed for the " +
"individual NPC. If you really want to change this, change it manually."); "individual NPC. If you really want to change this, change it manually.");
return false; return false;
@ -58,27 +66,36 @@ public class BlackSmithConfigCommand implements CommandExecutor {
} }
if (args.length == 1) { if (args.length == 1) {
//TODO: See if there's a way to remove this duplication
if (detectedGlobalSetting != null) { if (detectedGlobalSetting != null) {
sender.sendMessage(String.format("Current value of %s: %s", detectedGlobalSetting.getCommandName(), displaySuccessMessage(sender, Message.getCurrentValueMessage(detectedGlobalSetting.getCommandName(),
settings.getRawValue(detectedGlobalSetting))); MessageFormatter.escapeColorCodes(String.valueOf(settings.getRawValue(detectedGlobalSetting)))));
} else if (detectedNPCSetting != null) {
sender.sendMessage(String.format("Current value of %s: %s", detectedNPCSetting.getCommandName(),
settings.getRawValue(detectedNPCSetting)));
}
return true; return true;
} else if (detectedNPCSetting != null) {
displaySuccessMessage(sender, Message.getCurrentValueMessage(detectedNPCSetting.getCommandName(),
MessageFormatter.escapeColorCodes(String.valueOf(settings.getRawValue(detectedNPCSetting)))));
return true;
} else {
return false;
}
} else if (args.length == 2 && isSpecialCase(commandName)) { } else if (args.length == 2 && isSpecialCase(commandName)) {
return displaySpecialCaseValue(args[1], sender, detectedGlobalSetting, settings); if (displaySpecialCaseValue(args[1], sender, detectedGlobalSetting, settings)) {
return true;
}
} }
if (updateSpecialCase(settings, commandName, args)) { if (args.length == 3 && updateSpecialCase(settings, detectedGlobalSetting, args, sender)) {
return true; return true;
} }
String newValue = args[1];
if (detectedGlobalSetting != null) { if (detectedGlobalSetting != null) {
settings.changeValue(detectedGlobalSetting, args[1]); settings.changeValue(detectedGlobalSetting, newValue);
displaySuccessMessage(sender, Message.getValueChangedMessage(detectedGlobalSetting.getCommandName(), newValue));
return true; return true;
} else if (detectedNPCSetting != null) { } else if (detectedNPCSetting != null) {
settings.changeValue(detectedNPCSetting, args[1]); settings.changeValue(detectedNPCSetting, newValue);
displaySuccessMessage(sender, Message.getValueChangedMessage(detectedNPCSetting.getNodeName(), newValue));
return true; return true;
} }
return false; return false;
@ -95,31 +112,32 @@ public class BlackSmithConfigCommand implements CommandExecutor {
*/ */
private boolean displaySpecialCaseValue(String selector, CommandSender sender, GlobalSetting setting, private boolean displaySpecialCaseValue(String selector, CommandSender sender, GlobalSetting setting,
GlobalSettings settings) { GlobalSettings settings) {
if (setting == GlobalSetting.BASE_PRICE || setting == GlobalSetting.PRICE_PER_DURABILITY_POINT) {
Material material = Material.matchMaterial(selector);
if (material == null) {
return false;
}
String currentValue;
if (setting == GlobalSetting.BASE_PRICE) { if (setting == GlobalSetting.BASE_PRICE) {
Material material = Material.matchMaterial(selector); currentValue = String.valueOf(settings.getBasePrice(material));
if (material == null) { } else {
return false; currentValue = String.valueOf(settings.getPricePerDurabilityPoint(material));
} }
sender.sendMessage(String.format("Current value of %s for material %s: %s", setting.getCommandName(), displaySuccessMessage(sender, Message.getItemCurrentValueMessage(setting.getCommandName(), ItemType.MATERIAL,
material, settings.getBasePrice(material))); material.name(), currentValue));
return true; return true;
} else if (setting == GlobalSetting.PRICE_PER_DURABILITY_POINT) {
Material material = Material.matchMaterial(selector);
if (material == null) {
return false;
}
sender.sendMessage(String.format("Current value of %s for material %s: %s", setting.getCommandName(),
material, settings.getPricePerDurabilityPoint(material)));
} else if (setting == GlobalSetting.ENCHANTMENT_COST) { } else if (setting == GlobalSetting.ENCHANTMENT_COST) {
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(selector)); Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(selector));
if (enchantment == null) { if (enchantment == null) {
return false; return false;
} }
sender.sendMessage(String.format("Current value of %s for enchantment %s: %s", setting.getCommandName(), displaySuccessMessage(sender, Message.getItemCurrentValueMessage(setting.getCommandName(), ItemType.ENCHANTMENT,
enchantment, settings.getEnchantmentCost(enchantment))); enchantment.toString(), String.valueOf(settings.getEnchantmentCost(enchantment))));
} return true;
} else {
return false; return false;
} }
}
/** /**
* Gets whether a command name matches a special case command * Gets whether a command name matches a special case command
@ -137,39 +155,49 @@ public class BlackSmithConfigCommand implements CommandExecutor {
* Updates a special-case configuration value if a special-case is encountered * Updates a special-case configuration value if a special-case is encountered
* *
* @param settings <p>The settings to modify</p> * @param settings <p>The settings to modify</p>
* @param commandName <p>The sub-command the player specified</p> * @param detectedGlobalSetting <p>The global setting specified</p>
* @param args <p>All arguments given</p> * @param args <p>All arguments given</p>
* @param sender <p>The command sender to notify if successful</p>
* @return <p>True if already handled as a special case</p> * @return <p>True if already handled as a special case</p>
*/ */
private boolean updateSpecialCase(GlobalSettings settings, String commandName, String[] args) { private boolean updateSpecialCase(GlobalSettings settings, GlobalSetting detectedGlobalSetting, String[] args,
if (commandName.equalsIgnoreCase(GlobalSetting.BASE_PRICE.getCommandName())) { CommandSender sender) {
Material material = Material.matchMaterial(args[1]); if (!TypeValidationHelper.isValid(SettingValueType.POSITIVE_DOUBLE, args[2], sender)) {
return true;
}
double newPrice = Double.parseDouble(args[2]);
String itemChanged;
ItemType itemType;
String newValue = String.valueOf(newPrice);
if (detectedGlobalSetting == GlobalSetting.BASE_PRICE ||
detectedGlobalSetting == GlobalSetting.PRICE_PER_DURABILITY_POINT) {
Material material = InputParsingHelper.matchMaterial(args[1]);
if (material == null) { if (material == null) {
return false; return false;
} }
settings.setBasePrice(material, Double.parseDouble(args[2])); itemType = ItemType.MATERIAL;
return true; itemChanged = material.name();
if (detectedGlobalSetting == GlobalSetting.BASE_PRICE) {
settings.setBasePrice(material, newPrice);
} else {
settings.setPricePerDurabilityPoint(material, newPrice);
} }
} else if (detectedGlobalSetting == GlobalSetting.ENCHANTMENT_COST) {
if (commandName.equalsIgnoreCase(GlobalSetting.PRICE_PER_DURABILITY_POINT.getCommandName())) { Enchantment enchantment = InputParsingHelper.matchEnchantment(args[1]);
Material material = Material.matchMaterial(args[1]);
if (material == null) {
return false;
}
settings.setPricePerDurabilityPoint(material, Double.parseDouble(args[2]));
return true;
}
if (commandName.equalsIgnoreCase(GlobalSetting.ENCHANTMENT_COST.getCommandName())) {
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(args[1]));
if (enchantment == null) { if (enchantment == null) {
return false; return false;
} }
settings.setEnchantmentCost(enchantment, Double.parseDouble(args[2])); itemType = ItemType.ENCHANTMENT;
return true; itemChanged = enchantment.toString();
} settings.setEnchantmentCost(enchantment, newPrice);
} else {
return false; return false;
} }
displaySuccessMessage(sender, Message.getItemValueChangedMessage(detectedGlobalSetting.getCommandName(),
itemType, itemChanged, newValue));
return true;
}
} }

View File

@ -2,8 +2,7 @@ package net.knarcraft.blacksmith.command;
import net.knarcraft.blacksmith.config.GlobalSetting; import net.knarcraft.blacksmith.config.GlobalSetting;
import net.knarcraft.blacksmith.config.NPCSetting; import net.knarcraft.blacksmith.config.NPCSetting;
import net.knarcraft.blacksmith.util.TabCompleteValuesHelper; import net.knarcraft.blacksmith.config.SettingValueType;
import net.knarcraft.blacksmith.util.TabCompletionHelper;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
@ -13,6 +12,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.knarcraft.blacksmith.util.TabCompleteValuesHelper.getTabCompletions;
import static net.knarcraft.blacksmith.util.TabCompletionHelper.filterMatchingContains;
/** /**
* The tab completer for the command used for changing global configuration options * The tab completer for the command used for changing global configuration options
*/ */
@ -35,7 +37,7 @@ public class BlackSmithConfigTabCompleter implements TabCompleter {
for (GlobalSetting globalSetting : GlobalSetting.values()) { for (GlobalSetting globalSetting : GlobalSetting.values()) {
availableCommands.add(globalSetting.getCommandName()); availableCommands.add(globalSetting.getCommandName());
} }
return TabCompletionHelper.filterMatchingContains(availableCommands, args[0]); return filterMatchingContains(availableCommands, args[0]);
} else if (args.length == 2) { } else if (args.length == 2) {
return tabCompleteCommandValues(args[0], args[1]); return tabCompleteCommandValues(args[0], args[1]);
} }
@ -55,17 +57,33 @@ public class BlackSmithConfigTabCompleter implements TabCompleter {
} }
for (GlobalSetting globalSetting : GlobalSetting.values()) { for (GlobalSetting globalSetting : GlobalSetting.values()) {
if (globalSetting.getCommandName().equalsIgnoreCase(commandName)) { if (globalSetting.getCommandName().equalsIgnoreCase(commandName)) {
return TabCompletionHelper.filterMatchingContains(TabCompleteValuesHelper.getTabCompletions( return getCompletions(globalSetting, commandValue);
globalSetting.getValueType()), commandValue);
} }
} }
for (NPCSetting npcSetting : NPCSetting.values()) { for (NPCSetting npcSetting : NPCSetting.values()) {
if (npcSetting.getCommandName().equalsIgnoreCase(commandName)) { if (npcSetting.getCommandName().equalsIgnoreCase(commandName)) {
return TabCompletionHelper.filterMatchingContains(TabCompleteValuesHelper.getTabCompletions( return filterMatchingContains(getTabCompletions(
npcSetting.getValueType()), commandValue); npcSetting.getValueType()), commandValue);
} }
} }
return null; return null;
} }
/**
* Gets tab-completions for the given global setting and filters on the command value
*
* @param globalSetting <p>The global setting to get tab-completions for</p>
* @param commandValue <p>The command value used to filter between available tab-completions</p>
* @return <p>The available tab-completions</p>
*/
private List<String> getCompletions(GlobalSetting globalSetting, String commandValue) {
List<String> returnValues = filterMatchingContains(getTabCompletions(globalSetting.getValueType()), commandValue);
if (globalSetting == GlobalSetting.BASE_PRICE || globalSetting == GlobalSetting.PRICE_PER_DURABILITY_POINT) {
returnValues.addAll(filterMatchingContains(getTabCompletions(SettingValueType.MATERIAL), commandValue));
} else if (globalSetting == GlobalSetting.ENCHANTMENT_COST) {
returnValues.addAll(filterMatchingContains(getTabCompletions(SettingValueType.ENCHANTMENT), commandValue));
}
return returnValues;
}
} }

View File

@ -3,7 +3,9 @@ package net.knarcraft.blacksmith.command;
import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.blacksmith.config.NPCSetting; import net.knarcraft.blacksmith.config.NPCSetting;
import net.knarcraft.blacksmith.manager.Message;
import net.knarcraft.blacksmith.trait.BlacksmithTrait; import net.knarcraft.blacksmith.trait.BlacksmithTrait;
import net.knarcraft.blacksmith.util.MessageFormatter;
import net.knarcraft.blacksmith.util.TypeValidationHelper; import net.knarcraft.blacksmith.util.TypeValidationHelper;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -11,6 +13,8 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;
/** /**
* The main command used for blacksmith editing * The main command used for blacksmith editing
*/ */
@ -21,10 +25,14 @@ public class BlackSmithEditCommand implements CommandExecutor {
@NotNull String[] args) { @NotNull String[] args) {
NPC npc = CitizensAPI.getDefaultNPCSelector().getSelected(sender); NPC npc = CitizensAPI.getDefaultNPCSelector().getSelected(sender);
if (npc == null || !npc.hasTrait(BlacksmithTrait.class)) { if (npc == null || !npc.hasTrait(BlacksmithTrait.class)) {
sender.sendMessage(ChatColor.DARK_RED + "You must select an NPC before running this command"); MessageFormatter.displayErrorMessage(sender, "You must select an NPC before running this command");
return true; return true;
} }
if (args.length < 1) {
return false;
}
BlacksmithTrait blacksmithTrait = npc.getTrait(BlacksmithTrait.class); BlacksmithTrait blacksmithTrait = npc.getTrait(BlacksmithTrait.class);
for (NPCSetting npcSetting : NPCSetting.values()) { for (NPCSetting npcSetting : NPCSetting.values()) {
@ -50,8 +58,8 @@ public class BlackSmithEditCommand implements CommandExecutor {
CommandSender sender) { CommandSender sender) {
if (newValue == null) { if (newValue == null) {
//Display the current value of the setting //Display the current value of the setting
sender.sendMessage(ChatColor.GREEN + "Current value of " + npcSetting.getCommandName() + ": " + displaySuccessMessage(sender, Message.getCurrentValueMessage(npcSetting.getCommandName(),
ChatColor.GOLD + blacksmithTrait.getSettings().getRawValue(npcSetting)); MessageFormatter.escapeColorCodes(String.valueOf(blacksmithTrait.getSettings().getRawValue(npcSetting)))));
return true; return true;
} else { } else {
boolean isValidType = TypeValidationHelper.isValid(npcSetting.getValueType(), newValue, sender); boolean isValidType = TypeValidationHelper.isValid(npcSetting.getValueType(), newValue, sender);
@ -59,7 +67,7 @@ public class BlackSmithEditCommand implements CommandExecutor {
//Change the setting //Change the setting
blacksmithTrait.getSettings().changeSetting(npcSetting, blacksmithTrait.getSettings().changeSetting(npcSetting,
ChatColor.translateAlternateColorCodes('&', newValue)); ChatColor.translateAlternateColorCodes('&', newValue));
sender.sendMessage(ChatColor.GREEN + npcSetting.getNodeName() + " set to " + ChatColor.GOLD + newValue); displaySuccessMessage(sender, Message.getValueChangedMessage(npcSetting.getNodeName(), newValue));
return true; return true;
} else { } else {
return false; return false;

View File

@ -1,7 +1,6 @@
package net.knarcraft.blacksmith.command; package net.knarcraft.blacksmith.command;
import net.knarcraft.blacksmith.BlacksmithPlugin; import net.knarcraft.blacksmith.BlacksmithPlugin;
import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
@ -11,6 +10,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;
/** /**
* The command for re-loading the plugin * The command for re-loading the plugin
*/ */
@ -20,7 +21,7 @@ public class ReloadCommand implements TabExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) { @NotNull String[] args) {
BlacksmithPlugin.getInstance().reload(); BlacksmithPlugin.getInstance().reload();
sender.sendMessage(ChatColor.GREEN + "Blacksmith config reloaded!"); displaySuccessMessage(sender, "Blacksmith config reloaded!");
return true; return true;
} }

View File

@ -23,24 +23,24 @@ public enum NPCSetting {
| Messages | | Messages |
-----------*/ -----------*/
BUSY_WITH_PLAYER_MESSAGE("defaults.messages.busy-with-player", SettingValueType.STRING, BUSY_WITH_PLAYER_MESSAGE("defaults.messages.busy-with-player", SettingValueType.STRING,
"§cI'm busy at the moment. Come back later!", "busyPlayerMessage"), "&cI'm busy at the moment. Come back later!", "busyPlayerMessage"),
BUSY_WITH_REFORGE_MESSAGE("defaults.messages.busy-with-reforge", SettingValueType.STRING, "§cI'm working on it. Be patient!", BUSY_WITH_REFORGE_MESSAGE("defaults.messages.busy-with-reforge", SettingValueType.STRING,
"busyReforgeMessage"), "&cI'm working on it. Be patient!", "busyReforgeMessage"),
COOL_DOWN_UNEXPIRED_MESSAGE("defaults.messages.cool-down-not-expired", SettingValueType.STRING, COOL_DOWN_UNEXPIRED_MESSAGE("defaults.messages.cool-down-not-expired", SettingValueType.STRING,
"§cYou've already had your chance! Give me a break!", "coolDownUnexpiredMessage"), "&cYou've already had your chance! Give me a break!", "coolDownUnexpiredMessage"),
COST_MESSAGE( COST_MESSAGE(
"defaults.messages.cost", SettingValueType.STRING, "defaults.messages.cost", SettingValueType.STRING,
"§eIt will cost §a<price> §eto reforge that §a<item>§e! Click again to reforge!", "costMessage"), "&eIt will cost &a<price> &eto reforge that &a<item>&e! Click again to reforge!", "costMessage"),
FAIL_MESSAGE("defaults.messages.fail-reforge", SettingValueType.STRING, "§cWhoops! Didn't mean to do that! Maybe next time?", FAIL_MESSAGE("defaults.messages.fail-reforge", SettingValueType.STRING, "&cWhoops! Didn't mean to do that! Maybe next time?",
"failReforgeMessage"), "failReforgeMessage"),
INSUFFICIENT_FUNDS_MESSAGE("defaults.messages.insufficient-funds", SettingValueType.STRING, INSUFFICIENT_FUNDS_MESSAGE("defaults.messages.insufficient-funds", SettingValueType.STRING,
"§cYou don't have enough money to reforge that item!", "insufficientFundsMessage"), "&cYou don't have enough money to reforge that item!", "insufficientFundsMessage"),
INVALID_ITEM_MESSAGE("defaults.messages.invalid-item", SettingValueType.STRING, INVALID_ITEM_MESSAGE("defaults.messages.invalid-item", SettingValueType.STRING,
"§cI'm sorry, but I don't know how to reforge that!", "invalidItemMessage"), "&cI'm sorry, but I don't know how to reforge that!", "invalidItemMessage"),
ITEM_UNEXPECTEDLY_CHANGED_MESSAGE("defaults.messages.item-changed-during-reforge", SettingValueType.STRING, ITEM_UNEXPECTEDLY_CHANGED_MESSAGE("defaults.messages.item-changed-during-reforge", SettingValueType.STRING,
"§cThat's not the item you wanted to reforge before!", "itemChangedMessage"), "&cThat's not the item you wanted to reforge before!", "itemChangedMessage"),
START_REFORGE_MESSAGE("defaults.messages.start-reforge", SettingValueType.STRING, START_REFORGE_MESSAGE("defaults.messages.start-reforge", SettingValueType.STRING,
"§eOk, let's see what I can do...", "startReforgeMessage"), "&eOk, let's see what I can do...", "startReforgeMessage"),
SUCCESS_MESSAGE("defaults.messages.successful-reforge", SettingValueType.STRING, SUCCESS_MESSAGE("defaults.messages.successful-reforge", SettingValueType.STRING,
"There you go! All better!", "successMessage"); "There you go! All better!", "successMessage");

View File

@ -33,6 +33,16 @@ public enum SettingValueType {
/** /**
* A string list (used for reforge-able items) * A string list (used for reforge-able items)
*/ */
STRING_LIST STRING_LIST,
/**
* A reforge-able material
*/
MATERIAL,
/**
* An enchantment
*/
ENCHANTMENT
} }

View File

@ -5,6 +5,9 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
/**
* A listener for detecting and handling a Blacksmith being right-clicked
*/
public class NPCClickListener implements Listener { public class NPCClickListener implements Listener {
@EventHandler @EventHandler

View File

@ -14,6 +14,9 @@ import org.bukkit.plugin.ServicesManager;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/**
* A class which deals with everything economy
*/
public class EconomyManager { public class EconomyManager {
private static Economy economy; private static Economy economy;

View File

@ -0,0 +1,31 @@
package net.knarcraft.blacksmith.manager;
/**
* An enum representing all item types used in messages
*/
public enum ItemType {
ENCHANTMENT("enchantment"),
MATERIAL("material");
private final String itemTypeName;
/**
* Instantiates an item type
*
* @param itemTypeName <p>The name shown in messages</p>
*/
ItemType(String itemTypeName) {
this.itemTypeName = itemTypeName;
}
/**
* Gets the name of this item type
*
* @return <p>The name of this item type</p>
*/
public String getItemTypeName() {
return this.itemTypeName;
}
}

View File

@ -0,0 +1,100 @@
package net.knarcraft.blacksmith.manager;
public enum Message {
VALUE_CHANGED("&7{setting} set to &6{newValue}"),
VALUE_FOR_ITEM_CHANGED("&7{setting} for {itemType} {item} set to &6{newValue}"),
CURRENT_VALUE("&7Current value of {setting}:&r {currentValue}"),
CURRENT_VALUE_FOR_ITEM("&7Current value of {setting} for {itemType} {item}:&r {currentValue}");
private final String messageString;
/**
* Instantiates a new message
*
* @param messageString <p>The string value of this message</p>
*/
Message(String messageString) {
this.messageString = messageString;
}
/**
* Gets the message to display when a value has been changed
*
* @param setting <p>The setting whose value has been changed</p>
* @param newValue <p>The new value of the setting</p>
* @return <p>The string to display to a user</p>
*/
public static String getValueChangedMessage(String setting, String newValue) {
return replacePlaceholders(VALUE_CHANGED.messageString, new String[]{"{setting}", "{newValue}"},
new String[]{setting, newValue});
}
/**
* Gets the message to display when a value has been changed for an item
*
* @param setting <p>The setting whose value has been changed</p>
* @param itemType <p>The type of item changed ("material" or "enchantment")</p>
* @param item <p>The item the setting was changed for (a material or an enchantment name)</p>
* @param newValue <p>The new value of the setting</p>
* @return <p>The string to display to a user</p>
*/
public static String getItemValueChangedMessage(String setting, ItemType itemType, String item, String newValue) {
return replacePlaceholders(VALUE_FOR_ITEM_CHANGED.messageString, new String[]{"{setting}", "{itemType}",
"{item}", "{newValue}"}, new String[]{setting, itemType.getItemTypeName(), item, newValue});
}
/**
* Gets the message to display when displaying a setting's current value
*
* @param setting <p>The setting whose value is shown</p>
* @param currentValue <p>The current value of the setting</p>
* @return <p>The string to display to a user</p>
*/
public static String getCurrentValueMessage(String setting, String currentValue) {
return replacePlaceholders(CURRENT_VALUE.messageString, new String[]{"{setting}", "{currentValue}"},
new String[]{setting, currentValue});
}
/**
* Gets the message to display when displaying a setting's current value for an item
*
* @param setting <p>The setting whose value is shown</p>
* @param itemType <p>The type of item shown ("material" or "enchantment")</p>
* @param item <p>The item the setting is shown for (a material or an enchantment name)</p>
* @param currentValue <p>The current value of the setting</p>
* @return <p>The string to display to a user</p>
*/
public static String getItemCurrentValueMessage(String setting, ItemType itemType, String item, String currentValue) {
return replacePlaceholders(CURRENT_VALUE_FOR_ITEM.messageString, new String[]{"{setting}", "{itemType}",
"{item}", "{currentValue}"}, new String[]{setting, itemType.getItemTypeName(), item, currentValue});
}
/**
* Replaces a placeholder in a string
*
* @param input <p>The input string to replace in</p>
* @param placeholder <p>The placeholder to replace</p>
* @param replacement <p>The replacement value</p>
* @return <p>The input string with the placeholder replaced</p>
*/
private static String replacePlaceholder(String input, String placeholder, String replacement) {
return input.replace(placeholder, replacement);
}
/**
* Replaces placeholders in a string
*
* @param input <p>The input string to replace in</p>
* @param placeholders <p>The placeholders to replace</p>
* @param replacements <p>The replacement values</p>
* @return <p>The input string with placeholders replaced</p>
*/
private static String replacePlaceholders(String input, String[] placeholders, String[] replacements) {
for (int i = 0; i < Math.min(placeholders.length, replacements.length); i++) {
input = replacePlaceholder(input, placeholders[i], replacements[i]);
}
return input;
}
}

View File

@ -21,6 +21,8 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import static net.knarcraft.blacksmith.util.MessageFormatter.sendNPCMessage;
/** /**
* The class representing the Blacksmith NPC trait * The class representing the Blacksmith NPC trait
*/ */
@ -115,7 +117,7 @@ public class BlacksmithTrait extends Trait {
//Deny if on cool-down, or remove cool-down if expired //Deny if on cool-down, or remove cool-down if expired
if (coolDowns.get(player.getUniqueId()) != null) { if (coolDowns.get(player.getUniqueId()) != null) {
if (!Calendar.getInstance().after(coolDowns.get(player.getUniqueId()))) { if (!Calendar.getInstance().after(coolDowns.get(player.getUniqueId()))) {
player.sendMessage(config.getCoolDownUnexpiredMessage()); sendNPCMessage(this.npc, player, config.getCoolDownUnexpiredMessage());
return false; return false;
} }
coolDowns.remove(player.getUniqueId()); coolDowns.remove(player.getUniqueId());
@ -139,13 +141,13 @@ public class BlacksmithTrait extends Trait {
public void continueSession(Player player) { public void continueSession(Player player) {
//Another player is using the blacksmith //Another player is using the blacksmith
if (!session.isInSession(player)) { if (!session.isInSession(player)) {
player.sendMessage(config.getBusyWithPlayerMessage()); sendNPCMessage(this.npc, player, config.getBusyWithPlayerMessage());
return; return;
} }
//The blacksmith is already reforging for the player //The blacksmith is already reforging for the player
if (session.isRunning()) { if (session.isRunning()) {
player.sendMessage(config.getBusyReforgingMessage()); sendNPCMessage(this.npc, player, config.getBusyReforgingMessage());
return; return;
} }
if (session.endSession()) { if (session.endSession()) {
@ -167,7 +169,7 @@ public class BlacksmithTrait extends Trait {
//Refuse if not repairable, or if reforge-able items is set, but doesn't include the held item //Refuse if not repairable, or if reforge-able items is set, but doesn't include the held item
List<Material> reforgeAbleItems = config.getReforgeAbleItems(); List<Material> reforgeAbleItems = config.getReforgeAbleItems();
if (!isRepairable(hand) || (!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType()))) { if (!isRepairable(hand) || (!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType()))) {
player.sendMessage(config.getInvalidItemMessage()); sendNPCMessage(this.npc, player, config.getInvalidItemMessage());
return; return;
} }
@ -178,7 +180,7 @@ public class BlacksmithTrait extends Trait {
//Tell the player the cost of repairing the item //Tell the player the cost of repairing the item
String cost = EconomyManager.formatCost(player); String cost = EconomyManager.formatCost(player);
String itemName = hand.getType().name().toLowerCase().replace('_', ' '); String itemName = hand.getType().name().toLowerCase().replace('_', ' ');
player.sendMessage(config.getCostMessage().replace("<price>", cost).replace("<item>", itemName)); sendNPCMessage(this.npc, player, config.getCostMessage().replace("<price>", cost).replace("<item>", itemName));
} }
/** /**
@ -188,7 +190,7 @@ public class BlacksmithTrait extends Trait {
* @param player <p>The player that initiated the reforge</p> * @param player <p>The player that initiated the reforge</p>
*/ */
private void reforge(NPC npc, Player player) { private void reforge(NPC npc, Player player) {
player.sendMessage(config.getStartReforgeMessage()); sendNPCMessage(this.npc, player, config.getStartReforgeMessage());
EconomyManager.withdraw(player); EconomyManager.withdraw(player);
session.beginReforge(); session.beginReforge();
ItemStack heldItem = player.getInventory().getItemInMainHand(); ItemStack heldItem = player.getInventory().getItemInMainHand();

View File

@ -17,6 +17,8 @@ import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.logging.Level; import java.util.logging.Level;
import static net.knarcraft.blacksmith.util.MessageFormatter.sendNPCMessage;
/** /**
* A representation of the session between a player and a blacksmith * A representation of the session between a player and a blacksmith
*/ */
@ -57,7 +59,7 @@ public class ReforgeSession implements Runnable {
*/ */
@Override @Override
public void run() { public void run() {
player.sendMessage(reforgeItem() ? config.getSuccessMessage() : config.getFailMessage()); sendNPCMessage(this.npc, player, reforgeItem() ? config.getSuccessMessage() : config.getFailMessage());
//Stop the re-forged item from displaying in the blacksmith's hand //Stop the re-forged item from displaying in the blacksmith's hand
if (npc.getEntity() instanceof Player) { if (npc.getEntity() instanceof Player) {
@ -191,12 +193,12 @@ public class ReforgeSession implements Runnable {
// Prevent player from switching items during session // Prevent player from switching items during session
ItemStack itemInHand = player.getInventory().getItemInMainHand(); ItemStack itemInHand = player.getInventory().getItemInMainHand();
if (!itemToReforge.equals(itemInHand)) { if (!itemToReforge.equals(itemInHand)) {
player.sendMessage(config.getItemChangedMessage()); sendNPCMessage(this.npc, player, config.getItemChangedMessage());
return true; return true;
} }
// The player is unable to pay // The player is unable to pay
if (!EconomyManager.canPay(player)) { if (!EconomyManager.canPay(player)) {
player.sendMessage(config.getInsufficientFundsMessage()); sendNPCMessage(this.npc, player, config.getInsufficientFundsMessage());
return true; return true;
} }
return false; return false;

View File

@ -0,0 +1,36 @@
package net.knarcraft.blacksmith.util;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
/**
* A helper class for parsing input into proper object types
*/
public final class InputParsingHelper {
private InputParsingHelper() {
}
/**
* Tries to find the material matching the given input string
*
* @param input <p>The string to match to a material</p>
* @return <p>The material matching the string, or null if not found</p>
*/
public static Material matchMaterial(String input) {
return Material.matchMaterial(input.replace("-", "_"));
}
/**
* Tries to find the enchantment matching the given input string
*
* @param input <p>The string to match to an enchantment</p>
* @return <p>The enchantment matching the string, or null if not found</p>
*/
public static Enchantment matchEnchantment(String input) {
return Enchantment.getByKey(NamespacedKey.minecraft(input.replace("-", "_")));
}
}

View File

@ -0,0 +1,83 @@
package net.knarcraft.blacksmith.util;
import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.blacksmith.BlacksmithPlugin;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* A message formatter to ensure uniform colors and format of chat messages
*/
public final class MessageFormatter {
private final static String pluginName = BlacksmithPlugin.getInstance().getDescription().getName();
private MessageFormatter() {
}
/**
* Sends a message from a blacksmith NPC to a player
*
* @param npc <p>The NPC sending the message</p>
* @param player <p>The player to send the message to</p>
* @param message <p>The message to send</p>
*/
public static void sendNPCMessage(NPC npc, Player player, String message) {
player.sendMessage(ChatColor.GREEN + "[" + npc.getName() + "] -> You:" + ChatColor.RESET + " " +
translateColors(message));
}
/**
* Displays a message signifying a successful action
*
* @param sender <p>The command sender to display the message to</p>
* @param message <p>The raw message to display</p>
*/
public static void displaySuccessMessage(CommandSender sender, String message) {
sender.sendMessage(ChatColor.GREEN + getFormattedMessage(message));
}
/**
* Displays a message signifying an unsuccessful action
*
* @param sender <p>The command sender to display the message to</p>
* @param message <p>The raw message to display</p>
*/
public static void displayErrorMessage(CommandSender sender, String message) {
sender.sendMessage(ChatColor.DARK_RED + getFormattedMessage(message));
}
/**
* Escapes color codes to prevent them from being shown
*
* @param input <p>The input string to escape color codes for</p>
* @return <p>The input string with color codes escaped</p>
*/
public static String escapeColorCodes(String input) {
//TODO: Find a working way of escaping color codes
return translateColors(input).replace(String.valueOf(ChatColor.COLOR_CHAR), "&&&");
}
/**
* Gets the formatted version of any chat message
*
* @param message <p>The message to format</p>
* @return <p>The formatted message</p>
*/
private static String getFormattedMessage(String message) {
return "[" + pluginName + "] " + ChatColor.RESET + translateColors(message);
}
/**
* Translates & color codes to proper colors
*
* @param input <p>The input string to translate colors for</p>
* @return <p>The input with color codes translated</p>
*/
private static String translateColors(String input) {
return ChatColor.translateAlternateColorCodes('&', input);
}
}

View File

@ -1,6 +1,11 @@
package net.knarcraft.blacksmith.util; package net.knarcraft.blacksmith.util;
import net.knarcraft.blacksmith.config.SettingValueType; import net.knarcraft.blacksmith.config.SettingValueType;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -28,9 +33,40 @@ public final class TabCompleteValuesHelper {
case STRING -> getStrings(); case STRING -> getStrings();
case PERCENTAGE -> getPercentages(); case PERCENTAGE -> getPercentages();
case STRING_LIST -> getReforgeAbleMaterials(); case STRING_LIST -> getReforgeAbleMaterials();
case MATERIAL -> getAllReforgeAbleMaterials();
case ENCHANTMENT -> getAllEnchantments();
}; };
} }
/**
* Gets a complete list of all reforge-able materials
*
* @return <p>A complete list of reforge-able materials</p>
*/
private static List<String> getAllReforgeAbleMaterials() {
List<String> reforgeAbleMaterials = new ArrayList<>();
for (Material material : Material.values()) {
ItemStack item = new ItemStack(material);
if (item.getItemMeta() instanceof Damageable && EnchantmentTarget.BREAKABLE.includes(item)) {
reforgeAbleMaterials.add(material.name());
}
}
return reforgeAbleMaterials;
}
/**
* Gets a complete list of enchantments
*
* @return <p>A complete list of enchantments</p>
*/
private static List<String> getAllEnchantments() {
List<String> enchantments = new ArrayList<>();
for (Enchantment enchantment : Enchantment.values()) {
enchantments.add(enchantment.toString());
}
return enchantments;
}
/** /**
* Gets some example possible values for reforge-able materials * Gets some example possible values for reforge-able materials
* *

View File

@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* A helper class for tab complation * A helper class for tab-completion
*/ */
public final class TabCompletionHelper { public final class TabCompletionHelper {

View File

@ -1,9 +1,10 @@
package net.knarcraft.blacksmith.util; package net.knarcraft.blacksmith.util;
import net.knarcraft.blacksmith.config.SettingValueType; import net.knarcraft.blacksmith.config.SettingValueType;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import static net.knarcraft.blacksmith.util.MessageFormatter.displayErrorMessage;
/** /**
* A helper class for validating a value's type * A helper class for validating a value's type
*/ */
@ -30,6 +31,7 @@ public final class TypeValidationHelper {
case PERCENTAGE -> isPercentage(value, sender); case PERCENTAGE -> isPercentage(value, sender);
case BOOLEAN -> true; case BOOLEAN -> true;
case STRING_LIST -> isStringList(value, sender); case STRING_LIST -> isStringList(value, sender);
case MATERIAL, ENCHANTMENT -> false;
}; };
} catch (ClassCastException exception) { } catch (ClassCastException exception) {
//This error signifies that an object is not a string, and of the wrong class //This error signifies that an object is not a string, and of the wrong class
@ -47,7 +49,7 @@ public final class TypeValidationHelper {
private static boolean isStringList(Object value, CommandSender sender) { private static boolean isStringList(Object value, CommandSender sender) {
boolean isStringList = value instanceof String[] || value instanceof String; boolean isStringList = value instanceof String[] || value instanceof String;
if (!isStringList && sender != null) { if (!isStringList && sender != null) {
sender.sendMessage(ChatColor.DARK_RED + "A string list is required!"); displayErrorMessage(sender, "A string list is required!");
} }
return isStringList; return isStringList;
} }
@ -65,7 +67,7 @@ public final class TypeValidationHelper {
return intValue > 0 && intValue <= 100; return intValue > 0 && intValue <= 100;
} catch (NumberFormatException | NullPointerException exception) { } catch (NumberFormatException | NullPointerException exception) {
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.DARK_RED + "You specified a value which isn't between 0 and 100!"); displayErrorMessage(sender, "You specified a value which isn't between 0 and 100!");
} }
return false; return false;
} }
@ -81,7 +83,7 @@ public final class TypeValidationHelper {
private static boolean isNonEmptyString(Object value, CommandSender sender) { private static boolean isNonEmptyString(Object value, CommandSender sender) {
boolean isString = value instanceof String string && !string.strip().isEmpty(); boolean isString = value instanceof String string && !string.strip().isEmpty();
if (!isString && sender != null) { if (!isString && sender != null) {
sender.sendMessage(ChatColor.DARK_RED + "A non-empty string is required!"); displayErrorMessage(sender, "A non-empty string is required!");
} }
return isString; return isString;
} }
@ -98,7 +100,7 @@ public final class TypeValidationHelper {
return ConfigHelper.asDouble(value) > 0.0; return ConfigHelper.asDouble(value) > 0.0;
} catch (NumberFormatException | NullPointerException exception) { } catch (NumberFormatException | NullPointerException exception) {
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.DARK_RED + "You specified a value which isn't a positive double!"); displayErrorMessage(sender, "You specified a value which isn't a positive double!");
} }
return false; return false;
} }
@ -116,7 +118,7 @@ public final class TypeValidationHelper {
return ConfigHelper.asInt(value) > 0; return ConfigHelper.asInt(value) > 0;
} catch (NumberFormatException | NullPointerException exception) { } catch (NumberFormatException | NullPointerException exception) {
if (sender != null) { if (sender != null) {
sender.sendMessage(ChatColor.DARK_RED + "You specified a value which isn't a positive integer!"); displayErrorMessage(sender, "You specified a value which isn't a positive integer!");
} }
return false; return false;
} }

View File

@ -59,31 +59,31 @@ defaults:
# All messages used by the NPC # All messages used by the NPC
messages: messages:
# The message to display when another player is using the blacksmith # The message to display when another player is using the blacksmith
busy-with-player: "§cI'm busy at the moment. Come back later!" busy-with-player: "&cI'm busy at the moment. Come back later!"
# The message to display when the blacksmith is working on the re-forge # The message to display when the blacksmith is working on the re-forge
busy-with-reforge: "§cI'm working on it. Be patient!" busy-with-reforge: "&cI'm working on it. Be patient!"
# The message to display when the blacksmith is still on a cool-down from the previous re-forging # The message to display when the blacksmith is still on a cool-down from the previous re-forging
cool-down-not-expired: "§cYou've already had your chance! Give me a break!" cool-down-not-expired: "&cYou've already had your chance! Give me a break!"
# The message to display when informing a player about the re-forge cost # The message to display when informing a player about the re-forge cost
cost: "§eIt will cost §a<price> §eto reforge that §a<item>§e! Click again to reforge!" cost: "&eIt will cost &a<price> &eto reforge that &a<item>&e! Click again to reforge!"
# The message to display when the blacksmith fails to re-forge an item # The message to display when the blacksmith fails to re-forge an item
fail-reforge: "§cWhoops! Didn't mean to do that! Maybe next time?" fail-reforge: "&cWhoops! Didn't mean to do that! Maybe next time?"
# The message to display when a player cannot pay for the re-forge # The message to display when a player cannot pay for the re-forge
insufficient-funds: "§cYou don't have enough money to reforge that item!" insufficient-funds: "&cYou don't have enough money to reforge that item!"
# The message to display when holding an item the blacksmith is unable to re-forge # The message to display when holding an item the blacksmith is unable to re-forge
invalid-item: "§cI'm sorry, but I don't know how to reforge that!" invalid-item: "&cI'm sorry, but I don't know how to reforge that!"
# The message to display when presenting a different item than the one just evaluated # The message to display when presenting a different item than the one just evaluated
item-changed-during-reforge: "§cThat's not the item you wanted to reforge before!" item-changed-during-reforge: "&cThat's not the item you wanted to reforge before!"
# The message to display once the blacksmith starts re-forging # The message to display once the blacksmith starts re-forging
start-reforge: "§eOk, let's see what I can do..." start-reforge: "&eOk, let's see what I can do..."
# The message to display once the re-forge has successfully finished # The message to display once the re-forge has successfully finished
successful-reforge: "There you go! All better!" successful-reforge: "There you go! All better!"