diff --git a/lib/HyperConomy.jar b/lib/HyperConomy.jar
new file mode 100644
index 0000000..1197186
Binary files /dev/null and b/lib/HyperConomy.jar differ
diff --git a/plugin.yml b/plugin.yml
new file mode 100644
index 0000000..5f7b60b
--- /dev/null
+++ b/plugin.yml
@@ -0,0 +1,11 @@
+name: Blacksmith
+author: aPunch, jrbudda, HurricanKai
+version: 1.12
+main: net.apunch.blacksmith.BlacksmithPlugin
+depend: [Citizens, Vault]
+softdepend: [HyperConomy]
+
+commands:
+ blacksmithreload:
+ permission: blacksmith.reload
+ description: reloads the config file for Blacksmith
diff --git a/pom.xml b/pom.xml
index d7b0646..7cdbebc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,75 +1,87 @@
- 4.0.0
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
- net.apunch
- blacksmith
- 1.0-SNAPSHOT
- Blacksmith
- Blacksmith Character for the CitizensAPI
+ net.apunch
+ blacksmith
+ 1.12-SNAPSHOT
+ Blacksmith
+ Blacksmith Character for the CitizensAPI
-
-
- UTF-8
- 1.2.5-R0.1-SNAPSHOT
- 2.0-SNAPSHOT
- 1.2.13-SNAPSHOT
- Unknown
-
+
+
+ UTF-8
+ 1.10.2-R0.1-SNAPSHOT
+ 2.0.20-SNAPSHOT
+ 1.5.6
+ 0.975.7-SNAPSHOT
+ Unknown
+
-
-
+
+
- bukkit-repo
- http://repo.bukkit.org/content/groups/public/
+ spigot-repo
+ https://hub.spigotmc.org/nexus/content/groups/public/
citizens-repo
- http://repo.citizensnpcs.net/
+ http://ci.citizensnpcs.co/job/Citizens2/lastSuccessfulBuild/maven-repository/repository/
vault-repo
- http://ci.milkbowl.net/plugin/repository/everything
+ http://nexus.hc.to/content/repositories/pub_releases
-
+
+ grokswell-repo
+ http://www.grokswell.com:8000/repo/
+
+
-
-
-
+
+
+
+ net.citizensnpcs
+ citizensapi
+ 2.0.22-SNAPSHOT
+ jar
+ compile
+
+
org.bukkit
bukkit
${bukkit.version}
provided
+
+ net.milkbowl.vault
+ Vault
+ ${vault.version}
+ provided
+
- net.citizensnpcs
- citizensapi
- ${citizensapi.version}
+ regalowl.hyperconomy
+ hyperconomy
+ ${hyperconomy.version}
provided
-
-
- net.milkbowl.vault
- Vault
- ${vault.version}
- provided
-
-
+
+
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 2.3.2
-
-
- 1.6
-
-
-
-
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.5.1
+
+
+ 1.6
+
+
+
+
-
\ No newline at end of file
+
diff --git a/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java b/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java
index 536f8df..649621c 100644
--- a/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java
+++ b/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java
@@ -1,149 +1,288 @@
package net.apunch.blacksmith;
+import java.util.ArrayList;
import java.util.logging.Level;
import net.apunch.blacksmith.util.Settings;
import net.apunch.blacksmith.util.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
-import net.citizensnpcs.api.npc.character.CharacterFactory;
+import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.DataKey;
import net.milkbowl.vault.economy.Economy;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.OfflinePlayer;
+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.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
+import regalowl.hyperconomy.HyperAPI;
+import regalowl.hyperconomy.HyperConomy;
+import regalowl.hyperconomy.bukkit.BukkitConnector;
+import regalowl.hyperconomy.inventory.HItemStack;
+import regalowl.hyperconomy.tradeobject.TradeObject;
+
+
public class BlacksmithPlugin extends JavaPlugin {
- private Settings config;
- private Economy economy;
+ public BlacksmithPlugin plugin;
+ private Settings config;
+ private Economy economy;
+ private HyperAPI hyperAPI;
+ private BukkitConnector bukCon;
+ private boolean useHyperAPI = false;
+ //private boolean hasCititrader = false; // CitiTrader dependency outdated and broken
- @Override
- public void onDisable() {
- config.save();
+ @Override
+ public void onDisable() {
+ // config.save();
- getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " disabled.");
- }
+ getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " disabled.");
+ }
- @Override
- public void onEnable() {
- config = new Settings(this);
+ @Override
+ public void onEnable() {
+ config = new Settings(this);
+ config.load();
+ // 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.
+ 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 hcPlugin = getServer().getPluginManager().getPlugin("HyperConomy");
+ bukCon = (BukkitConnector)hcPlugin;
+ HyperConomy hc = bukCon.getHC();
+ this.hyperAPI = (HyperAPI) hc.getAPI();
+ }
+ getLogger().log(Level.INFO, "Setting Up Vault now....");
+ /* CitiTrader dependency outdated and broken
+ // Check for Cititrader
+ if(getServer().getPluginManager().getPlugin("CitiTrader") != null) {
+ hasCititrader = true;
+ }
+ */
+
+ boolean canload = SetupVault();
+ if (!canload)
+ {
+ getLogger().log(Level.INFO, "Vault Failed....");
+ getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+ CitizensAPI.getTraitFactory().registerTrait(net.citizensnpcs.api.trait.TraitInfo.create(BlacksmithTrait.class).withName("blacksmith"));
+
+
+ getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " enabled.");
+ }
+
+ private boolean SetupVault() {
+ // Setup Vault
+ RegisteredServiceProvider 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 Command command, final String label, final String[] args) {
config.load();
+ sender.sendMessage(ChatColor.GREEN + "Blacksmith config reloaded!");
+ return true;
+ }
- // Setup Vault
- RegisteredServiceProvider economyProvider = getServer().getServicesManager().getRegistration(
- Economy.class);
- if (economyProvider != null)
- economy = economyProvider.getProvider();
- else {
- // Disable if no economy plugin was found
- getServer().getLogger().log(Level.SEVERE, "Failed to load an economy plugin. Disabling...");
- getServer().getPluginManager().disablePlugin(this);
- return;
+ /* CitiTrader dependency outdated and broken
+ // Return if we have cititrader
+ public boolean hasCititrader() {
+ return this.hasCititrader;
+ }
+ */
+
+ public BlacksmithTrait getBlacksmith(NPC npc){
+
+ if (npc !=null && npc.hasTrait(BlacksmithTrait.class)){
+ return npc.getTrait(BlacksmithTrait.class);
+ }
+
+ return null;
+ }
+
+
+ public boolean isTool(ItemStack item) {
+ switch (item.getType()) {
+ case WOOD_PICKAXE:
+ case WOOD_SPADE:
+ case WOOD_HOE:
+ case WOOD_SWORD:
+ case WOOD_AXE:
+ case STONE_PICKAXE:
+ case STONE_SPADE:
+ case STONE_HOE:
+ case STONE_SWORD:
+ case STONE_AXE:
+ case GOLD_PICKAXE:
+ case GOLD_SPADE:
+ case GOLD_HOE:
+ case GOLD_SWORD:
+ case GOLD_AXE:
+ case IRON_PICKAXE:
+ case IRON_SPADE:
+ case IRON_HOE:
+ case IRON_SWORD:
+ case IRON_AXE:
+ case DIAMOND_PICKAXE:
+ case DIAMOND_SPADE:
+ case DIAMOND_HOE:
+ case DIAMOND_SWORD:
+ case DIAMOND_AXE:
+ case BOW:
+ case FLINT_AND_STEEL:
+ case FISHING_ROD:
+ case SHEARS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isArmor(ItemStack item) {
+ switch (item.getType()) {
+ case LEATHER_HELMET:
+ case LEATHER_CHESTPLATE:
+ case LEATHER_LEGGINGS:
+ case LEATHER_BOOTS:
+ case CHAINMAIL_HELMET:
+ case CHAINMAIL_CHESTPLATE:
+ case CHAINMAIL_LEGGINGS:
+ case CHAINMAIL_BOOTS:
+ case GOLD_HELMET:
+ case GOLD_CHESTPLATE:
+ case GOLD_LEGGINGS:
+ case GOLD_BOOTS:
+ case IRON_HELMET:
+ case IRON_CHESTPLATE:
+ case IRON_LEGGINGS:
+ case IRON_BOOTS:
+ case DIAMOND_HELMET:
+ case DIAMOND_CHESTPLATE:
+ case DIAMOND_LEGGINGS:
+ case DIAMOND_BOOTS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean doesPlayerHaveEnough(Player player) {
+ return economy.getBalance((OfflinePlayer) player) - getCost(player.getItemInHand(), player) >= 0;
+ }
+
+ public String formatCost(Player player) {
+ double cost = getCost(player.getItemInHand(), player);
+ return economy.format(cost);
+ }
+
+ public void withdraw(Player player) {
+ economy.withdrawPlayer(((OfflinePlayer) player), getCost(player.getItemInHand(), player));
+ }
+ /* CitiTrader dependency outdated and broken.
+ public void deposit(NPC npc, Player player) {
+// if(hasCititrader) {
+// if(npc.hasTrait(WalletTrait.class)) {
+// npc.getTrait(WalletTrait.class).deposit(getCost(player.getItemInHand()));
+// }
+// }
}
+ */
- CitizensAPI.getCharacterManager().registerCharacter(
- new CharacterFactory(Blacksmith.class).withName("blacksmith"));
+ private double getCost(ItemStack item, Player player) {
+ DataKey root = config.getConfig().getKey("");
+ double price = Setting.BASE_PRICE.asDouble();
+ if (root.keyExists("base-prices." + item.getType().name().toLowerCase().replace('_', '-')))
+ price = root.getDouble("base-prices." + item.getType().name().toLowerCase().replace('_', '-'));
- getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " enabled.");
- }
+ // Adjust price based on durability and enchantments
+ if (this.useHyperAPI) {
+ // 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 durablity point * current durability
+ double hyperPrice = 0;
+ HItemStack hi = hyperAPI.getHyperPlayer(player.getName()).getItemInHand();
+ ItemStack item2 = player.getItemInHand().clone();
+
+ for (TradeObject enchant : hyperAPI.getEnchantmentHyperObjects(hi, player.getName())) {
+ hyperPrice = hyperPrice + enchant.getBuyPrice(1);
+ item2.removeEnchantment(Enchantment.getByName(enchant.getEnchantment().getEnchantmentName()));
+ }
+
+ ArrayList 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.getItemInHand().getType())){
+ hi3 = bukCon.getBukkitCommon().getSerializableItemStack(new ItemStack(player.getItemInHand().getType()));
+ }
+
+ TradeObject to = this.hyperAPI.getHyperObject(hi, "default");
+ if (to==null) {
+ to = hyperAPI.getHyperObject(hi3, "default");
+ if (to==null) {
+ HItemStack hi4 = bukCon.getBukkitCommon().getSerializableItemStack(new ItemStack(player.getItemInHand().getType()));
+ to = this.hyperAPI.getHyperObject(hi4, "default");
+ }
+ hyperPrice = hyperPrice+to.getSellPrice(1);
+
+ } else {
+ hyperPrice = to.getSellPrice(1);
+ }
+ double hyperPricePerDurability = hyperPrice / item.getType().getMaxDurability();
+ price += (item.getDurability() * hyperPricePerDurability);
+
+ double enchantmentModifier = Setting.ENCHANTMENT_MODIFIER.asDouble();
+ for (Enchantment enchantment : item2.getEnchantments().keySet()) {
+ if (root.keyExists("enchantment-modifiers." + enchantment.getName().toLowerCase().replace('_', '-')))
+ enchantmentModifier = root.getDouble("enchantment-modifiers."
+ + enchantment.getName().toLowerCase().replace('_', '-'));
+ price += enchantmentModifier * item2.getEnchantmentLevel(enchantment);
+ }
+
+
+ return price;
+ }
- public boolean isTool(ItemStack item) {
- switch (item.getType()) {
- case WOOD_PICKAXE:
- case WOOD_SPADE:
- case WOOD_HOE:
- case WOOD_SWORD:
- case WOOD_AXE:
- case STONE_PICKAXE:
- case STONE_SPADE:
- case STONE_HOE:
- case STONE_SWORD:
- case STONE_AXE:
- case GOLD_PICKAXE:
- case GOLD_SPADE:
- case GOLD_HOE:
- case GOLD_SWORD:
- case GOLD_AXE:
- case IRON_PICKAXE:
- case IRON_SPADE:
- case IRON_HOE:
- case IRON_SWORD:
- case IRON_AXE:
- case DIAMOND_PICKAXE:
- case DIAMOND_SPADE:
- case DIAMOND_HOE:
- case DIAMOND_SWORD:
- case DIAMOND_AXE:
- case BOW:
- case FLINT_AND_STEEL:
- case FISHING_ROD:
- case SHEARS:
- return true;
- default:
- return false;
- }
- }
+ else {
+ if (root.keyExists("price-per-durability-point." + item.getType().name().toLowerCase().replace('_', '-')))
+ price += item.getDurability() * root.getDouble("price-per-durability-point." + item.getType().name().toLowerCase().replace('_', '-'));
+ else price += (item.getDurability() * Setting.PRICE_PER_DURABILITY_POINT.asDouble());
+ }
- public boolean isArmor(ItemStack item) {
- switch (item.getType()) {
- case LEATHER_HELMET:
- case LEATHER_CHESTPLATE:
- case LEATHER_LEGGINGS:
- case LEATHER_BOOTS:
- case CHAINMAIL_HELMET:
- case CHAINMAIL_CHESTPLATE:
- case CHAINMAIL_LEGGINGS:
- case CHAINMAIL_BOOTS:
- case GOLD_HELMET:
- case GOLD_CHESTPLATE:
- case GOLD_LEGGINGS:
- case GOLD_BOOTS:
- case IRON_HELMET:
- case IRON_CHESTPLATE:
- case IRON_LEGGINGS:
- case IRON_BOOTS:
- case DIAMOND_HELMET:
- case DIAMOND_CHESTPLATE:
- case DIAMOND_LEGGINGS:
- case DIAMOND_BOOTS:
- return true;
- default:
- return false;
- }
- }
-
- public boolean doesPlayerHaveEnough(Player player) {
- return economy.getBalance(player.getName()) - getCost(player.getItemInHand()) >= 0;
- }
-
- public String formatCost(Player player) {
- return economy.format(getCost(player.getItemInHand()));
- }
-
- public void withdraw(Player player) {
- economy.withdrawPlayer(player.getName(), getCost(player.getItemInHand()));
- }
-
- private double getCost(ItemStack item) {
- DataKey root = config.getConfig().getKey("");
- double price = Setting.BASE_PRICE.asDouble();
- if (root.keyExists("base-prices." + item.getType().name().toLowerCase().replace('_', '-')))
- price = root.getDouble("base-prices." + item.getType().name().toLowerCase().replace('_', '-'));
-
- // Adjust price based on durability and enchantments
- price += (item.getType().getMaxDurability() - item.getDurability());
-
- double enchantmentModifier = Setting.ENCHANTMENT_MODIFIER.asDouble();
- for (Enchantment enchantment : item.getEnchantments().keySet()) {
- if (root.keyExists("enchantment-modifiers." + enchantment.getName().toLowerCase().replace('_', '-')))
- enchantmentModifier = root.getDouble("enchantment-modifiers."
- + enchantment.getName().toLowerCase().replace('_', '-'));
- price += enchantmentModifier * item.getEnchantmentLevel(enchantment);
- }
- return price;
- }
-}
\ No newline at end of file
+ double enchantmentModifier = Setting.ENCHANTMENT_MODIFIER.asDouble();
+ for (Enchantment enchantment : item.getEnchantments().keySet()) {
+ if (root.keyExists("enchantment-modifiers." + enchantment.getName().toLowerCase().replace('_', '-')))
+ enchantmentModifier = root.getDouble("enchantment-modifiers."
+ + enchantment.getName().toLowerCase().replace('_', '-'));
+ price += enchantmentModifier * item.getEnchantmentLevel(enchantment);
+ }
+ return price;
+ }
+}
diff --git a/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java b/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java
new file mode 100644
index 0000000..5b8d380
--- /dev/null
+++ b/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java
@@ -0,0 +1,345 @@
+package net.apunch.blacksmith;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.inventory.ItemStack;
+
+import net.apunch.blacksmith.util.Settings.Setting;
+
+import net.citizensnpcs.api.npc.NPC;
+import net.citizensnpcs.api.trait.Trait;
+import net.citizensnpcs.api.util.DataKey;
+
+public class BlacksmithTrait extends Trait {
+ private static final String[] enchantments = new String[Enchantment.values().length];
+
+ private final BlacksmithPlugin plugin;
+ private final List reforgeableItems = new ArrayList();
+ private final Map cooldowns = new HashMap();
+ private ReforgeSession session;
+
+ // Defaults
+ private String busyWithPlayerMsg = Setting.BUSY_WITH_PLAYER_MESSAGE.asString();
+ private String busyReforgingMsg = Setting.BUSY_WITH_REFORGE_MESSAGE.asString();
+ private String costMsg = Setting.COST_MESSAGE.asString();
+ private String invalidItemMsg = Setting.INVALID_ITEM_MESSAGE.asString();
+ private String startReforgeMsg = Setting.START_REFORGE_MESSAGE.asString();
+ private String successMsg = Setting.SUCCESS_MESSAGE.asString();
+ private String failMsg = Setting.FAIL_MESSAGE.asString();
+ private String insufficientFundsMsg = Setting.INSUFFICIENT_FUNDS_MESSAGE.asString();
+ private String cooldownUnexpiredMsg = Setting.COOLDOWN_UNEXPIRED_MESSAGE.asString();
+ private String itemChangedMsg = 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_COOLDOWN.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_COOLDOWN.asBoolean();
+ private boolean disabledelay = Setting.DISABLE_DELAY.asBoolean();
+
+ public BlacksmithTrait() {
+ super("blacksmith");
+ plugin = (BlacksmithPlugin) Bukkit.getServer().getPluginManager().getPlugin("Blacksmith");
+ int i = 0;
+ for (Enchantment enchantment : Enchantment.values())
+ enchantments[i++] = enchantment.getName();
+ }
+
+ @Override
+ public void load(DataKey key) {
+ for (DataKey sub : key.getRelative("reforgeable-items").getIntegerSubKeys())
+ if (Material.getMaterial(sub.getString("").toUpperCase().replace('-', '_')) != null)
+ reforgeableItems.add(Material.getMaterial(sub.getString("").toUpperCase().replace('-', '_')));
+
+ // Override defaults if they exist
+ if (key.keyExists("messages.busy-with-player"))
+ busyWithPlayerMsg = key.getString("messages.busy-with-player");
+ if (key.keyExists("messages.busy-with-reforge"))
+ busyReforgingMsg = key.getString("messages.busy-with-reforge");
+ if (key.keyExists("messages.cost"))
+ costMsg = key.getString("messages.cost");
+ if (key.keyExists("messages.invalid-item"))
+ invalidItemMsg = key.getString("messages.invalid-item");
+ if (key.keyExists("messages.start-reforge"))
+ startReforgeMsg = key.getString("messages.start-reforge");
+ if (key.keyExists("messages.successful-reforge"))
+ successMsg = key.getString("messages.successful-reforge");
+ if (key.keyExists("messages.fail-reforge"))
+ failMsg = key.getString("messages.fail-reforge");
+ if (key.keyExists("messages.insufficient-funds"))
+ insufficientFundsMsg = key.getString("messages.insufficient-funds");
+ if (key.keyExists("messages.cooldown-not-expired"))
+ cooldownUnexpiredMsg = key.getString("messages.cooldown-not-expired");
+ if (key.keyExists("messages.item-changed-during-reforge"))
+ itemChangedMsg = key.getString("messages.item-changed-during-reforge");
+ if (key.keyExists("delays-in-seconds.minimum"))
+ minReforgeDelay = key.getInt("delays-in-seconds.minimum");
+ if (key.keyExists("delays-in-seconds.maximum"))
+ maxReforgeDelay = key.getInt("delays-in-seconds.maximum");
+ if (key.keyExists("delays-in-seconds.reforge-cooldown"))
+ reforgeCooldown = key.getInt("delays-in-seconds.reforge-cooldown");
+ if (key.keyExists("percent-chance-to-fail-reforge"))
+ failChance = key.getInt("percent-chance-to-fail-reforge");
+ if (key.keyExists("maximum-enchantments"))
+ maxEnchantments = key.getInt("maximum-enchantments");
+ if (key.keyExists("extra-enchantments-chance"))
+ extraEnchantmentChance = key.getInt("extra-enchantment-chance");
+ if (key.keyExists("drop-item"))
+ dropItem = key.getBoolean("drop-item");
+ if (key.keyExists("disable-cooldown"))
+ disablecooldown = key.getBoolean("disable-cooldown");
+ if (key.keyExists("disable-delay"))
+ disabledelay = key.getBoolean("disable-delay");
+ }
+
+ @EventHandler
+ public void onRightClick(net.citizensnpcs.api.event.NPCRightClickEvent event) {
+ if(this.npc!=event.getNPC()) return;
+
+ Player player = event.getClicker();
+ if ((disablecooldown & (cooldowns.get(player.getName()) != (null))))
+ {
+ cooldowns.remove(player.getName());
+ }
+ if (!player.hasPermission("blacksmith.reforge"))
+ return;
+
+ if (cooldowns.get(player.getName()) != null) {
+ if (!Calendar.getInstance().after(cooldowns.get(player.getName()))) {
+ player.sendMessage(cooldownUnexpiredMsg);
+ return;
+ }
+ cooldowns.remove(player.getName());
+ }
+
+
+ ItemStack hand = player.getItemInHand();
+
+ if(session!=null){
+ //timeout
+ if ( System.currentTimeMillis() > _sessionstart + 10*1000 || this.npc.getEntity().getLocation().distance(session.player.getLocation()) > 20 ){
+ session = null;
+ }
+ }
+
+
+ if (session != null) {
+ if (!session.isInSession(player)) {
+
+ player.sendMessage( busyWithPlayerMsg);
+ return;
+
+ }
+
+ if (session.isRunning()) {
+ player.sendMessage( busyReforgingMsg);
+ return;
+ }
+ if (session.handleClick())
+ session = null;
+ else
+ reforge(npc, player);
+ } else {
+ if ((!plugin.isTool(hand) && !plugin.isArmor(hand))
+ || (!reforgeableItems.isEmpty() && !reforgeableItems.contains(hand.getType()))) {
+ player.sendMessage( invalidItemMsg);
+ return;
+ }
+
+ String cost = plugin.formatCost(player);
+
+ _sessionstart = System.currentTimeMillis();
+ session = new ReforgeSession(player, npc);
+ player.sendMessage(costMsg.replace("", cost).replace("- ",
+ hand.getType().name().toLowerCase().replace('_', ' ')));
+
+ }
+ }
+
+ private long _sessionstart = System.currentTimeMillis();
+
+ @Override
+ public void save(DataKey key) {
+ for (int i = 0; i < reforgeableItems.size(); i++)
+ key.getRelative("reforgeable-items").setString(String.valueOf(i),
+ reforgeableItems.get(i).name().toLowerCase().replace('_', '-'));
+
+ key.setString("messages.busy-with-player", busyWithPlayerMsg);
+ key.setString("messages.busy-with-reforge", busyReforgingMsg);
+ key.setString("messages.cost", costMsg);
+ key.setString("messages.invalid-item", invalidItemMsg);
+ key.setString("messages.start-reforge", startReforgeMsg);
+ key.setString("messages.successful-reforge", successMsg);
+ key.setString("messages.fail-reforge", failMsg);
+ key.setString("messages.insufficient-funds", insufficientFundsMsg);
+ key.setString("messages.cooldown-not-expired", cooldownUnexpiredMsg);
+ key.setString("messages.item-changed-during-reforge", itemChangedMsg);
+ key.setInt("delays-in-seconds.minimum", minReforgeDelay);
+ key.setInt("delays-in-seconds.maximum", maxReforgeDelay);
+ key.setInt("delays-in-seconds.reforge-cooldown", reforgeCooldown);
+ key.setInt("percent-chance-to-fail-reforge", failChance);
+ key.setInt("percent-chance-for-extra-enchantment", extraEnchantmentChance);
+ key.setInt("maximum-enchantments", maxEnchantments);
+ key.setBoolean("drop-item", dropItem);
+ key.setBoolean("disable-delay", disabledelay);
+ key.setBoolean("disable-cooldown", disablecooldown);
+ }
+
+ private void reforge(NPC npc, Player player) {
+ player.sendMessage( startReforgeMsg);
+
+ //plugin.deposit(npc, player); // CitiTrader dependency outdated and broken
+
+ plugin.withdraw(player);
+ session.beginReforge();
+ if (npc.getEntity() instanceof Player)
+ ((Player) npc.getEntity()).setItemInHand(player.getItemInHand());
+ else
+ ((LivingEntity) npc.getEntity()).getEquipment().setItemInHand(player.getItemInHand());
+ player.setItemInHand(null);
+ }
+
+ private class ReforgeSession implements Runnable {
+ private final Player player;
+ private final NPC npc;
+ private final ItemStack reforge;
+ private int taskId;
+
+ private ReforgeSession(Player player, NPC npc) {
+ this.player = player;
+ this.npc = npc;
+ reforge = player.getItemInHand();
+ }
+
+ @Override
+ public void run() {
+ player.sendMessage("dropitem:" + dropItem);
+ player.sendMessage( reforgeItemInHand() ? successMsg : failMsg);
+ if (npc.getEntity() instanceof Player)
+ ((Player) npc.getEntity()).setItemInHand(null);
+ else
+ ((LivingEntity) npc.getEntity()).getEquipment().setItemInHand(null);
+ if (!disabledelay)
+ {
+ if (dropItem)
+ player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), reforge);
+ else {
+ player.getInventory().addItem(reforge);
+ /*
+ oldmethode ?
+ for (ItemStack stack : player.getInventory().addItem(reforge).values())
+ player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), stack);
+ */
+ }
+ }
+ else
+ {
+ player.setItemInHand(reforge);
+ }
+ session = null;
+ // Start cooldown
+ Calendar wait = Calendar.getInstance();
+ wait.add(Calendar.SECOND, reforgeCooldown);
+ cooldowns.put(player.getName(), wait);
+ }
+
+ private boolean reforgeItemInHand() {
+ Random random = new Random();
+ if (random.nextInt(100) < failChance) {
+ for (Enchantment enchantment : reforge.getEnchantments().keySet()) {
+ // Remove or downgrade enchantments
+ if (random.nextBoolean())
+ reforge.removeEnchantment(enchantment);
+ else {
+ if (reforge.getEnchantmentLevel(enchantment) > 1) {
+ reforge.removeEnchantment(enchantment);
+ reforge.addEnchantment(enchantment, 1);
+ }
+ }
+ }
+ // Damage the item
+ short durability = (short) (reforge.getDurability() + reforge.getDurability() * random.nextInt(8));
+ short maxDurability = reforge.getType().getMaxDurability();
+ if (durability <= 0)
+ durability = (short) (maxDurability / 3);
+ else if (reforge.getDurability() + durability > maxDurability)
+ durability = (short) (maxDurability - random.nextInt(maxDurability - 25));
+ reforge.setDurability(durability);
+ return false;
+ }
+
+ reforge.setDurability((short) 0);
+
+ // Add random enchantments
+
+
+ // If durability is full, chance is multiplied by 4. Seems unbalanced, so disabled for now.
+ /*if (reforge.getDurability() == 0)
+ chance *= 4;
+ else */
+
+ int roll = random.nextInt(100);
+ if (roll < extraEnchantmentChance && reforge.getEnchantments().keySet().size() < maxEnchantments){
+
+ Enchantment enchantment = Enchantment.getByName(enchantments[random.nextInt(enchantments.length)]);
+ if (enchantment.canEnchantItem(reforge)) reforge.addEnchantment(enchantment, random.nextInt(enchantment.getMaxLevel() - enchantment.getStartLevel()) + enchantment.getStartLevel());
+
+ }
+
+ return true;
+ }
+
+ // Return if the session should end
+ private boolean handleClick() {
+ // Prevent player from switching items during session
+ if (!reforge.equals(player.getItemInHand())) {
+ player.sendMessage( itemChangedMsg);
+ return true;
+ }
+ if (!plugin.doesPlayerHaveEnough(player)) {
+ player.sendMessage( insufficientFundsMsg);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isRunning() {
+ return plugin.getServer().getScheduler().isQueued(taskId);
+ }
+
+ private boolean isInSession(Player other) {
+ return player.getName().equals(other.getName());
+ }
+
+ private void beginReforge() {
+ if (!disablecooldown)
+ {
+ taskId = plugin
+ .getServer()
+ .getScheduler()
+ .scheduleSyncDelayedTask(plugin, this,
+ (new Random().nextInt(maxReforgeDelay) + minReforgeDelay) * 20);
+ }
+ else
+ {
+ taskId = plugin
+ .getServer()
+ .getScheduler()
+ .scheduleSyncDelayedTask(plugin, this,0);
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/apunch/blacksmith/util/Settings.java b/src/main/java/net/apunch/blacksmith/util/Settings.java
index 7bfc7ba..d693efd 100644
--- a/src/main/java/net/apunch/blacksmith/util/Settings.java
+++ b/src/main/java/net/apunch/blacksmith/util/Settings.java
@@ -11,10 +11,11 @@ public class Settings {
private final YamlStorage config;
public Settings(BlacksmithPlugin plugin) {
- config = new YamlStorage(plugin.getDataFolder() + File.separator + "config.yml", "Blacksmith Configuration");
+ config = new YamlStorage(new File(plugin.getDataFolder() + File.separator + "config.yml"), "Blacksmith Configuration");
}
public void load() {
+ config.load();
DataKey root = config.getKey("");
for (Setting setting : Setting.values())
if (!root.keyExists(setting.path))
@@ -22,10 +23,6 @@ public class Settings {
else
setting.set(root.getRaw(setting.path));
- save();
- }
-
- public void save() {
config.save();
}
@@ -35,31 +32,35 @@ public class Settings {
public enum Setting {
BASE_PRICE("base-prices.default", 10),
- BUSY_WITH_PLAYER_MESSAGE("defaults.messages.busy-with-player", "I'm busy at the moment. Come back later!"),
- BUSY_WITH_REFORGE_MESSAGE("defaults.messages.busy-with-reforge", "I'm working on it. Be patient!"),
+ PRICE_PER_DURABILITY_POINT("price-per-durability-point.default", 1),
+ 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!"),
COOLDOWN_UNEXPIRED_MESSAGE(
"defaults.messages.cooldown-not-expired",
- "You've already had your chance! Give me a break!"),
+ "§cYou've already had your chance! Give me a break!"),
COST_MESSAGE(
"defaults.messages.cost",
- "It will cost to reforge that
- ! Click again to reforge!"),
- DROP_ITEM("defaults.drop-item", true),
+ "§eIt will cost §a §eto reforge that §a
- §e! Click again to reforge!"),
+ DROP_ITEM("defaults.dropitem", true),
+ DISABLE_COOLDOWN("defaults.disablecooldown", false),
+ DISABLE_DELAY("defaults.disabledelay", false),
ENCHANTMENT_MODIFIER("enchantment-modifiers.default", 5),
FAIL_CHANCE("defaults.percent-chance-to-fail-reforge", 10),
- FAIL_MESSAGE("defaults.messages.fail-reforge", "Whoops! Didn't mean to do that! Maybe next time?"),
+ FAIL_MESSAGE("defaults.messages.fail-reforge", "§cWhoops! Didn't mean to do that! Maybe next time?"),
INSUFFICIENT_FUNDS_MESSAGE(
"defaults.messages.insufficient-funds",
- "You don't have enough money to reforge that item!"),
- INVALID_ITEM_MESSAGE("defaults.messages.invalid-item", "I'm sorry, but I don't know how to reforge that!"),
+ "§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",
- "That's not the item you wanted to reforge before!"),
+ "§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_COOLDOWN("defaults.delays-in-seconds.reforge-cooldown", 60),
- START_REFORGE_MESSAGE("defaults.messages.start-reforge", "Ok, let's see what I can do..."),
- SUCCESS_MESSAGE("defaults.messages.successful-reforge", "There you go! All better!");
+ 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!");
private String path;
private Object value;