Implements a mix of #3 and #7

Adds a preset command which can be used to see available presets
Adds preset filters which can be used to specify item sub-categories within a preset
Removes SWORD_SMITH and RANGED_SMITH, as those are replaced by the RANGED and SWORD filters
Adds a list of usable filters for each preset
This commit is contained in:
2022-10-13 18:40:38 +02:00
parent 6a55300c1e
commit 12f807060e
16 changed files with 552 additions and 55 deletions

View File

@ -5,43 +5,126 @@ package net.knarcraft.blacksmith.config;
*/
public enum NPCSetting {
/**
* The setting for whether the NPC should drop an item to the ground when finished
*
* <p>If set to false, the item will be directly put in the player's inventory instead</p>
*/
DROP_ITEM("dropItem", SettingValueType.BOOLEAN, true, "dropItem"),
/**
* The setting for whether the cool-down period between reforging sessions should be disabled
*/
DISABLE_COOL_DOWN("disableCoolDown", SettingValueType.BOOLEAN, false, "disableCoolDown"),
/**
* The setting for whether the delay it takes for an item to be repaired should be disabled
*/
DISABLE_DELAY("disableDelay", SettingValueType.BOOLEAN, false, "disableDelay"),
/**
* The setting for the chance of a reforging to fail
*/
FAIL_CHANCE("failReforgeChance", SettingValueType.PERCENTAGE, 10, "failReforgeChance"),
/**
* The setting for the chance of an additional enchantment being added
*/
EXTRA_ENCHANTMENT_CHANCE("extraEnchantmentChance", SettingValueType.PERCENTAGE, 5,
"extraEnchantmentChance"),
/**
* The setting for the maximum amount of enchantments that can be added to an item
*/
MAX_ENCHANTMENTS("maxEnchantments", SettingValueType.POSITIVE_INTEGER, 3, "maxEnchantments"),
/**
* The maximum amount of seconds a player may need to wait for the reforging to finish
*/
MAX_REFORGE_DELAY("delaysInSeconds.maximum", SettingValueType.POSITIVE_INTEGER, 30, "maxReforgeDelay"),
/**
* The minimum amount of seconds a player may need to wait for the reforging to finish
*/
MIN_REFORGE_DELAY("delaysInSeconds.minimum", SettingValueType.POSITIVE_INTEGER, 5, "minReforgeDelay"),
/**
* The setting for number of seconds a player has to wait between each usage of the blacksmith
*/
REFORGE_COOL_DOWN("delaysInSeconds.reforgeCoolDown", SettingValueType.POSITIVE_INTEGER, 60, "reforgeCoolDown"),
/**
* The setting for which items the blacksmith is able to reforge
*/
REFORGE_ABLE_ITEMS("reforgeAbleItems", SettingValueType.STRING_LIST, new String[]{}, "reforgeAbleItems"),
/*-----------
| Messages |
-----------*/
/**
* The message displayed when the blacksmith is busy with another player
*/
BUSY_WITH_PLAYER_MESSAGE("messages.busyPlayerMessage", SettingValueType.STRING,
"&cI'm busy at the moment. Come back later!", "busyPlayerMessage"),
//TODO: Add placeholder for remaining time?
/**
* The message displayed when the blacksmith is already reforging something for the player
*/
BUSY_WITH_REFORGE_MESSAGE("messages.busyReforgeMessage", SettingValueType.STRING,
"&cI'm working on it. Be patient!", "busyReforgeMessage"),
//TODO: Add placeholder for remaining time?
/**
* The message displayed if the player has to wait for the cool-down to expire
*/
COOL_DOWN_UNEXPIRED_MESSAGE("messages.coolDownUnexpiredMessage", SettingValueType.STRING,
"&cYou've already had your chance! Give me a break!", "coolDownUnexpiredMessage"),
/**
* The message displayed when displaying the cost of reforging the held item to the player
*/
COST_MESSAGE("messages.costMessage", SettingValueType.STRING,
"&eIt will cost &a<price> &eto reforge that &a<item>&e! Click again to reforge!", "costMessage"),
/**
* The message displayed if the blacksmith fails reforging an item
*/
FAIL_MESSAGE("messages.failReforgeMessage", SettingValueType.STRING,
"&cWhoops! Didn't mean to do that! Maybe next time?", "failReforgeMessage"),
/**
* The message displayed if a player is unable to pay the blacksmith
*/
INSUFFICIENT_FUNDS_MESSAGE("messages.insufficientFundsMessage", SettingValueType.STRING,
"&cYou don't have enough money to reforge that item!", "insufficientFundsMessage"),
/**
* The message displayed if the blacksmith encounters an item they cannot reforge
*/
INVALID_ITEM_MESSAGE("messages.invalidItemMessage", SettingValueType.STRING,
"&cI'm sorry, but I don't know how to reforge that!", "invalidItemMessage"),
/**
* The message displayed if a player presents a different item after seeing the price to reforge an item
*/
ITEM_UNEXPECTEDLY_CHANGED_MESSAGE("messages.itemChangedMessage", SettingValueType.STRING,
"&cThat's not the item you wanted to reforge before!", "itemChangedMessage"),
/**
* The message displayed when the blacksmith starts reforging an item
*/
START_REFORGE_MESSAGE("messages.startReforgeMessage", SettingValueType.STRING,
"&eOk, let's see what I can do...", "startReforgeMessage"),
/**
* The message displayed when the blacksmith successfully finishes reforging an item
*/
SUCCESS_MESSAGE("messages.successMessage", SettingValueType.STRING,
"There you go! All better!", "successMessage"),
/**
* The message displayed when trying to reforge an item with full durability
*/
NOT_DAMAGED_MESSAGE("messages.notDamagedMessage", SettingValueType.STRING,
"&cThat item is not in need of repair", "notDamagedMessage");

View File

@ -1,39 +1,77 @@
package net.knarcraft.blacksmith.config;
import net.knarcraft.blacksmith.BlacksmithPlugin;
import org.bukkit.Material;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
/**
* A representation of the presets for different kinds of smiths
*/
public enum SmithPreset {
/**
* A blacksmith capable of re-forging all swords
*/
SWORD_SMITH,
/**
* A blacksmith capable of re-forging all weapons (including shields)
*/
WEAPON_SMITH,
WEAPON_SMITH(new SmithPresetFilter[]{SmithPresetFilter.BOW, SmithPresetFilter.SWORD, SmithPresetFilter.RANGED}),
/**
* A blacksmith capable of re-forging all armor
*/
ARMOR_SMITH,
ARMOR_SMITH(new SmithPresetFilter[]{SmithPresetFilter.LEATHER, SmithPresetFilter.IRON, SmithPresetFilter.CHAINMAIL,
SmithPresetFilter.GOLD, SmithPresetFilter.DIAMOND, SmithPresetFilter.NETHERITE}),
/**
* A blacksmith capable of re-forging all tools (hoe, axe, shovel, pickaxe, flint and steel, shears, fishing rod)
*/
TOOL_SMITH,
TOOL_SMITH(new SmithPresetFilter[]{SmithPresetFilter.WOOD, SmithPresetFilter.STONE, SmithPresetFilter.IRON,
SmithPresetFilter.GOLD, SmithPresetFilter.DIAMOND, SmithPresetFilter.NETHERITE, SmithPresetFilter.PICKAXE,
SmithPresetFilter.AXE, SmithPresetFilter.HOE, SmithPresetFilter.SHOVEL, SmithPresetFilter.MISC});
private final SmithPresetFilter[] filters;
/**
* A blacksmith capable of re-forging all ranged weapons (bow, crossbow, trident)
* Instantiates a new smith preset
*
* @param filters <p>The filters applicable to this preset</p>
*/
RANGED_SMITH;
SmithPreset(SmithPresetFilter[] filters) {
this.filters = filters;
}
/**
* Gets whether this preset supports the given filter
*
* @param filter <p>The filter to check</p>
* @return <p>True if the filter is supported</p>
*/
public boolean supportsFilter(SmithPresetFilter filter) {
return List.of(filters).contains(filter);
}
/**
* Gets all filters supported by this preset
*
* @return <p>The filters supported by this preset</p>
*/
public List<SmithPresetFilter> getSupportedFilters() {
return List.of(filters);
}
/**
* Gets the names of all available smith presets
*
* @return <p>All available smith presets</p>
*/
public static List<String> getPresetNames() {
List<String> presetNames = new ArrayList<>();
for (SmithPreset preset : SmithPreset.values()) {
presetNames.add(preset.name());
}
return presetNames;
}
/**
* Replaces the given string if it's a smith type preset
@ -42,13 +80,47 @@ public enum SmithPreset {
* @return <p>The string, possibly with the preset replaced</p>
*/
public static String replacePreset(String possiblePreset) {
for (SmithPreset smithPreset : SmithPreset.values()) {
if (possiblePreset.replace('-', '_').equalsIgnoreCase("preset:" +
smithPreset.name())) {
return String.join(",", smithPreset.getMaterialNames());
}
String upperCasedPreset = possiblePreset.replace('-', '_').toUpperCase();
if (!upperCasedPreset.startsWith("PRESET:")) {
return possiblePreset;
}
return possiblePreset;
//Parse the input
SmithPresetFilter filter = null;
SmithPreset preset;
try {
String[] parts = upperCasedPreset.split(":");
if (parts.length > 2) {
filter = SmithPresetFilter.valueOf(parts[2]);
}
preset = SmithPreset.valueOf(parts[1]);
} catch (IllegalArgumentException exception) {
/* This case means that either the preset or the filter given is invalid, and thus the preset string should
be ignored to prevent any problems. */
BlacksmithPlugin.getInstance().getLogger().log(Level.WARNING, String.format("The smith preset %s is " +
"invalid, and will be ignored. Please fix it!", possiblePreset));
return "";
}
//Return the list of materials included in the preset
if (filter != null) {
return String.join(",", preset.getMaterialNames(filter));
} else {
return String.join(",", preset.getMaterialNames());
}
}
/**
* Gets the materials included in this preset, filtered using the given filter
*
* @param filter <p>The filter to use for filtering</p>
* @return <p>The materials included in this preset, filtered using the given filter</p>
*/
public List<Material> getFilteredMaterials(SmithPresetFilter filter) {
List<Material> materials = new ArrayList<>(this.getMaterials());
materials.removeIf((item) -> !filter.isIncluded(item));
return materials;
}
/**
@ -58,11 +130,9 @@ public enum SmithPreset {
*/
public List<Material> getMaterials() {
return switch (this) {
case SWORD_SMITH -> getSwords();
case WEAPON_SMITH -> getWeapons();
case ARMOR_SMITH -> getArmor();
case TOOL_SMITH -> getTools();
case RANGED_SMITH -> getRanged();
};
}
@ -149,8 +219,28 @@ public enum SmithPreset {
* @return <p>All material names for this smith</p>
*/
private List<String> getMaterialNames() {
return getNames(this.getMaterials());
}
/**
* Gets material names of all materials reforge-able by this smith
*
* @param filter <p>The filter used for filtering materials</p>
* @return <p>All material names for this smith</p>
*/
private List<String> getMaterialNames(SmithPresetFilter filter) {
return getNames(this.getFilteredMaterials(filter));
}
/**
* Gets a list of material names from the given materials
*
* @param materials <p>The materials to get the names of</p>
* @return <p>The names of the materials</p>
*/
private List<String> getNames(List<Material> materials) {
List<String> items = new ArrayList<>();
for (Material material : this.getMaterials()) {
for (Material material : materials) {
items.add(material.name().toLowerCase().replace("_", "-"));
}
return items;

View File

@ -0,0 +1,147 @@
package net.knarcraft.blacksmith.config;
import org.bukkit.Material;
/**
* A representation of all available filters for smith presets
*/
public enum SmithPresetFilter {
/**
* Filters to only include items made of wood
*/
WOOD(true, "WOODEN_"),
/**
* Filters to only include items made of iron
*/
IRON(true, "IRON_"),
/**
* Filters to only include items made of leather
*/
LEATHER(true, "LEATHER_"),
/**
* Filters to only include items made of chainmail
*/
CHAINMAIL(true, "CHAINMAIL_"),
/**
* Filters to only include items made of gold
*/
GOLD(true, "GOLDEN_"),
/**
* Filters to only include items made of diamond
*/
DIAMOND(true, "DIAMOND"),
/**
* Filters to only include items made of netherite
*/
NETHERITE(true, "NETHERITE_"),
/**
* Filters to only include items made of stone
*/
STONE(true, "STONE_"),
/**
* Filters to only include bows
*/
BOW(false, "BOW"),
/**
* Filters to only include pickaxes
*/
PICKAXE(false, "_PICKAXE"),
/**
* Filters to only include hoes
*/
HOE(false, "_HOE"),
/**
* Filters to only include shovels
*/
SHOVEL(false, "_SHOVEL"),
/**
* Filters to only include axes
*/
AXE(false, "_AXE"),
/**
* Filters to only include swords
*/
SWORD(false, "_SWORD"),
/**
* Filters to only include ranged weapons (bows and trident)
*/
RANGED(false, null),
/**
* Filters to only include miscellaneous tools (fishing rod, flint and steel, shears)
*/
MISC(false, null);
private final boolean searchStart;
private final String identifier;
/**
* Instantiates a new smith preset filter
*
* @param searchStart <p>Whether to search the start of a string for the identifier</p>
* @param identifier <p>The string any material matching this filter contains</p>
*/
SmithPresetFilter(boolean searchStart, String identifier) {
this.searchStart = searchStart;
this.identifier = identifier;
}
/**
* Gets whether the given material is included in this filter
*
* @param material <p>The material to check</p>
* @return <p>True if the material is included in this filter</p>
*/
public boolean isIncluded(Material material) {
if (isSpecialCase()) {
return isIncludedSpecialCase(material);
}
if (this.searchStart) {
return material.name().startsWith(this.identifier);
} else {
return material.name().endsWith(this.identifier);
}
}
/**
* Checks if this filter is a special case which doesn't work with normal rules
*
* @return <p>True if this filter is a special case</p>
*/
private boolean isSpecialCase() {
return this == RANGED || this == MISC;
}
/**
* Uses a special-case check to see if the given material is part of this filter
*
* @param material <p>The material to check</p>
* @return <p>True if the material is part of this filter</p>
*/
private boolean isIncludedSpecialCase(Material material) {
if (this == RANGED) {
return material.name().endsWith(BOW.identifier) || material == Material.TRIDENT;
} else if (this == MISC) {
return material == Material.SHEARS || material == Material.FLINT_AND_STEEL ||
material == Material.FISHING_ROD;
} else {
return false;
}
}
}