initial commit
This commit is contained in:
commit
bca7427c1c
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/bin
|
||||
/build
|
||||
/target
|
||||
.classpath
|
||||
.project
|
||||
Blacksmith.jar
|
||||
build.xml
|
12
.settings/org.eclipse.jdt.core.prefs
Normal file
12
.settings/org.eclipse.jdt.core.prefs
Normal file
@ -0,0 +1,12 @@
|
||||
#Thu Feb 09 16:52:58 CST 2012
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
BIN
lib/CitizensAPI.jar
Normal file
BIN
lib/CitizensAPI.jar
Normal file
Binary file not shown.
BIN
lib/bukkit-1.1-R3.jar
Normal file
BIN
lib/bukkit-1.1-R3.jar
Normal file
Binary file not shown.
4
plugin.yml
Normal file
4
plugin.yml
Normal file
@ -0,0 +1,4 @@
|
||||
name: Blacksmith
|
||||
author: aPunch
|
||||
version: 1.0
|
||||
main: net.apunch.blacksmith.Blacksmith
|
118
src/net/apunch/blacksmith/Blacksmith.java
Normal file
118
src/net/apunch/blacksmith/Blacksmith.java
Normal file
@ -0,0 +1,118 @@
|
||||
package net.apunch.blacksmith;
|
||||
|
||||
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.util.DataKey;
|
||||
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Blacksmith extends JavaPlugin {
|
||||
private Settings config;
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
config.save();
|
||||
|
||||
getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " disabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
config = new Settings(this);
|
||||
config.load();
|
||||
|
||||
CitizensAPI.getCharacterManager().register(BlacksmithCharacter.class);
|
||||
|
||||
getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " enabled.");
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
189
src/net/apunch/blacksmith/BlacksmithCharacter.java
Normal file
189
src/net/apunch/blacksmith/BlacksmithCharacter.java
Normal file
@ -0,0 +1,189 @@
|
||||
package net.apunch.blacksmith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.apunch.blacksmith.util.Settings.Setting;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.trait.Character;
|
||||
import net.citizensnpcs.api.npc.trait.SaveId;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
@SaveId("blacksmith")
|
||||
public class BlacksmithCharacter extends Character {
|
||||
private final Blacksmith plugin;
|
||||
private final List<Material> reforgeableItems = new ArrayList<Material>();
|
||||
private RepairSession 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 int minReforgeDelay = Setting.MIN_REFORGE_DELAY.asInt();
|
||||
private int maxReforgeDelay = Setting.MAX_REFORGE_DELAY.asInt();
|
||||
private int failChance = Setting.FAIL_CHANCE.asInt();
|
||||
|
||||
public BlacksmithCharacter() {
|
||||
plugin = (Blacksmith) Bukkit.getServer().getPluginManager().getPlugin("Blacksmith");
|
||||
}
|
||||
|
||||
@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("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("percent-chance-to-fail-reforge"))
|
||||
failChance = key.getInt("percent-chance-to-fail-reforge");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRightClick(NPC npc, Player player) {
|
||||
// TODO cooldowns
|
||||
ItemStack hand = player.getItemInHand();
|
||||
if (session != null) {
|
||||
if (!session.isInSession(player)) {
|
||||
npc.chat(busyWithPlayerMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (session.isRunning()) {
|
||||
npc.chat(player, 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()))) {
|
||||
npc.chat(player, invalidItemMsg);
|
||||
return;
|
||||
}
|
||||
session = new RepairSession(player, npc);
|
||||
npc.chat(player, costMsg.replace("<price>", String.valueOf(plugin.getCost(hand))).replace("<item>",
|
||||
hand.getType().name().toLowerCase().replace('_', ' ')));
|
||||
}
|
||||
}
|
||||
|
||||
@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.setInt("delays-in-seconds.minimum", minReforgeDelay);
|
||||
key.setInt("delays-in-seconds.maximum", maxReforgeDelay);
|
||||
key.setInt("percent-chance-to-fail-reforge", failChance);
|
||||
}
|
||||
|
||||
public String getInsufficientFundsMessage() {
|
||||
return insufficientFundsMsg;
|
||||
}
|
||||
|
||||
private void reforge(NPC npc, Player player) {
|
||||
npc.chat(player, startReforgeMsg);
|
||||
session.setTask(plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin,
|
||||
new ReforgeTask(npc, player), (new Random().nextInt(maxReforgeDelay) + minReforgeDelay) * 20));
|
||||
player.setItemInHand(null);
|
||||
}
|
||||
|
||||
private class ReforgeTask implements Runnable {
|
||||
private final NPC npc;
|
||||
private final Player player;
|
||||
private final ItemStack reforge;
|
||||
|
||||
private ReforgeTask(NPC npc, Player player) {
|
||||
this.npc = npc;
|
||||
this.player = player;
|
||||
reforge = player.getItemInHand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
npc.chat(player, reforgeItemInHand() ? successMsg : failMsg);
|
||||
player.getWorld().dropItemNaturally(npc.getBukkitEntity().getLocation(), reforge);
|
||||
session = null;
|
||||
}
|
||||
|
||||
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
|
||||
if (random.nextInt(3) == 0) {
|
||||
reforge.setDurability(reforge.getDurability() + reforge.getDurability() * random.nextInt(3) < reforge
|
||||
.getType().getMaxDurability() ? (short) (reforge.getDurability() + reforge.getDurability()
|
||||
* random.nextInt(3)) : (short) (reforge.getType().getMaxDurability() - 10));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int chance = 50;
|
||||
if (reforge.getDurability() == 0)
|
||||
chance *= 2;
|
||||
else
|
||||
reforge.setDurability((short) 0);
|
||||
// Add random enchantments
|
||||
for (int i = 0; i < chance; i++) {
|
||||
int id = random.nextInt(100);
|
||||
Enchantment enchantment = Enchantment.getById(id);
|
||||
if (enchantment != null && enchantment.canEnchantItem(reforge))
|
||||
reforge.addEnchantment(Enchantment.getById(id), random.nextInt(enchantment.getMaxLevel()) + 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
48
src/net/apunch/blacksmith/RepairSession.java
Normal file
48
src/net/apunch/blacksmith/RepairSession.java
Normal file
@ -0,0 +1,48 @@
|
||||
package net.apunch.blacksmith;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class RepairSession {
|
||||
private final Blacksmith plugin;
|
||||
private final Player player;
|
||||
private final ItemStack reforge;
|
||||
private final NPC npc;
|
||||
private int taskId;
|
||||
|
||||
public RepairSession(Player player, NPC npc) {
|
||||
this.player = player;
|
||||
reforge = player.getItemInHand();
|
||||
this.npc = npc;
|
||||
|
||||
plugin = (Blacksmith) player.getServer().getPluginManager().getPlugin("Blacksmith");
|
||||
}
|
||||
|
||||
// Return is the session should end
|
||||
public boolean handleClick() {
|
||||
// Prevent player from switching items during session
|
||||
if (!reforge.equals(player.getItemInHand())) {
|
||||
npc.chat(player, "<c>That's not the item you wanted to reforge before!");
|
||||
return true;
|
||||
}
|
||||
if (plugin.getCost(player.getItemInHand()) < 0 /* TODO hasEnough */) {
|
||||
npc.chat(player, ((BlacksmithCharacter) npc.getCharacter()).getInsufficientFundsMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return plugin.getServer().getScheduler().isQueued(taskId);
|
||||
}
|
||||
|
||||
public boolean isInSession(Player other) {
|
||||
return player.getName().equals(other.getName());
|
||||
}
|
||||
|
||||
public void setTask(int taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
}
|
87
src/net/apunch/blacksmith/util/Settings.java
Normal file
87
src/net/apunch/blacksmith/util/Settings.java
Normal file
@ -0,0 +1,87 @@
|
||||
package net.apunch.blacksmith.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.apunch.blacksmith.Blacksmith;
|
||||
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.YamlStorage;
|
||||
|
||||
public class Settings {
|
||||
private final YamlStorage config;
|
||||
|
||||
public Settings(Blacksmith plugin) {
|
||||
config = new YamlStorage(plugin.getDataFolder() + File.separator + "config.yml", "Blacksmith Configuration");
|
||||
}
|
||||
|
||||
public void load() {
|
||||
DataKey root = config.getKey("");
|
||||
for (Setting setting : Setting.values())
|
||||
if (!root.keyExists(setting.path))
|
||||
root.setRaw(setting.path, setting.get());
|
||||
else
|
||||
setting.set(root.getRaw(setting.path));
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public YamlStorage getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public enum Setting {
|
||||
BASE_PRICE("base-prices.default", 10),
|
||||
BUSY_WITH_PLAYER_MESSAGE("defaults.messages.busy-with-player", "<c>I'm busy at the moment. Come back later!"),
|
||||
BUSY_WITH_REFORGE_MESSAGE("defaults.messages.busy-with-reforge", "<c>I'm working on it. Be patient!"),
|
||||
COST_MESSAGE("defaults.messages.cost", "<e>It will cost <a><price> <e>to reforge that <a><item><e>! Click again to reforge!"),
|
||||
ENCHANTMENT_MODIFIER("enchantment-modifiers.default", 5),
|
||||
FAIL_CHANCE("defaults.percent-chance-to-fail-reforge", 10),
|
||||
FAIL_MESSAGE("defaults.messages.fail-reforge", "<c>Whoops! Didn't mean to do that! Maybe next time?"),
|
||||
INSUFFICIENT_FUNDS_MESSAGE("defaults.messages.insufficient-funds", "<c>You don't have enough money to reforge that item!"),
|
||||
INVALID_ITEM_MESSAGE("defaults.messages.invalid-item", "<c>I'm sorry, but I don't know how to reforge that!"),
|
||||
MAX_REFORGE_DELAY("defaults.delays-in-seconds.maximum", 30),
|
||||
MIN_REFORGE_DELAY("defaults.delays-in-seconds.minimum", 5),
|
||||
START_REFORGE_MESSAGE("defaults.messages.start-reforge", "<e>Ok, let's see what I can do..."),
|
||||
SUCCESS_MESSAGE("defaults.messages.successful-reforge", "<a>There you go! All better!");
|
||||
|
||||
private String path;
|
||||
private Object value;
|
||||
|
||||
Setting(String path, Object value) {
|
||||
this.path = path;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean asBoolean() {
|
||||
return (Boolean) value;
|
||||
}
|
||||
|
||||
public double asDouble() {
|
||||
if (value instanceof String)
|
||||
return Double.valueOf((String) value);
|
||||
if (value instanceof Integer)
|
||||
return (Integer) value;
|
||||
return (Double) value;
|
||||
}
|
||||
|
||||
public int asInt() {
|
||||
return (Integer) value;
|
||||
}
|
||||
|
||||
public String asString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
private Object get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private void set(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user