409 lines
15 KiB
Java
409 lines
15 KiB
Java
package net.knarcraft.blacksmith.config;
|
|
|
|
import net.citizensnpcs.api.util.DataKey;
|
|
import net.citizensnpcs.api.util.YamlStorage;
|
|
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
|
import net.knarcraft.blacksmith.util.ConfigHelper;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.NamespacedKey;
|
|
import org.bukkit.enchantments.Enchantment;
|
|
|
|
import java.io.File;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.logging.Level;
|
|
|
|
/**
|
|
* A class which keeps track of all default NPC settings and all global settings
|
|
*/
|
|
public class GlobalSettings {
|
|
|
|
private final Map<Material, Double> materialBasePrices = new HashMap<>();
|
|
private final Map<Material, Double> materialPricePerDurabilityPoints = new HashMap<>();
|
|
private final Map<Enchantment, Double> enchantmentCosts = new HashMap<>();
|
|
|
|
private final Map<NPCSetting, Object> defaultNPCSettings = new HashMap<>();
|
|
private final Map<GlobalSetting, Object> globalSettings = new HashMap<>();
|
|
|
|
private final YamlStorage defaultConfig;
|
|
|
|
/**
|
|
* Instantiates a new "Settings"
|
|
*
|
|
* @param plugin <p>A reference to the blacksmith plugin</p>
|
|
*/
|
|
public GlobalSettings(BlacksmithPlugin plugin) {
|
|
defaultConfig = new YamlStorage(new File(plugin.getDataFolder() + File.separator + "config.yml"),
|
|
"Blacksmith Configuration\nWarning: The values under defaults are the values set for a " +
|
|
"blacksmith upon creation. To change any values for existing NPCs, edit the citizens NPC file.");
|
|
}
|
|
|
|
/**
|
|
* Loads all configuration values from the config file
|
|
*/
|
|
public void load() {
|
|
//Load the config from disk
|
|
defaultConfig.load();
|
|
DataKey root = defaultConfig.getKey("");
|
|
|
|
//Just in case, clear existing values
|
|
defaultNPCSettings.clear();
|
|
globalSettings.clear();
|
|
materialBasePrices.clear();
|
|
materialPricePerDurabilityPoints.clear();
|
|
enchantmentCosts.clear();
|
|
|
|
//Load/Save NPC default settings
|
|
loadDefaultNPCSettings(root);
|
|
|
|
//Load/Save global settings
|
|
loadGlobalSettings(root);
|
|
|
|
//Save any modified values to disk
|
|
defaultConfig.save();
|
|
}
|
|
|
|
/**
|
|
* Changes the value of the given setting
|
|
*
|
|
* @param globalSetting <p>The global setting to change</p>
|
|
* @param newValue <p>The new value of the setting</p>
|
|
*/
|
|
public void changeValue(GlobalSetting globalSetting, Object newValue) {
|
|
globalSettings.put(globalSetting, newValue);
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Changes the value of the given setting
|
|
*
|
|
* @param npcSetting <p>The default NPC setting to change</p>
|
|
* @param newValue <p>The new value for the setting</p>
|
|
*/
|
|
public void changeValue(NPCSetting npcSetting, Object newValue) {
|
|
defaultNPCSettings.put(npcSetting, newValue);
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Gets the current raw value of the given global setting
|
|
*
|
|
* @param globalSetting <p>The setting to get</p>
|
|
* @return <p>The current raw setting value</p>
|
|
*/
|
|
public Object getRawValue(GlobalSetting globalSetting) {
|
|
return globalSettings.get(globalSetting);
|
|
}
|
|
|
|
/**
|
|
* Gets the current raw value of the given default NPC setting
|
|
*
|
|
* @param npcSetting <p>The setting to get</p>
|
|
* @return <p>The current raw setting value</p>
|
|
*/
|
|
public Object getRawValue(NPCSetting npcSetting) {
|
|
return defaultNPCSettings.get(npcSetting);
|
|
}
|
|
|
|
/**
|
|
* Sets the enchantment cost for the given enchantment
|
|
*
|
|
* @param enchantment <p>The enchantment to set the enchantment cost for</p>
|
|
* @param newEnchantmentCost <p>The new enchantment cost</p>
|
|
*/
|
|
public void setEnchantmentCost(Enchantment enchantment, double newEnchantmentCost) {
|
|
if (newEnchantmentCost < 0) {
|
|
throw new IllegalArgumentException("Enchantment cost cannot be negative!");
|
|
}
|
|
if (enchantment == null) {
|
|
globalSettings.put(GlobalSetting.ENCHANTMENT_COST, newEnchantmentCost);
|
|
} else {
|
|
enchantmentCosts.put(enchantment, newEnchantmentCost);
|
|
}
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Sets the price per durability point for the given material
|
|
*
|
|
* @param material <p>The material to set the price per durability point price for</p>
|
|
* @param newPrice <p>The new price per durability point price</p>
|
|
*/
|
|
public void setPricePerDurabilityPoint(Material material, double newPrice) {
|
|
if (newPrice < 0) {
|
|
throw new IllegalArgumentException("Price per durability point cannot be negative!");
|
|
}
|
|
if (material == null) {
|
|
globalSettings.put(GlobalSetting.PRICE_PER_DURABILITY_POINT, newPrice);
|
|
} else {
|
|
materialPricePerDurabilityPoints.put(material, newPrice);
|
|
}
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Sets the base price for the given material
|
|
*
|
|
* @param material <p>The material to set the base price for</p>
|
|
* @param newBasePrice <p>The new base price</p>
|
|
*/
|
|
public void setBasePrice(Material material, double newBasePrice) {
|
|
if (newBasePrice < 0) {
|
|
throw new IllegalArgumentException("Base price cannot be negative!");
|
|
}
|
|
if (material == null) {
|
|
globalSettings.put(GlobalSetting.BASE_PRICE, newBasePrice);
|
|
} else {
|
|
materialBasePrices.put(material, newBasePrice);
|
|
}
|
|
save();
|
|
}
|
|
|
|
/**
|
|
* Gets the current value of the default NPC settings
|
|
*
|
|
* @return <p>The current value of the default NPC settings</p>
|
|
*/
|
|
public Map<NPCSetting, Object> getDefaultNPCSettings() {
|
|
return new HashMap<>(this.defaultNPCSettings);
|
|
}
|
|
|
|
/**
|
|
* Gets whether to use natural cost for cost calculation
|
|
*
|
|
* <p>Natural cost makes it more costly the more damage is dealt to an item. The alternative is the legacy behavior
|
|
* where the amount of durability points remaining increases the cost.</p>
|
|
*
|
|
* @return <p>Whether to use natural cost</p>
|
|
*/
|
|
public boolean getUseNaturalCost() {
|
|
return asBoolean(GlobalSetting.NATURAL_COST);
|
|
}
|
|
|
|
/**
|
|
* Gets the base price for the given material
|
|
*
|
|
* @param material <p>The material to get the base price for</p>
|
|
* @return <p>The base price for the material</p>
|
|
*/
|
|
public double getBasePrice(Material material) {
|
|
if (materialBasePrices.containsKey(material) && materialBasePrices.get(material) != null) {
|
|
return materialBasePrices.get(material);
|
|
} else {
|
|
return asDouble(GlobalSetting.BASE_PRICE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the price per durability point for the given material
|
|
*
|
|
* @param material <p>The material to get the durability point price for</p>
|
|
* @return <p>The durability point price for the material</p>
|
|
*/
|
|
public double getPricePerDurabilityPoint(Material material) {
|
|
if (materialPricePerDurabilityPoints.containsKey(material) &&
|
|
materialPricePerDurabilityPoints.get(material) != null) {
|
|
return materialPricePerDurabilityPoints.get(material);
|
|
} else {
|
|
return asDouble(GlobalSetting.PRICE_PER_DURABILITY_POINT);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the cost to be added for each level of the given enchantment
|
|
*
|
|
* @param enchantment <p>The enchantment to get the cost for</p>
|
|
* @return <p>The cost of each enchantment level</p>
|
|
*/
|
|
public double getEnchantmentCost(Enchantment enchantment) {
|
|
if (enchantmentCosts.containsKey(enchantment) && enchantmentCosts.get(enchantment) != null) {
|
|
return enchantmentCosts.get(enchantment);
|
|
} else {
|
|
return asDouble(GlobalSetting.ENCHANTMENT_COST);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the given value as a boolean
|
|
*
|
|
* <p>This will throw an exception if used for a non-boolean value</p>
|
|
*
|
|
* @param setting <p>The setting to get the value of</p>
|
|
* @return <p>The value of the given setting as a boolean</p>
|
|
*/
|
|
public boolean asBoolean(GlobalSetting setting) {
|
|
return ConfigHelper.asBoolean(getValue(setting));
|
|
}
|
|
|
|
/**
|
|
* Gets the given value as a double
|
|
*
|
|
* <p>This will throw an exception if used for a non-double setting</p>
|
|
*
|
|
* @param setting <p>The setting to get the value of</p>
|
|
* @return <p>The value of the given setting as a double</p>
|
|
*/
|
|
public double asDouble(GlobalSetting setting) {
|
|
return ConfigHelper.asDouble(getValue(setting));
|
|
}
|
|
|
|
/**
|
|
* Gets the value of a setting, using the default if not set
|
|
*
|
|
* @param setting <p>The setting to get the value of</p>
|
|
* @return <p>The current value</p>
|
|
*/
|
|
private Object getValue(GlobalSetting setting) {
|
|
Object value = globalSettings.get(setting);
|
|
//If not set in config.yml, use the default value from the enum
|
|
if (value == null) {
|
|
value = setting.getDefaultValue();
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Loads all global settings
|
|
*
|
|
* @param root <p>The root node of all global settings</p>
|
|
*/
|
|
private void loadGlobalSettings(DataKey root) {
|
|
for (GlobalSetting globalSetting : GlobalSetting.values()) {
|
|
if (!root.keyExists(globalSetting.getPath())) {
|
|
//If the setting does not exist in the config file, add it
|
|
root.setRaw(globalSetting.getPath(), globalSetting.getDefaultValue());
|
|
} else {
|
|
//Set the setting to the value found in the path
|
|
globalSettings.put(globalSetting, root.getRaw(globalSetting.getPath()));
|
|
}
|
|
}
|
|
|
|
//Load all base prices
|
|
DataKey basePriceNode = root.getRelative(GlobalSetting.BASE_PRICE.getParent());
|
|
Map<String, String> relevantKeys = getRelevantKeys(basePriceNode);
|
|
for (String key : relevantKeys.keySet()) {
|
|
String materialName = relevantKeys.get(key);
|
|
Material material = Material.matchMaterial(materialName);
|
|
if (material != null) {
|
|
materialBasePrices.put(material, basePriceNode.getDouble(key));
|
|
} else {
|
|
BlacksmithPlugin.getInstance().getLogger().log(Level.WARNING,
|
|
"Unable to find a material matching " + materialName);
|
|
}
|
|
}
|
|
|
|
//Load all per-durability-point prices
|
|
DataKey basePerDurabilityPriceNode = root.getRelative(GlobalSetting.PRICE_PER_DURABILITY_POINT.getParent());
|
|
relevantKeys = getRelevantKeys(basePerDurabilityPriceNode);
|
|
for (String key : relevantKeys.keySet()) {
|
|
String materialName = relevantKeys.get(key);
|
|
Material material = Material.matchMaterial(materialName);
|
|
if (material != null) {
|
|
materialPricePerDurabilityPoints.put(material, basePerDurabilityPriceNode.getDouble(key));
|
|
} else {
|
|
BlacksmithPlugin.getInstance().getLogger().log(Level.WARNING,
|
|
"Unable to find a material matching " + materialName);
|
|
}
|
|
}
|
|
|
|
//Load all enchantment prices
|
|
DataKey enchantmentCostNode = root.getRelative(GlobalSetting.ENCHANTMENT_COST.getParent());
|
|
relevantKeys = getRelevantKeys(basePerDurabilityPriceNode);
|
|
for (String key : relevantKeys.keySet()) {
|
|
String enchantmentName = relevantKeys.get(key);
|
|
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantmentName));
|
|
if (enchantment != null) {
|
|
enchantmentCosts.put(enchantment, enchantmentCostNode.getDouble(key));
|
|
} else {
|
|
BlacksmithPlugin.getInstance().getLogger().log(Level.WARNING,
|
|
"Unable to find an enchantment matching " + enchantmentName);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets a map between relevant keys and their normalized name
|
|
*
|
|
* @param rootKey <p>The root data key containing sub-keys</p>
|
|
* @return <p>Any sub-keys found that aren't the default</p>
|
|
*/
|
|
private Map<String, String> getRelevantKeys(DataKey rootKey) {
|
|
Map<String, String> relevant = new HashMap<>();
|
|
for (DataKey dataKey : rootKey.getSubKeys()) {
|
|
String keyName = dataKey.name();
|
|
//Skip the default value
|
|
if (keyName.equals("default")) {
|
|
continue;
|
|
}
|
|
String normalizedName = keyName.toUpperCase().replace("-", "_");
|
|
relevant.put(keyName, normalizedName);
|
|
}
|
|
return relevant;
|
|
}
|
|
|
|
/**
|
|
* Converts a normalized material name to the format used in the config file
|
|
*
|
|
* @param normalizedName <p>The normalized name to un-normalize</p>
|
|
* @return <p>The un-normalized name</p>
|
|
*/
|
|
private String unNormalizeName(String normalizedName) {
|
|
return normalizedName.toLowerCase().replace("_", "-");
|
|
}
|
|
|
|
/**
|
|
* Loads all default NPC settings
|
|
*
|
|
* @param root <p>The root node of all default NPC settings</p>
|
|
*/
|
|
private void loadDefaultNPCSettings(DataKey root) {
|
|
for (NPCSetting setting : NPCSetting.values()) {
|
|
if (!root.keyExists(setting.getPath())) {
|
|
//If the setting does not exist in the config file, add it
|
|
root.setRaw(setting.getPath(), setting.getDefaultValue());
|
|
} else {
|
|
//Set the setting to the value found in the path
|
|
defaultNPCSettings.put(setting, root.getRaw(setting.getPath()));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves all current settings to the config file
|
|
*/
|
|
private void save() {
|
|
DataKey root = defaultConfig.getKey("");
|
|
//Save all default NPC settings
|
|
for (NPCSetting setting : NPCSetting.values()) {
|
|
root.setRaw(setting.getPath(), defaultNPCSettings.get(setting));
|
|
}
|
|
|
|
//Save all normal global settings
|
|
for (GlobalSetting globalSetting : GlobalSetting.values()) {
|
|
root.setRaw(globalSetting.getPath(), globalSettings.get(globalSetting));
|
|
}
|
|
|
|
//Save all base prices
|
|
DataKey basePriceNode = root.getRelative(GlobalSetting.BASE_PRICE.getParent());
|
|
for (Material material : materialBasePrices.keySet()) {
|
|
basePriceNode.setRaw(unNormalizeName(material.name()), materialBasePrices.get(material));
|
|
}
|
|
|
|
//Save all per-durability-point prices
|
|
DataKey basePerDurabilityPriceNode = root.getRelative(GlobalSetting.PRICE_PER_DURABILITY_POINT.getParent());
|
|
for (Material material : materialPricePerDurabilityPoints.keySet()) {
|
|
basePerDurabilityPriceNode.setRaw(unNormalizeName(material.name()), materialPricePerDurabilityPoints.get(material));
|
|
}
|
|
|
|
//Load all enchantment prices
|
|
DataKey enchantmentCostNode = root.getRelative(GlobalSetting.ENCHANTMENT_COST.getParent());
|
|
for (Enchantment enchantment : enchantmentCosts.keySet()) {
|
|
enchantmentCostNode.setRaw(unNormalizeName(enchantment.getKey().toString()), enchantmentCosts.get(enchantment));
|
|
}
|
|
|
|
//Perform the actual save to disk
|
|
defaultConfig.save();
|
|
}
|
|
|
|
}
|