Changes package name to net.knarcraft
This commit is contained in:
315
src/main/java/net/knarcraft/blacksmith/BlacksmithPlugin.java
Normal file
315
src/main/java/net/knarcraft/blacksmith/BlacksmithPlugin.java
Normal file
@ -0,0 +1,315 @@
|
||||
package net.knarcraft.blacksmith;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.knarcraft.blacksmith.config.Setting;
|
||||
import net.knarcraft.blacksmith.config.Settings;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import regalowl.hyperconomy.HyperAPI;
|
||||
import regalowl.hyperconomy.HyperConomy;
|
||||
import regalowl.hyperconomy.bukkit.BukkitConnector;
|
||||
import regalowl.hyperconomy.inventory.HItemStack;
|
||||
import regalowl.hyperconomy.tradeobject.TradeObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.Sanitizer.sanitizeItemName;
|
||||
|
||||
/**
|
||||
* Blacksmith's main class
|
||||
*/
|
||||
public class BlacksmithPlugin extends JavaPlugin {
|
||||
|
||||
private static BlacksmithPlugin instance;
|
||||
private Settings config;
|
||||
private Economy economy;
|
||||
private HyperAPI hyperAPI;
|
||||
private BukkitConnector bukkitConnector;
|
||||
private boolean useHyperAPI = false;
|
||||
|
||||
/**
|
||||
* Gets an instance of the Blacksmith plugin
|
||||
*
|
||||
* @return <p>An instance of the blacksmith plugin</p>
|
||||
*/
|
||||
public static BlacksmithPlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets settings for the blacksmith plugin
|
||||
*
|
||||
* @return <p>Settings for the blacksmith plugin</p>
|
||||
*/
|
||||
public Settings getSettings() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// config.save();
|
||||
|
||||
getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " disabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
//Load settings
|
||||
config = new Settings(this);
|
||||
config.load();
|
||||
//Load HyperConomy if available
|
||||
setupHyperConomy();
|
||||
|
||||
getLogger().log(Level.INFO, "Setting Up Vault now....");
|
||||
boolean canLoad = setupVault();
|
||||
if (!canLoad) {
|
||||
getLogger().log(Level.SEVERE, "Vault Integration Failed....");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
//Register the blacksmith trait with Citizens
|
||||
CitizensAPI.getTraitFactory().registerTrait(
|
||||
net.citizensnpcs.api.trait.TraitInfo.create(BlacksmithTrait.class).withName("blacksmith"));
|
||||
|
||||
getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " enabled.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up HyperConomy
|
||||
*
|
||||
* <p>Setup HyperConomy (Soft-Depend only, so this is completely optional!). HyperConomy uses your favorite
|
||||
* Vault-compatible economy system and calculates prices for items based on supply and demand on the fly.
|
||||
* This is only used to get the cost of a repair.</p>
|
||||
*/
|
||||
private void setupHyperConomy() {
|
||||
if (Bukkit.getPluginManager().getPlugin("HyperConomy") != null) {
|
||||
getServer().getLogger().log(Level.INFO, "Found HyperConomy! Using that for calculating prices, " +
|
||||
"base-prices and price-per-durability-point in the Blacksmith config.yml will NOT be used!");
|
||||
this.useHyperAPI = true;
|
||||
Plugin hyperConomyPlugin = getServer().getPluginManager().getPlugin("HyperConomy");
|
||||
bukkitConnector = (BukkitConnector) hyperConomyPlugin;
|
||||
HyperConomy hyperConomy = Objects.requireNonNull(bukkitConnector).getHC();
|
||||
this.hyperAPI = (HyperAPI) hyperConomy.getAPI();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up Vault for economy
|
||||
*
|
||||
* @return <p>True if Vault was successfully set up</p>
|
||||
*/
|
||||
private boolean setupVault() {
|
||||
// Setup Vault
|
||||
RegisteredServiceProvider<Economy> economyProvider = getServer().getServicesManager().getRegistration(
|
||||
Economy.class);
|
||||
if (economyProvider != null) {
|
||||
economy = economyProvider.getProvider();
|
||||
return true;
|
||||
} else {
|
||||
// Disable if no economy plugin was found
|
||||
getServer().getLogger().log(Level.SEVERE, "Failed to load an economy plugin. Disabling...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final CommandSender sender, final @NotNull Command command, final @NotNull String label,
|
||||
final String[] args) {
|
||||
//Handle the reload command
|
||||
config.load();
|
||||
sender.sendMessage(ChatColor.GREEN + "Blacksmith config reloaded!");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the given item is a type of tool
|
||||
*
|
||||
* @param item <p>The item to check if is tool or not</p>
|
||||
* @return <p>True if the given item is a type of tool</p>
|
||||
*/
|
||||
public boolean isTool(ItemStack item) {
|
||||
return switch (item.getType()) {
|
||||
case WOODEN_PICKAXE, WOODEN_SHOVEL, WOODEN_HOE, WOODEN_SWORD, WOODEN_AXE, STONE_PICKAXE, STONE_SHOVEL,
|
||||
STONE_HOE, STONE_SWORD, STONE_AXE, GOLDEN_PICKAXE, GOLDEN_SHOVEL, GOLDEN_HOE, GOLDEN_SWORD,
|
||||
GOLDEN_AXE, IRON_PICKAXE, IRON_SHOVEL, IRON_HOE, IRON_SWORD, IRON_AXE, DIAMOND_PICKAXE,
|
||||
DIAMOND_SHOVEL, DIAMOND_HOE, DIAMOND_SWORD, DIAMOND_AXE, NETHERITE_SWORD, NETHERITE_SHOVEL,
|
||||
NETHERITE_PICKAXE, NETHERITE_AXE, NETHERITE_HOE, BOW, CROSSBOW, FLINT_AND_STEEL, FISHING_ROD,
|
||||
SHEARS, TRIDENT, SHIELD -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the given item is a type of armor
|
||||
*
|
||||
* @param item <p>The item to check if is armor or not</p>
|
||||
* @return <p>True if the given item is a type of armor</p>
|
||||
*/
|
||||
public static boolean isArmor(ItemStack item) {
|
||||
return switch (item.getType()) {
|
||||
case LEATHER_HELMET, LEATHER_CHESTPLATE, LEATHER_LEGGINGS, LEATHER_BOOTS, CHAINMAIL_HELMET,
|
||||
CHAINMAIL_CHESTPLATE, CHAINMAIL_LEGGINGS, CHAINMAIL_BOOTS, GOLDEN_HELMET, GOLDEN_CHESTPLATE,
|
||||
GOLDEN_LEGGINGS, GOLDEN_BOOTS, IRON_HELMET, IRON_CHESTPLATE, IRON_LEGGINGS, IRON_BOOTS,
|
||||
DIAMOND_HELMET, DIAMOND_CHESTPLATE, DIAMOND_LEGGINGS, DIAMOND_BOOTS, TURTLE_HELMET, ELYTRA,
|
||||
NETHERITE_HELMET, NETHERITE_CHESTPLATE, NETHERITE_LEGGINGS, NETHERITE_BOOTS -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public boolean doesPlayerHaveEnough(Player player) {
|
||||
return economy.getBalance(player) - getCost(player.getInventory().getItemInMainHand(), player) >= 0;
|
||||
}
|
||||
|
||||
public String formatCost(Player player) {
|
||||
double cost = getCost(player.getInventory().getItemInMainHand(), player);
|
||||
return economy.format(cost);
|
||||
}
|
||||
|
||||
public void withdraw(Player player) {
|
||||
economy.withdrawPlayer(player, getCost(player.getInventory().getItemInMainHand(), player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the durability of the given item
|
||||
*
|
||||
* @param itemStack <p>The item to get the durability of</p>
|
||||
* @return <p>The durability of the item</p>
|
||||
*/
|
||||
public static short getDurability(ItemStack itemStack) {
|
||||
Damageable damageable = (Damageable) itemStack.getItemMeta();
|
||||
return (short) (itemStack.getType().getMaxDurability() - damageable.getDamage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damage done to the given item
|
||||
*
|
||||
* @param itemStack <p>The damage done to the item</p>
|
||||
* @return <p>The damage done to the item</p>
|
||||
*/
|
||||
public static short getDamage(ItemStack itemStack) {
|
||||
Damageable damageable = (Damageable) itemStack.getItemMeta();
|
||||
return (short) damageable.getDamage();
|
||||
}
|
||||
|
||||
private double getCost(ItemStack item, Player player) {
|
||||
DataKey root = config.getConfig().getKey("");
|
||||
String itemName = sanitizeItemName(item.getType().name());
|
||||
double price;
|
||||
if (root.keyExists("base-prices." + itemName)) {
|
||||
price = root.getDouble("base-prices." + itemName);
|
||||
} else {
|
||||
price = Setting.BASE_PRICE.asDouble();
|
||||
}
|
||||
|
||||
// Adjust price based on durability and enchantments
|
||||
if (this.useHyperAPI) {
|
||||
return getHyperAPICost(player, item, root, price);
|
||||
} else {
|
||||
double pricePerDurabilityPoint;
|
||||
if (root.keyExists("price-per-durability-point." + itemName)) {
|
||||
pricePerDurabilityPoint = root.getDouble("price-per-durability-point." + itemName);
|
||||
} else {
|
||||
pricePerDurabilityPoint = Setting.PRICE_PER_DURABILITY_POINT.asDouble();
|
||||
}
|
||||
if (config.getNaturalCost()) {
|
||||
//Cost increases with damage
|
||||
price += ((double) getDamage(item)) * pricePerDurabilityPoint;
|
||||
} else {
|
||||
//Cost decreases with damage
|
||||
price += ((double) getDurability(item)) * pricePerDurabilityPoint;
|
||||
}
|
||||
}
|
||||
|
||||
//Add the enchantment modifier for each enchantment on the item
|
||||
price += getEnchantmentCost(item, root);
|
||||
return price;
|
||||
}
|
||||
|
||||
private double getHyperAPICost(Player player, ItemStack item, DataKey root, double price) {
|
||||
// If using hyperConomy, price is calculated like so:
|
||||
// New Item Price + Enchantments Price (from hyperConomy) / maxDurability = price per durability point
|
||||
// Total price would then be base_price + price per durability point * current durability
|
||||
double hyperPrice = 0;
|
||||
HItemStack hi = hyperAPI.getHyperPlayer(player.getName()).getItemInHand();
|
||||
ItemStack item2 = player.getInventory().getItemInMainHand().clone();
|
||||
|
||||
for (TradeObject enchant : hyperAPI.getEnchantmentHyperObjects(hi, player.getName())) {
|
||||
hyperPrice = hyperPrice + enchant.getBuyPrice(1);
|
||||
Enchantment enchantment = Enchantment.getByKey(
|
||||
NamespacedKey.minecraft(enchant.getEnchantment().getEnchantmentName()));
|
||||
item2.removeEnchantment(Objects.requireNonNull(enchantment));
|
||||
}
|
||||
|
||||
ArrayList<Material> leathers = new ArrayList<>();
|
||||
leathers.add(Material.LEATHER_BOOTS);
|
||||
leathers.add(Material.LEATHER_CHESTPLATE);
|
||||
leathers.add(Material.LEATHER_HELMET);
|
||||
leathers.add(Material.LEATHER_LEGGINGS);
|
||||
|
||||
HItemStack hi3 = null;
|
||||
if (leathers.contains(player.getInventory().getItemInMainHand().getType())) {
|
||||
hi3 = bukkitConnector.getBukkitCommon().getSerializableItemStack(
|
||||
new ItemStack(player.getInventory().getItemInMainHand().getType()));
|
||||
}
|
||||
|
||||
TradeObject to = this.hyperAPI.getHyperObject(hi, "default");
|
||||
if (to == null) {
|
||||
to = hyperAPI.getHyperObject(hi3, "default");
|
||||
if (to == null) {
|
||||
HItemStack hi4 = bukkitConnector.getBukkitCommon().getSerializableItemStack(
|
||||
new ItemStack(player.getInventory().getItemInMainHand().getType()));
|
||||
to = this.hyperAPI.getHyperObject(hi4, "default");
|
||||
}
|
||||
hyperPrice = hyperPrice + to.getSellPrice(1);
|
||||
|
||||
} else {
|
||||
hyperPrice = to.getSellPrice(1);
|
||||
}
|
||||
double hyperPricePerDurability = hyperPrice / item.getType().getMaxDurability();
|
||||
price += getDurability(item) * hyperPricePerDurability;
|
||||
|
||||
price += getEnchantmentCost(item2, root);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost resulting from all enchantments on the given item
|
||||
*
|
||||
* @param item <p>The item to calculate enchantment cost for</p>
|
||||
* @param root <p>The data key containing the enchantment-modifiers option</p>
|
||||
* @return <p>The resulting enchantment cost</p>
|
||||
*/
|
||||
private double getEnchantmentCost(ItemStack item, DataKey root) {
|
||||
double enchantmentModifier = Setting.ENCHANTMENT_MODIFIER.asDouble();
|
||||
double price = 0;
|
||||
for (Enchantment enchantment : item.getEnchantments().keySet()) {
|
||||
String enchantmentKey = "enchantment-modifiers." + sanitizeItemName(enchantment.getKey().asString());
|
||||
if (root.keyExists(enchantmentKey)) {
|
||||
price += root.getDouble(enchantmentKey) * item.getEnchantmentLevel(enchantment);
|
||||
} else {
|
||||
price += enchantmentModifier * item.getEnchantmentLevel(enchantment);
|
||||
}
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
}
|
269
src/main/java/net/knarcraft/blacksmith/BlacksmithTrait.java
Normal file
269
src/main/java/net/knarcraft/blacksmith/BlacksmithTrait.java
Normal file
@ -0,0 +1,269 @@
|
||||
package net.knarcraft.blacksmith;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.knarcraft.blacksmith.config.Settings;
|
||||
import net.knarcraft.blacksmith.util.Sanitizer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.Sanitizer.sanitizedToItemName;
|
||||
|
||||
/**
|
||||
* The class representing the Blacksmith NPC trait
|
||||
*/
|
||||
public class BlacksmithTrait extends Trait {
|
||||
|
||||
private final BlacksmithPlugin plugin;
|
||||
private final List<Material> reforgeAbleItems = new ArrayList<>();
|
||||
private final Map<UUID, Calendar> coolDowns = new HashMap<>();
|
||||
private ReforgeSession session;
|
||||
private final Settings config;
|
||||
private long _sessionStart = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Instantiates a new blacksmith trait
|
||||
*/
|
||||
public BlacksmithTrait() {
|
||||
super("blacksmith");
|
||||
plugin = (BlacksmithPlugin) Bukkit.getServer().getPluginManager().getPlugin("Blacksmith");
|
||||
this.config = BlacksmithPlugin.getInstance().getSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cool-down for the given player's next blacksmith reforge
|
||||
*
|
||||
* @param playerUUID <p>The ID of the player to add the cool-down for</p>
|
||||
* @param waitUntil <p>The time when the player can interact again</p>
|
||||
*/
|
||||
public void addCoolDown(UUID playerUUID, Calendar waitUntil) {
|
||||
coolDowns.put(playerUUID, waitUntil);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets the session of this blacksmith, making it ready for another round
|
||||
*/
|
||||
public void unsetSession() {
|
||||
this.session = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) {
|
||||
for (DataKey sub : key.getRelative("reforge-able-items").getIntegerSubKeys()) {
|
||||
Material material = Material.getMaterial(sanitizedToItemName(sub.getString("")));
|
||||
if (material != null) {
|
||||
reforgeAbleItems.add(material);
|
||||
}
|
||||
}
|
||||
config.loadVariables(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
//Save all items the blacksmith knows how to reforge
|
||||
for (int i = 0; i < reforgeAbleItems.size(); i++) {
|
||||
key.getRelative("reforge-able-items").setString(String.valueOf(i), Sanitizer.sanitizeItemName(
|
||||
reforgeAbleItems.get(i).name()));
|
||||
}
|
||||
|
||||
//Save all other config values
|
||||
config.saveVariables(key);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onClick(PlayerInteractEvent event) {
|
||||
if (event.getHand() == null || (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() !=
|
||||
Action.RIGHT_CLICK_BLOCK)) {
|
||||
return;
|
||||
}
|
||||
//If the player is not looking at a blacksmith, there is no need to do anything
|
||||
Entity target = getTarget(event.getPlayer(), event.getPlayer().getLocation().getNearbyEntities(15, 10, 15));
|
||||
if (!CitizensAPI.getNPCRegistry().isNPC(target) ||
|
||||
!CitizensAPI.getNPCRegistry().getNPC(target).hasTrait(BlacksmithTrait.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Block armor equip if interacting with a blacksmith
|
||||
ItemStack usedItem = event.getPlayer().getInventory().getItem(event.getHand());
|
||||
if (usedItem != null && BlacksmithPlugin.isArmor(usedItem)) {
|
||||
event.setUseItemInHand(Event.Result.DENY);
|
||||
event.getPlayer().updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRightClick(net.citizensnpcs.api.event.NPCRightClickEvent event) {
|
||||
if (this.npc != event.getNPC()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Perform any necessary pre-session work
|
||||
Player player = event.getClicker();
|
||||
if (!prepareForSession(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (session != null) {
|
||||
//Continue the existing session
|
||||
continueSession(player);
|
||||
} else {
|
||||
//Start a new session
|
||||
startSession(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs necessary work before the session is started or continued
|
||||
*
|
||||
* @param player <p>The player to prepare the session for</p>
|
||||
* @return <p>True if preparations were successful. False if a session shouldn't be started</p>
|
||||
*/
|
||||
private boolean prepareForSession(Player player) {
|
||||
//If cool-down has been disabled after it was set for this player, remove the cool-down
|
||||
if (config.getDisableCoolDown() && coolDowns.get(player.getUniqueId()) != null) {
|
||||
coolDowns.remove(player.getUniqueId());
|
||||
}
|
||||
//Deny if permission is missing
|
||||
if (!player.hasPermission("blacksmith.reforge")) {
|
||||
return false;
|
||||
}
|
||||
//Deny if on cool-down, or remove cool-down if expired
|
||||
if (coolDowns.get(player.getUniqueId()) != null) {
|
||||
if (!Calendar.getInstance().after(coolDowns.get(player.getUniqueId()))) {
|
||||
player.sendMessage(config.getCoolDownUnexpiredMessage());
|
||||
return false;
|
||||
}
|
||||
coolDowns.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
//If already in a session, but the player has failed to interact, or left the blacksmith, allow a new session
|
||||
if (session != null) {
|
||||
if (System.currentTimeMillis() > _sessionStart + 10 * 1000 ||
|
||||
this.npc.getEntity().getLocation().distance(session.getPlayer().getLocation()) > 20) {
|
||||
session = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to continue the session for the given player
|
||||
*
|
||||
* @param player <p>The player to continue the session for</p>
|
||||
*/
|
||||
private void continueSession(Player player) {
|
||||
//Another player is using the blacksmith
|
||||
if (!session.isInSession(player)) {
|
||||
player.sendMessage(config.getBusyWithPlayerMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
//The blacksmith is already reforging for the player
|
||||
if (session.isRunning()) {
|
||||
player.sendMessage(config.getBusyReforgingMessage());
|
||||
return;
|
||||
}
|
||||
if (session.endSession()) {
|
||||
//Quit if the player cannot afford, or has changed their item
|
||||
session = null;
|
||||
} else {
|
||||
//Start reforging for the player
|
||||
reforge(npc, player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new session, and prepares to repair the player's item
|
||||
*
|
||||
* @param player <p>The player to start the session for</p>
|
||||
*/
|
||||
private void startSession(Player player) {
|
||||
ItemStack hand = player.getInventory().getItemInMainHand();
|
||||
//If not a tool, not armor, and not set in reforgeAbleItems, refuse to repair
|
||||
if ((!plugin.isTool(hand) && !BlacksmithPlugin.isArmor(hand)) ||
|
||||
(!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType()))) {
|
||||
player.sendMessage(config.getInvalidItemMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
//Start a new reforge session for the player
|
||||
_sessionStart = System.currentTimeMillis();
|
||||
session = new ReforgeSession(this, player, npc, config);
|
||||
|
||||
//Tell the player the cost of repairing the item
|
||||
String cost = plugin.formatCost(player);
|
||||
String itemName = hand.getType().name().toLowerCase().replace('_', ' ');
|
||||
player.sendMessage(config.getCostMessage().replace("<price>", cost).replace("<item>", itemName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts reforging the player's item
|
||||
*
|
||||
* @param npc <p>The NPC performing the reforge</p>
|
||||
* @param player <p>The player that initiated the reforge</p>
|
||||
*/
|
||||
private void reforge(NPC npc, Player player) {
|
||||
player.sendMessage(config.getStartReforgeMessage());
|
||||
plugin.withdraw(player);
|
||||
session.beginReforge();
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
|
||||
//Display the item in the NPC's hand
|
||||
if (npc.getEntity() instanceof Player) {
|
||||
((Player) npc.getEntity()).getInventory().setItemInMainHand(heldItem);
|
||||
} else {
|
||||
Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(heldItem);
|
||||
}
|
||||
//Remove the item from the player's inventory
|
||||
player.getInventory().setItemInMainHand(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the target-entity the entity is looking at
|
||||
*
|
||||
* @param entity <p>The entity looking at something</p>
|
||||
* @param entities <p>Entities near the player</p>
|
||||
* @param <T> <p>The type of entity the player is looking at</p>
|
||||
* @return <p>The entity the player is looking at, or null if no such entity exists</p>
|
||||
*/
|
||||
private static <T extends Entity> T getTarget(final Entity entity, final Iterable<T> entities) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
T target = null;
|
||||
final double threshold = 1;
|
||||
for (final T other : entities) {
|
||||
final Vector n = other.getLocation().toVector().subtract(entity.getLocation().toVector());
|
||||
if (entity.getLocation().getDirection().normalize().crossProduct(n).lengthSquared() < threshold &&
|
||||
n.normalize().dot(entity.getLocation().getDirection().normalize()) >= 0) {
|
||||
if (target == null ||
|
||||
target.getLocation().distanceSquared(entity.getLocation()) >
|
||||
other.getLocation().distanceSquared(entity.getLocation())) {
|
||||
target = other;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
}
|
166
src/main/java/net/knarcraft/blacksmith/ReforgeSession.java
Normal file
166
src/main/java/net/knarcraft/blacksmith/ReforgeSession.java
Normal file
@ -0,0 +1,166 @@
|
||||
package net.knarcraft.blacksmith;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.knarcraft.blacksmith.config.Settings;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* A representation of the session between a player and a blacksmith
|
||||
*/
|
||||
public class ReforgeSession implements Runnable {
|
||||
|
||||
private final BlacksmithTrait blacksmithTrait;
|
||||
private final Player player;
|
||||
private final NPC npc;
|
||||
private final ItemStack itemToReforge;
|
||||
private int taskId;
|
||||
private final Settings config;
|
||||
private static final String[] enchantments = new String[Enchantment.values().length];
|
||||
|
||||
/**
|
||||
* Instantiates a new session
|
||||
*
|
||||
* @param blacksmithTrait <p>A reference to the blacksmith trait</p>
|
||||
* @param player <p>The player initiating the session</p>
|
||||
* @param npc <p>The Blacksmith NPC involved in the session</p>
|
||||
* @param config <p>The config to use for the session</p>
|
||||
*/
|
||||
ReforgeSession(BlacksmithTrait blacksmithTrait, Player player, NPC npc, Settings config) {
|
||||
this.blacksmithTrait = blacksmithTrait;
|
||||
this.player = player;
|
||||
this.npc = npc;
|
||||
itemToReforge = player.getInventory().getItemInMainHand();
|
||||
this.config = config;
|
||||
|
||||
int i = 0;
|
||||
for (Enchantment enchantment : Enchantment.values()) {
|
||||
enchantments[i++] = enchantment.getKey().asString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
player.sendMessage(reforgeItemInHand() ? config.getSuccessMessage() : config.getFailMessage());
|
||||
if (npc.getEntity() instanceof Player) {
|
||||
((Player) npc.getEntity()).getInventory().setItemInMainHand(null);
|
||||
} else {
|
||||
Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(null);
|
||||
}
|
||||
if (!config.getDisableDelay()) {
|
||||
if (config.getDropItem()) {
|
||||
player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), itemToReforge);
|
||||
} else {
|
||||
player.getInventory().addItem(itemToReforge);
|
||||
}
|
||||
} else {
|
||||
player.getInventory().setItemInMainHand(itemToReforge);
|
||||
}
|
||||
blacksmithTrait.unsetSession();
|
||||
// Start cool down
|
||||
Calendar wait = Calendar.getInstance();
|
||||
wait.add(Calendar.SECOND, config.getReforgeCoolDown());
|
||||
blacksmithTrait.addCoolDown(player.getUniqueId(), wait);
|
||||
}
|
||||
|
||||
private boolean reforgeItemInHand() {
|
||||
Random random = new Random();
|
||||
if (random.nextInt(100) < config.getFailChance()) {
|
||||
for (Enchantment enchantment : itemToReforge.getEnchantments().keySet()) {
|
||||
// Remove or downgrade enchantments
|
||||
if (random.nextBoolean()) {
|
||||
itemToReforge.removeEnchantment(enchantment);
|
||||
} else {
|
||||
if (itemToReforge.getEnchantmentLevel(enchantment) > 1) {
|
||||
itemToReforge.removeEnchantment(enchantment);
|
||||
itemToReforge.addEnchantment(enchantment, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Damage the item
|
||||
short reforgeDurability = BlacksmithPlugin.getDurability(itemToReforge);
|
||||
short durability = (short) (reforgeDurability + reforgeDurability * random.nextInt(8));
|
||||
short maxDurability = itemToReforge.getType().getMaxDurability();
|
||||
if (durability <= 0) {
|
||||
durability = (short) (maxDurability / 3);
|
||||
} else if (reforgeDurability + durability > maxDurability) {
|
||||
durability = (short) (maxDurability - random.nextInt(maxDurability - 25));
|
||||
}
|
||||
updateDamage(itemToReforge, maxDurability - durability);
|
||||
return false;
|
||||
} else {
|
||||
updateDamage(itemToReforge, 0);
|
||||
|
||||
// Add random enchantments
|
||||
int roll = random.nextInt(100);
|
||||
if (roll < config.getExtraEnchantmentChance() && itemToReforge.getEnchantments().keySet().size() < config.getMaxEnchantments()) {
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.fromString(enchantments[random.nextInt(enchantments.length)]));
|
||||
if (Objects.requireNonNull(enchantment).canEnchantItem(itemToReforge)) {
|
||||
int randomBound = enchantment.getMaxLevel() - enchantment.getStartLevel();
|
||||
//A workaround for the random method's bound sometimes being negative
|
||||
if (randomBound >= 0) {
|
||||
itemToReforge.addEnchantment(enchantment, random.nextInt(randomBound) +
|
||||
enchantment.getStartLevel());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDamage(ItemStack item, int newDamage) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
Damageable damageable = (Damageable) meta;
|
||||
damageable.setDamage(newDamage);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
// Return if the session should end
|
||||
boolean endSession() {
|
||||
// Prevent player from switching items during session
|
||||
ItemStack itemInHand = player.getInventory().getItemInMainHand();
|
||||
if (!itemToReforge.equals(itemInHand)) {
|
||||
player.sendMessage(config.getItemChangedMessage());
|
||||
return true;
|
||||
}
|
||||
if (!BlacksmithPlugin.getInstance().doesPlayerHaveEnough(player)) {
|
||||
player.sendMessage(config.getInsufficientFundsMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isRunning() {
|
||||
return BlacksmithPlugin.getInstance().getServer().getScheduler().isQueued(taskId);
|
||||
}
|
||||
|
||||
boolean isInSession(Player other) {
|
||||
return player.getName().equals(other.getName());
|
||||
}
|
||||
|
||||
void beginReforge() {
|
||||
if (!config.getDisableCoolDown()) {
|
||||
taskId = BlacksmithPlugin.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(
|
||||
BlacksmithPlugin.getInstance(), this, (new Random().nextInt(config.getMaxReforgeDelay()) +
|
||||
config.getMinReforgeDelay()) * 20L);
|
||||
} else {
|
||||
taskId = BlacksmithPlugin.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(
|
||||
BlacksmithPlugin.getInstance(), this, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
151
src/main/java/net/knarcraft/blacksmith/config/Setting.java
Normal file
151
src/main/java/net/knarcraft/blacksmith/config/Setting.java
Normal file
@ -0,0 +1,151 @@
|
||||
package net.knarcraft.blacksmith.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* An enum representing all of Blacksmith's settings
|
||||
*/
|
||||
public enum Setting {
|
||||
|
||||
BASE_PRICE("base-prices.default", 10.0),
|
||||
PRICE_PER_DURABILITY_POINT("price-per-durability-point.default", 1.0),
|
||||
BUSY_WITH_PLAYER_MESSAGE("defaults.messages.busy-with-player", "§cI'm busy at the moment. Come back later!"),
|
||||
BUSY_WITH_REFORGE_MESSAGE("defaults.messages.busy-with-reforge", "§cI'm working on it. Be patient!"),
|
||||
COOL_DOWN_UNEXPIRED_MESSAGE(
|
||||
"defaults.messages.cool-down-not-expired",
|
||||
"§cYou've already had your chance! Give me a break!"),
|
||||
COST_MESSAGE(
|
||||
"defaults.messages.cost",
|
||||
"§eIt will cost §a<price> §eto reforge that §a<item>§e! Click again to reforge!"),
|
||||
DROP_ITEM("defaults.drop-item", true),
|
||||
DISABLE_COOL_DOWN("defaults.disable-cool-down", false),
|
||||
DISABLE_DELAY("defaults.disable-delay", false),
|
||||
ENCHANTMENT_MODIFIER("enchantment-modifiers.default", 5),
|
||||
FAIL_CHANCE("defaults.percent-chance-to-fail-reforge", 10),
|
||||
FAIL_MESSAGE("defaults.messages.fail-reforge", "§cWhoops! Didn't mean to do that! Maybe next time?"),
|
||||
INSUFFICIENT_FUNDS_MESSAGE(
|
||||
"defaults.messages.insufficient-funds",
|
||||
"§cYou don't have enough money to reforge that item!"),
|
||||
INVALID_ITEM_MESSAGE("defaults.messages.invalid-item", "§cI'm sorry, but I don't know how to reforge that!"),
|
||||
ITEM_UNEXPECTEDLY_CHANGED_MESSAGE(
|
||||
"defaults.messages.item-changed-during-reforge",
|
||||
"§cThat's not the item you wanted to reforge before!"),
|
||||
EXTRA_ENCHANTMENT_CHANCE("defaults.percent-chance-for-extra-enchantment", 5),
|
||||
MAX_ENCHANTMENTS("defaults.maximum-enchantments", 3),
|
||||
MAX_REFORGE_DELAY("defaults.delays-in-seconds.maximum", 30),
|
||||
MIN_REFORGE_DELAY("defaults.delays-in-seconds.minimum", 5),
|
||||
REFORGE_COOL_DOWN("defaults.delays-in-seconds.reforge-cool-down", 60),
|
||||
START_REFORGE_MESSAGE("defaults.messages.start-reforge", "§eOk, let's see what I can do..."),
|
||||
SUCCESS_MESSAGE("defaults.messages.successful-reforge", "There you go! All better!"),
|
||||
NATURAL_COST("defaults.natural-cost", true);
|
||||
|
||||
private final String path;
|
||||
private final String childPath;
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Instantiates a new setting
|
||||
*
|
||||
* @param path <p>The full config path for this setting</p>
|
||||
* @param value <p>The default value of this setting</p>
|
||||
*/
|
||||
Setting(String path, Object value) {
|
||||
this.path = path;
|
||||
this.value = value;
|
||||
String[] pathParts = path.split("\\.");
|
||||
this.childPath = String.join(".", Arrays.copyOfRange(pathParts, 1, pathParts.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full config path for this setting
|
||||
*
|
||||
* @return <p>The full config path for this setting</p>
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the config path without the root node
|
||||
*
|
||||
* @return <p>The config path without the root node</p>
|
||||
*/
|
||||
public String getChildPath() {
|
||||
return childPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this setting as a boolean
|
||||
*
|
||||
* <p>This will throw an exception if used for a non-boolean value</p>
|
||||
*
|
||||
* @return <p>This setting as a boolean</p>
|
||||
*/
|
||||
public boolean asBoolean() {
|
||||
if (value instanceof String) {
|
||||
return Boolean.parseBoolean((String) value);
|
||||
} else {
|
||||
return (Boolean) value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this setting as a double
|
||||
*
|
||||
* <p>This will throw an exception if used for a non-double setting</p>
|
||||
*
|
||||
* @return <p>This setting as a double</p>
|
||||
*/
|
||||
public double asDouble() {
|
||||
if (value instanceof String) {
|
||||
return Double.parseDouble((String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
return (Integer) value;
|
||||
} else {
|
||||
return (Double) value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this setting as an integer
|
||||
*
|
||||
* <p>This will throw an exception if used for a non-integer setting</p>
|
||||
*
|
||||
* @return <p>This setting as an integer</p>
|
||||
*/
|
||||
public int asInt() {
|
||||
if (value instanceof String) {
|
||||
return Integer.parseInt((String) value);
|
||||
} else {
|
||||
return (Integer) value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this setting as a string
|
||||
*
|
||||
* @return <p>This setting as a string</p>
|
||||
*/
|
||||
public String asString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this setting
|
||||
*
|
||||
* @return <p>The value of this setting</p>
|
||||
*/
|
||||
Object get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this setting
|
||||
*
|
||||
* @param value <p>The new value of this setting</p>
|
||||
*/
|
||||
void set(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
357
src/main/java/net/knarcraft/blacksmith/config/Settings.java
Normal file
357
src/main/java/net/knarcraft/blacksmith/config/Settings.java
Normal file
@ -0,0 +1,357 @@
|
||||
package net.knarcraft.blacksmith.config;
|
||||
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.YamlStorage;
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* A class which keeps track of all Blacksmith settings/config values
|
||||
*/
|
||||
public class Settings {
|
||||
|
||||
private String busyWithPlayerMessage = Setting.BUSY_WITH_PLAYER_MESSAGE.asString();
|
||||
private String busyReforgingMessage = Setting.BUSY_WITH_REFORGE_MESSAGE.asString();
|
||||
private String costMessage = Setting.COST_MESSAGE.asString();
|
||||
private String invalidItemMessage = Setting.INVALID_ITEM_MESSAGE.asString();
|
||||
private String startReforgeMessage = Setting.START_REFORGE_MESSAGE.asString();
|
||||
private String successMessage = Setting.SUCCESS_MESSAGE.asString();
|
||||
private String failMessage = Setting.FAIL_MESSAGE.asString();
|
||||
private String insufficientFundsMessage = Setting.INSUFFICIENT_FUNDS_MESSAGE.asString();
|
||||
private String coolDownUnexpiredMessage = Setting.COOL_DOWN_UNEXPIRED_MESSAGE.asString();
|
||||
private String itemChangedMessage = Setting.ITEM_UNEXPECTEDLY_CHANGED_MESSAGE.asString();
|
||||
private int minReforgeDelay = Setting.MIN_REFORGE_DELAY.asInt();
|
||||
private int maxReforgeDelay = Setting.MAX_REFORGE_DELAY.asInt();
|
||||
private int reforgeCoolDown = Setting.REFORGE_COOL_DOWN.asInt();
|
||||
private int failChance = Setting.FAIL_CHANCE.asInt();
|
||||
private int extraEnchantmentChance = Setting.EXTRA_ENCHANTMENT_CHANCE.asInt();
|
||||
private int maxEnchantments = Setting.MAX_ENCHANTMENTS.asInt();
|
||||
private boolean dropItem = Setting.DROP_ITEM.asBoolean();
|
||||
private boolean disableCoolDown = Setting.DISABLE_COOL_DOWN.asBoolean();
|
||||
private boolean disableDelay = Setting.DISABLE_DELAY.asBoolean();
|
||||
private boolean naturalCost = Setting.NATURAL_COST.asBoolean();
|
||||
private final YamlStorage config;
|
||||
|
||||
/**
|
||||
* Instantiates a new "Settings"
|
||||
*
|
||||
* @param plugin <p>A reference to the blacksmith plugin</p>
|
||||
*/
|
||||
public Settings(BlacksmithPlugin plugin) {
|
||||
config = 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
|
||||
config.load();
|
||||
DataKey root = config.getKey("");
|
||||
for (Setting setting : Setting.values()) {
|
||||
if (!root.keyExists(setting.getPath())) {
|
||||
//If the setting does not exist in the config file, add it
|
||||
root.setRaw(setting.getPath(), setting.get());
|
||||
} else {
|
||||
//Set the setting to the value found in the path
|
||||
setting.set(root.getRaw(setting.getPath()));
|
||||
}
|
||||
}
|
||||
//Save any modified values to disk
|
||||
config.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration used for saving/loading from disk
|
||||
*
|
||||
* @return <p>The configuration</p>
|
||||
*/
|
||||
public YamlStorage getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads variables from the given data key
|
||||
*
|
||||
* @param key <p>The data key to load variables from</p>
|
||||
*/
|
||||
public void loadVariables(DataKey key) {
|
||||
// Override defaults if they exist
|
||||
if (key.keyExists(Setting.BUSY_WITH_PLAYER_MESSAGE.getChildPath())) {
|
||||
busyWithPlayerMessage = key.getString(Setting.BUSY_WITH_PLAYER_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.BUSY_WITH_REFORGE_MESSAGE.getChildPath())) {
|
||||
busyReforgingMessage = key.getString(Setting.BUSY_WITH_REFORGE_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.COST_MESSAGE.getChildPath())) {
|
||||
costMessage = key.getString(Setting.COST_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.INVALID_ITEM_MESSAGE.getChildPath())) {
|
||||
invalidItemMessage = key.getString(Setting.INVALID_ITEM_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.START_REFORGE_MESSAGE.getChildPath())) {
|
||||
startReforgeMessage = key.getString(Setting.START_REFORGE_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.SUCCESS_MESSAGE.getChildPath())) {
|
||||
successMessage = key.getString(Setting.SUCCESS_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.FAIL_MESSAGE.getChildPath())) {
|
||||
failMessage = key.getString(Setting.FAIL_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.INSUFFICIENT_FUNDS_MESSAGE.getChildPath())) {
|
||||
insufficientFundsMessage = key.getString(Setting.INSUFFICIENT_FUNDS_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.COOL_DOWN_UNEXPIRED_MESSAGE.getChildPath())) {
|
||||
coolDownUnexpiredMessage = key.getString(Setting.COOL_DOWN_UNEXPIRED_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.ITEM_UNEXPECTEDLY_CHANGED_MESSAGE.getChildPath())) {
|
||||
itemChangedMessage = key.getString(Setting.ITEM_UNEXPECTEDLY_CHANGED_MESSAGE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.MIN_REFORGE_DELAY.getChildPath())) {
|
||||
minReforgeDelay = key.getInt(Setting.MIN_REFORGE_DELAY.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.MAX_REFORGE_DELAY.getChildPath())) {
|
||||
maxReforgeDelay = key.getInt(Setting.MAX_REFORGE_DELAY.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.REFORGE_COOL_DOWN.getChildPath())) {
|
||||
reforgeCoolDown = key.getInt(Setting.REFORGE_COOL_DOWN.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.FAIL_CHANCE.getChildPath())) {
|
||||
failChance = key.getInt(Setting.FAIL_CHANCE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.MAX_ENCHANTMENTS.getChildPath())) {
|
||||
maxEnchantments = key.getInt(Setting.MAX_ENCHANTMENTS.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.EXTRA_ENCHANTMENT_CHANCE.getChildPath())) {
|
||||
extraEnchantmentChance = key.getInt(Setting.EXTRA_ENCHANTMENT_CHANCE.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.DROP_ITEM.getChildPath())) {
|
||||
dropItem = key.getBoolean(Setting.DROP_ITEM.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.DISABLE_COOL_DOWN.getChildPath())) {
|
||||
disableCoolDown = key.getBoolean(Setting.DISABLE_COOL_DOWN.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.DISABLE_DELAY.getChildPath())) {
|
||||
disableDelay = key.getBoolean(Setting.DISABLE_DELAY.getChildPath());
|
||||
}
|
||||
if (key.keyExists(Setting.NATURAL_COST.getChildPath())) {
|
||||
naturalCost = key.getBoolean(Setting.NATURAL_COST.getChildPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves variables to the given data key
|
||||
*
|
||||
* @param key <p>The data key to save variables to</p>
|
||||
*/
|
||||
public void saveVariables(DataKey key) {
|
||||
//This saves variables to the specific NPC.
|
||||
key.setString(Setting.BUSY_WITH_PLAYER_MESSAGE.getChildPath(), getBusyWithPlayerMessage());
|
||||
key.setString(Setting.BUSY_WITH_REFORGE_MESSAGE.getChildPath(), getBusyReforgingMessage());
|
||||
key.setString(Setting.COST_MESSAGE.getChildPath(), getCostMessage());
|
||||
key.setString(Setting.INVALID_ITEM_MESSAGE.getChildPath(), getInvalidItemMessage());
|
||||
key.setString(Setting.START_REFORGE_MESSAGE.getChildPath(), getStartReforgeMessage());
|
||||
key.setString(Setting.SUCCESS_MESSAGE.getChildPath(), getSuccessMessage());
|
||||
key.setString(Setting.FAIL_MESSAGE.getChildPath(), getFailMessage());
|
||||
key.setString(Setting.INSUFFICIENT_FUNDS_MESSAGE.getChildPath(), getInsufficientFundsMessage());
|
||||
key.setString(Setting.COOL_DOWN_UNEXPIRED_MESSAGE.getChildPath(), getCoolDownUnexpiredMessage());
|
||||
key.setString(Setting.ITEM_UNEXPECTEDLY_CHANGED_MESSAGE.getChildPath(), getItemChangedMessage());
|
||||
key.setInt(Setting.MIN_REFORGE_DELAY.getChildPath(), getMinReforgeDelay());
|
||||
key.setInt(Setting.MAX_REFORGE_DELAY.getChildPath(), getMaxReforgeDelay());
|
||||
key.setInt(Setting.REFORGE_COOL_DOWN.getChildPath(), getReforgeCoolDown());
|
||||
key.setInt(Setting.FAIL_CHANCE.getChildPath(), getFailChance());
|
||||
key.setInt(Setting.EXTRA_ENCHANTMENT_CHANCE.getChildPath(), getExtraEnchantmentChance());
|
||||
key.setInt(Setting.MAX_ENCHANTMENTS.getChildPath(), getMaxEnchantments());
|
||||
key.setBoolean(Setting.DROP_ITEM.getChildPath(), getDropItem());
|
||||
key.setBoolean(Setting.DISABLE_DELAY.getChildPath(), getDisableDelay());
|
||||
key.setBoolean(Setting.DISABLE_COOL_DOWN.getChildPath(), getDisableCoolDown());
|
||||
key.setBoolean(Setting.DISABLE_COOL_DOWN.getChildPath(), getDisableCoolDown());
|
||||
key.setBoolean(Setting.NATURAL_COST.getChildPath(), getNaturalCost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when the blacksmith is busy with another player
|
||||
*
|
||||
* @return <p>The busy with player message</p>
|
||||
*/
|
||||
public String getBusyWithPlayerMessage() {
|
||||
return busyWithPlayerMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when the blacksmith is busy with reforging an item
|
||||
*
|
||||
* @return <p>The busy reforging message</p>
|
||||
*/
|
||||
public String getBusyReforgingMessage() {
|
||||
return busyReforgingMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to use for displaying an item's cost
|
||||
*
|
||||
* @return <p>The message to use for displaying item cost</p>
|
||||
*/
|
||||
public String getCostMessage() {
|
||||
return costMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a blacksmith has been given an invalid item
|
||||
*
|
||||
* @return <p>The invalid item message</p>
|
||||
*/
|
||||
public String getInvalidItemMessage() {
|
||||
return invalidItemMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a blacksmith starts reforging an item
|
||||
*
|
||||
* @return <p>The start reforge message</p>
|
||||
*/
|
||||
public String getStartReforgeMessage() {
|
||||
return startReforgeMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a blacksmith has successfully repaired an item
|
||||
*
|
||||
* @return <p>The reforge success message</p>
|
||||
*/
|
||||
public String getSuccessMessage() {
|
||||
return successMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a blacksmith has failed to repair an item
|
||||
*
|
||||
* @return <p>The reforge fail message</p>
|
||||
*/
|
||||
public String getFailMessage() {
|
||||
return failMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a player cannot afford re-forging an item
|
||||
*
|
||||
* @return <p>The insufficient funds message</p>
|
||||
*/
|
||||
public String getInsufficientFundsMessage() {
|
||||
return insufficientFundsMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a blacksmith is still affected by a cool-down
|
||||
*
|
||||
* @return <p>The cool down unexpired message</p>
|
||||
*/
|
||||
public String getCoolDownUnexpiredMessage() {
|
||||
return coolDownUnexpiredMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a player has changed the item they're trying to reforge
|
||||
*
|
||||
* @return <p>The item changed message</p>
|
||||
*/
|
||||
public String getItemChangedMessage() {
|
||||
return itemChangedMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum delay used to wait for a re-forge to finish.
|
||||
*
|
||||
* @return <p>The minimum reforge delay</p>
|
||||
*/
|
||||
public int getMinReforgeDelay() {
|
||||
return minReforgeDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum delay used to wait for a re-forge to finish
|
||||
*
|
||||
* @return <p>The maximum reforge delay</p>
|
||||
*/
|
||||
public int getMaxReforgeDelay() {
|
||||
return maxReforgeDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cool-down between each reforge
|
||||
*
|
||||
* @return <p>The reforge cool-down</p>
|
||||
*/
|
||||
public int getReforgeCoolDown() {
|
||||
return reforgeCoolDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chance to fail a re-forge
|
||||
*
|
||||
* @return <p>The fail chance</p>
|
||||
*/
|
||||
public int getFailChance() {
|
||||
return failChance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chance for adding an extra enchantment to an item
|
||||
*
|
||||
* @return <p>The extra enchantment chance</p>
|
||||
*/
|
||||
public int getExtraEnchantmentChance() {
|
||||
return extraEnchantmentChance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the max number of enchantment to add to an item
|
||||
*
|
||||
* @return <p>The maximum enchantments</p>
|
||||
*/
|
||||
public int getMaxEnchantments() {
|
||||
return maxEnchantments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether an item should be dropped on the ground instead of being given to the player
|
||||
*
|
||||
* @return <p>Whether to drop reforged items on the ground</p>
|
||||
*/
|
||||
public boolean getDropItem() {
|
||||
return dropItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to disable the reforge-cool-down
|
||||
*
|
||||
* @return <p>Whether to disable the reforge-cool-down</p>
|
||||
*/
|
||||
public boolean getDisableCoolDown() {
|
||||
return disableCoolDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to disable the delay between starting reforging and the re-forge finishing
|
||||
*
|
||||
* @return <p>Whether to disable the reforge delay</p>
|
||||
*/
|
||||
public boolean getDisableDelay() {
|
||||
return disableDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to use a natural cost calculation
|
||||
*
|
||||
* <p>The natural cost makes repairs more expensive the more damaged an item is, rather than the opposite.</p>
|
||||
*
|
||||
* @return <p>Whether to use a natural cost calculation</p>
|
||||
*/
|
||||
public boolean getNaturalCost() {
|
||||
return naturalCost;
|
||||
}
|
||||
|
||||
}
|
29
src/main/java/net/knarcraft/blacksmith/util/Sanitizer.java
Normal file
29
src/main/java/net/knarcraft/blacksmith/util/Sanitizer.java
Normal file
@ -0,0 +1,29 @@
|
||||
package net.knarcraft.blacksmith.util;
|
||||
|
||||
public final class Sanitizer {
|
||||
|
||||
private Sanitizer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes an item name to the format used by this plugin
|
||||
*
|
||||
* @param itemName <p>The item name to sanitize</p>
|
||||
* @return <p>The sanitized name</p>
|
||||
*/
|
||||
public static String sanitizeItemName(String itemName) {
|
||||
return itemName.toLowerCase().replace('_', '-');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a sanitized item name to the original name
|
||||
*
|
||||
* @param itemName <p>The item name to convert</p>
|
||||
* @return <p>The un-sanitized name</p>
|
||||
*/
|
||||
public static String sanitizedToItemName(String itemName) {
|
||||
return itemName.toUpperCase().replace('-', '_');
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user