diff --git a/.metadata/.lock b/.metadata/.lock
new file mode 100644
index 0000000..e69de29
diff --git a/.metadata/.log b/.metadata/.log
new file mode 100644
index 0000000..e921336
--- /dev/null
+++ b/.metadata/.log
@@ -0,0 +1,58 @@
+!SESSION 2012-06-01 20:37:35.859 -----------------------------------------------
+eclipse.buildId=I20120518-2145
+java.version=1.6.0_31
+java.vendor=Sun Microsystems Inc.
+BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_US
+Command-line arguments: -os win32 -ws win32 -arch x86 -data C:\Documents and Settings\Charles\.ssh\Blacksmith
+
+!ENTRY org.eclipse.help.base 4 0 2012-06-01 20:39:24.500
+!MESSAGE An error occured while pre-processing help XHTML document "/org.eclipse.platform.doc.user/whatsNew/platform_whatsnew.html" for search indexing
+!STACK 0
+org.xml.sax.SAXParseException: Attribute name "allowfullscreen" associated with an element type "iframe" must be followed by the ' = ' character.
+ at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
+ at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
+ at org.eclipse.help.internal.dynamic.DocumentReader.read(DocumentReader.java:56)
+ at org.eclipse.help.internal.dynamic.XMLProcessor.process(XMLProcessor.java:49)
+ at org.eclipse.help.internal.xhtml.DynamicXHTMLProcessor.process(DynamicXHTMLProcessor.java:76)
+ at org.eclipse.help.internal.search.XHTMLSearchParticipant.preprocess(XHTMLSearchParticipant.java:106)
+ at org.eclipse.help.search.SearchParticipantXML.addDocument(SearchParticipantXML.java:296)
+ at org.eclipse.help.internal.search.HTMLSearchParticipant.addDocument(HTMLSearchParticipant.java:51)
+ at org.eclipse.help.internal.search.SearchIndex.addDocument(SearchIndex.java:231)
+ at org.eclipse.help.internal.search.IndexingOperation.addDocuments(IndexingOperation.java:252)
+ at org.eclipse.help.internal.search.IndexingOperation.addNewDocuments(IndexingOperation.java:159)
+ at org.eclipse.help.internal.search.IndexingOperation.execute(IndexingOperation.java:106)
+ at org.eclipse.help.internal.search.LocalSearchManager.updateIndex(LocalSearchManager.java:671)
+ at org.eclipse.help.internal.search.LocalSearchManager.ensureIndexUpdated(LocalSearchManager.java:645)
+ at org.eclipse.help.internal.search.federated.IndexerJob.run(IndexerJob.java:31)
+ at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
+
+!ENTRY org.eclipse.help.base 4 4 2012-06-01 20:39:24.593
+!MESSAGE Help documentation could not be indexed completely.
+!SUBENTRY 1 org.eclipse.help.base 4 4 2012-06-01 20:39:24.593
+!MESSAGE Exception occurred while adding document /org.eclipse.platform.doc.user/whatsNew/platform_whatsnew.html to index.
+!STACK 0
+org.xml.sax.SAXParseException: Premature end of file.
+ at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
+ at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
+ at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
+ at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
+ at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
+ at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
+ at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
+ at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
+ at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
+ at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
+ at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
+ at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
+ at javax.xml.parsers.SAXParser.parse(Unknown Source)
+ at javax.xml.parsers.SAXParser.parse(Unknown Source)
+ at org.eclipse.help.search.SearchParticipantXML.addDocument(SearchParticipantXML.java:297)
+ at org.eclipse.help.internal.search.HTMLSearchParticipant.addDocument(HTMLSearchParticipant.java:51)
+ at org.eclipse.help.internal.search.SearchIndex.addDocument(SearchIndex.java:231)
+ at org.eclipse.help.internal.search.IndexingOperation.addDocuments(IndexingOperation.java:252)
+ at org.eclipse.help.internal.search.IndexingOperation.addNewDocuments(IndexingOperation.java:159)
+ at org.eclipse.help.internal.search.IndexingOperation.execute(IndexingOperation.java:106)
+ at org.eclipse.help.internal.search.LocalSearchManager.updateIndex(LocalSearchManager.java:671)
+ at org.eclipse.help.internal.search.LocalSearchManager.ensureIndexUpdated(LocalSearchManager.java:645)
+ at org.eclipse.help.internal.search.federated.IndexerJob.run(IndexerJob.java:31)
+ at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
new file mode 100644
index 0000000..25cb955
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
new file mode 100644
index 0000000..3c42dfe
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
new file mode 100644
index 0000000..6b2aaa7
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/4.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/4.tree
new file mode 100644
index 0000000..8f1b97f
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/4.tree differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
new file mode 100644
index 0000000..bc94672
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..dffc6b5
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+version=1
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs
new file mode 100644
index 0000000..9dd00d6
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=\r\n\r\n
+preferredTargets=default\:default|
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..18669b6
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..50d885d
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_VM_XML=\r\n\r\n\r\n\r\n\r\n\r\n
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..63ff9b1
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,18 @@
+content_assist_number_of_computers=13
+content_assist_proposals_background=255,255,255
+content_assist_proposals_foreground=0,0,0
+eclipse.preferences.version=1
+fontPropagated=true
+org.eclipse.jdt.ui.editor.tab.width=
+org.eclipse.jdt.ui.formatterprofiles.version=12
+org.eclipse.jdt.ui.javadoclocations.migrated=true
+org.eclipse.jdt.ui.text.code_templates_migrated=true
+org.eclipse.jdt.ui.text.custom_code_templates=
+org.eclipse.jdt.ui.text.custom_templates=
+org.eclipse.jdt.ui.text.templates_migrated=true
+org.eclipse.jface.textfont=1|Courier New|10.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Courier New;
+proposalOrderMigrated=true
+spelling_locale_initialized=true
+tabWidthPropagated=true
+useAnnotationsPrefPage=true
+useQuickDiffPrefPage=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.search.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.search.prefs
new file mode 100644
index 0000000..cec65c4
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.search.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.search.defaultPerspective=org.eclipse.search.defaultPerspective.none
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs
new file mode 100644
index 0000000..f9e585b
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+pref_first_startup=false
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs
new file mode 100644
index 0000000..56cd496
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.team.ui.first_time=false
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs
new file mode 100644
index 0000000..61f3bb8
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+overviewRuler_migration=migrated_3.1
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
new file mode 100644
index 0000000..dac418a
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
@@ -0,0 +1,5 @@
+PROBLEMS_FILTERS_MIGRATE=true
+eclipse.preferences.version=1
+platformState=1338379144146
+quickStart=false
+tipsAndTricks=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
new file mode 100644
index 0000000..08076f2
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+showIntro=false
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
new file mode 100644
index 0000000..66379eb
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
@@ -0,0 +1,2 @@
+ENABLED_DECORATORS=org.eclipse.jdt.ui.override.decorator\:true,org.eclipse.jdt.ui.interface.decorator\:false,org.eclipse.jdt.ui.buildpath.decorator\:true,org.eclipse.pde.ui.binaryProjectDecorator\:false,org.eclipse.team.cvs.ui.decorator\:true,org.eclipse.ui.LinkedResourceDecorator\:true,org.eclipse.ui.VirtualResourceDecorator\:true,org.eclipse.ui.ContentTypeDecorator\:true,org.eclipse.ui.ResourceFilterDecorator\:false,
+eclipse.preferences.version=1
diff --git a/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml
new file mode 100644
index 0000000..bf74e15
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml
@@ -0,0 +1,8 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
new file mode 100644
index 0000000..05254dd
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
@@ -0,0 +1,1403 @@
+
+
+ activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration
+
+ topLevel
+ shellMaximized
+
+
+
+
+ persp.actionSet:org.eclipse.ui.cheatsheets.actionSet
+ persp.actionSet:org.eclipse.search.searchActionSet
+ persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation
+ persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation
+ persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo
+ persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet
+ persp.actionSet:org.eclipse.ui.actionSet.keyBindings
+ persp.actionSet:org.eclipse.ui.actionSet.openFiles
+ persp.actionSet:org.eclipse.debug.ui.launchActionSet
+ persp.actionSet:org.eclipse.jdt.ui.JavaActionSet
+ persp.actionSet:org.eclipse.jdt.ui.JavaElementCreationActionSet
+ persp.actionSet:org.eclipse.ui.NavigateActionSet
+ persp.viewSC:org.eclipse.jdt.ui.PackageExplorer
+ persp.viewSC:org.eclipse.jdt.ui.TypeHierarchy
+ persp.viewSC:org.eclipse.jdt.ui.SourceView
+ persp.viewSC:org.eclipse.jdt.ui.JavadocView
+ persp.viewSC:org.eclipse.search.ui.views.SearchView
+ persp.viewSC:org.eclipse.ui.console.ConsoleView
+ persp.viewSC:org.eclipse.ui.views.ContentOutline
+ persp.viewSC:org.eclipse.ui.views.ProblemView
+ persp.viewSC:org.eclipse.ui.views.ResourceNavigator
+ persp.viewSC:org.eclipse.ui.views.TaskList
+ persp.viewSC:org.eclipse.ui.views.ProgressView
+ persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer
+ persp.viewSC:org.eclipse.ui.texteditor.TemplatesView
+ persp.viewSC:org.eclipse.pde.runtime.LogView
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.JavaProjectWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewPackageCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewClassCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewEnumCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard
+ persp.newWizSC:org.eclipse.ui.wizards.new.folder
+ persp.newWizSC:org.eclipse.ui.wizards.new.file
+ persp.newWizSC:org.eclipse.ui.editors.wizards.UntitledTextFileWizard
+ persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective
+ persp.perspSC:org.eclipse.debug.ui.DebugPerspective
+ persp.viewSC:org.eclipse.ant.ui.views.AntView
+ persp.actionSet:org.eclipse.debug.ui.breakpointActionSet
+ persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet
+ persp.newWizSC:org.eclipse.jdt.junit.wizards.NewTestCaseCreationWizard
+ persp.actionSet:org.eclipse.jdt.junit.JUnitActionSet
+ persp.showIn:org.eclipse.jdt.ui.PackageExplorer
+ persp.showIn:org.eclipse.team.ui.GenericHistoryView
+ persp.showIn:org.eclipse.ui.views.ResourceNavigator
+ persp.showIn:org.eclipse.ui.navigator.ProjectExplorer
+
+
+ newtablook
+ org.eclipse.e4.primaryNavigationStack
+
+
+
+
+
+
+
+
+
+
+ newtablook
+ org.eclipse.e4.secondaryNavigationStack
+
+
+
+
+
+
+ newtablook
+ org.eclipse.e4.secondaryDataStack
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ View
+ categoryTag:Help
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+ View
+ categoryTag:Help
+
+
+
+ newtablook
+ org.eclipse.e4.primaryDataStack
+ EditorStack
+
+
+
+
+ View
+ categoryTag:Java
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+ View
+ categoryTag:Java
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+ View
+ categoryTag:Java
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Ant
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ stretch
+
+
+
+
+
+
+ TrimStack
+
+
+
+
+ TrimStack
+
+
+ TrimStack
+
+
+ TrimStack
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ platform:win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Editor
+
+
+ View
+ categoryTag:Ant
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Help
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Java Browsing
+
+
+ View
+ categoryTag:Java Browsing
+
+
+ View
+ categoryTag:Java Browsing
+
+
+ View
+ categoryTag:Java Browsing
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:API Tools
+
+
+ View
+ categoryTag:Plug-in Development
+
+
+ View
+ categoryTag:Plug-in Development
+
+
+ View
+ categoryTag:Plug-in Development
+
+
+ View
+ categoryTag:Plug-in Development
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:CVS
+
+
+ View
+ categoryTag:CVS
+
+
+ View
+ categoryTag:Team
+
+
+ View
+ categoryTag:Team
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Help
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.equinox.p2.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.equinox.p2.ui/dialog_settings.xml
new file mode 100644
index 0000000..ff34b52
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.equinox.p2.ui/dialog_settings.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps
new file mode 100644
index 0000000..593f470
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/indexNamesMap.txt b/.metadata/.plugins/org.eclipse.jdt.core/indexNamesMap.txt
new file mode 100644
index 0000000..68a85ef
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/indexNamesMap.txt
@@ -0,0 +1 @@
+INDEX VERSION 1.126
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache
new file mode 100644
index 0000000..593f470
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
new file mode 100644
index 0000000..8586397
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
@@ -0,0 +1 @@
+java
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
new file mode 100644
index 0000000..593f470
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt
new file mode 100644
index 0000000..f063a00
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt
@@ -0,0 +1 @@
+INDEX VERSION 1.126+C:\Documents and Settings\Charles\.ssh\Blacksmith\.metadata\.plugins\org.eclipse.jdt.core
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
new file mode 100644
index 0000000..46ba64d
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml
new file mode 100644
index 0000000..6e88291
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml b/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml
new file mode 100644
index 0000000..2383218
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
new file mode 100644
index 0000000..a4ee3cb
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
new file mode 100644
index 0000000..6290af8
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
new file mode 100644
index 0000000..94ff962
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
@@ -0,0 +1,32 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/6/22/refactorings.history b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/6/22/refactorings.history
new file mode 100644
index 0000000..0bd8b1e
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/6/22/refactorings.history
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/6/22/refactorings.index b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/6/22/refactorings.index
new file mode 100644
index 0000000..9d70283
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2012/6/22/refactorings.index
@@ -0,0 +1 @@
+1338601019687 Delete resource 'Blacksmith'
diff --git a/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml
new file mode 100644
index 0000000..27eb404
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties
new file mode 100644
index 0000000..2f8cb9d
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties
@@ -0,0 +1,2 @@
+#Cached timestamps
+#Fri Jun 01 20:56:46 EDT 2012
diff --git a/.metadata/.plugins/org.eclipse.search/dialog_settings.xml b/.metadata/.plugins/org.eclipse.search/dialog_settings.xml
new file mode 100644
index 0000000..6f4cc59
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.search/dialog_settings.xml
@@ -0,0 +1,11 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml
new file mode 100644
index 0000000..193673b
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/commentTemplates.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml
new file mode 100644
index 0000000..891f130
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/commitCommentHistory.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/dialog_settings.xml
new file mode 100644
index 0000000..e49f42e
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/dialog_settings.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml b/.metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml
new file mode 100644
index 0000000..5bf8420
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.team.cvs.ui/repositoriesView.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml
new file mode 100644
index 0000000..b438a7a
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml
@@ -0,0 +1,13 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml
new file mode 100644
index 0000000..f118f02
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml
@@ -0,0 +1,4 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml
new file mode 100644
index 0000000..dc08839
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml
@@ -0,0 +1,28 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
new file mode 100644
index 0000000..cff8d99
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.metadata/version.ini b/.metadata/version.ini
new file mode 100644
index 0000000..c51ff74
--- /dev/null
+++ b/.metadata/version.ini
@@ -0,0 +1 @@
+org.eclipse.core.runtime=1
\ No newline at end of file
diff --git a/src/main/java/net/instinxx/blacksmith/Blacksmith.java b/src/main/java/net/instinxx/blacksmith/Blacksmith.java
new file mode 100644
index 0000000..bb42d0e
--- /dev/null
+++ b/src/main/java/net/instinxx/blacksmith/Blacksmith.java
@@ -0,0 +1,271 @@
+package net.instinxx.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.Player;
+import org.bukkit.inventory.ItemStack;
+
+
+import net.citizensnpcs.api.npc.NPC;
+import net.citizensnpcs.api.npc.character.Character;
+import net.citizensnpcs.api.util.DataKey;
+import net.instinxx.blacksmith.util.Settings.Setting;
+
+public class Blacksmith extends Character {
+ private static final int[] enchantments = new int[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 maxEnchantments = Setting.MAX_ENCHANTMENTS.asInt();
+ private boolean dropItem = Setting.DROP_ITEM.asBoolean();
+
+ public Blacksmith() {
+ plugin = (BlacksmithPlugin) Bukkit.getServer().getPluginManager().getPlugin("Blacksmith");
+ int i = 0;
+ for (Enchantment enchantment : Enchantment.values())
+ enchantments[i++] = enchantment.getId();
+ }
+
+ @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("drop-item"))
+ dropItem = key.getBoolean("drop-item");
+ }
+
+ @Override
+ public void onRightClick(NPC npc, Player player) {
+ if (!player.hasPermission("blacksmith.reforge"))
+ return;
+
+ if (cooldowns.get(player.getName()) != null) {
+ if (!Calendar.getInstance().after(cooldowns.get(player.getName()))) {
+ npc.chat(player, cooldownUnexpiredMsg);
+ return;
+ }
+ cooldowns.remove(player.getName());
+ }
+
+ ItemStack hand = player.getItemInHand();
+ if (session != null) {
+ if (!session.isInSession(player)) {
+ npc.chat(player, 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 ReforgeSession(player, npc);
+ npc.chat(
+ player,
+ costMsg.replace("", plugin.formatCost(player)).replace("- ",
+ 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.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("maximum-enchantments", maxEnchantments);
+ key.setBoolean("drop-item", dropItem);
+ }
+
+ private void reforge(NPC npc, Player player) {
+ npc.chat(player, startReforgeMsg);
+ plugin.withdraw(player);
+ session.beginReforge();
+ if (npc.getBukkitEntity() instanceof Player)
+ ((Player) npc.getBukkitEntity()).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() {
+ npc.chat(player, reforgeItemInHand() ? successMsg : failMsg);
+ if (npc.getBukkitEntity() instanceof Player)
+ ((Player) npc.getBukkitEntity()).setItemInHand(null);
+ if (dropItem)
+ player.getWorld().dropItemNaturally(npc.getBukkitEntity().getLocation(), reforge);
+ else {
+ for (ItemStack stack : player.getInventory().addItem(reforge).values())
+ player.getWorld().dropItemNaturally(npc.getBukkitEntity().getLocation(), stack);
+ }
+ 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;
+ }
+ // Add random enchantments
+ int chance = 1;
+ if (reforge.getDurability() == 0)
+ chance *= 4;
+ else
+ reforge.setDurability((short) 0);
+ for (int i = 0; i < chance; i++) {
+ if (reforge.getEnchantments().keySet().size() == maxEnchantments)
+ break;
+ Enchantment enchantment = Enchantment.getById(enchantments[random.nextInt(enchantments.length)]);
+ if (enchantment.canEnchantItem(reforge))
+ reforge.addEnchantment(enchantment, random.nextInt(enchantment.getMaxLevel()) + 1);
+ }
+ return true;
+ }
+
+ // Return if the session should end
+ private boolean handleClick() {
+ // Prevent player from switching items during session
+ if (!reforge.equals(player.getItemInHand())) {
+ npc.chat(player, itemChangedMsg);
+ return true;
+ }
+ if (!plugin.doesPlayerHaveEnough(player)) {
+ npc.chat(player, 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() {
+ taskId = plugin
+ .getServer()
+ .getScheduler()
+ .scheduleAsyncDelayedTask(plugin, this,
+ (new Random().nextInt(maxReforgeDelay) + minReforgeDelay) * 20);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/instinxx/blacksmith/BlacksmithPlugin.java b/src/main/java/net/instinxx/blacksmith/BlacksmithPlugin.java
new file mode 100644
index 0000000..3c09974
--- /dev/null
+++ b/src/main/java/net/instinxx/blacksmith/BlacksmithPlugin.java
@@ -0,0 +1,149 @@
+package net.instinxx.blacksmith;
+
+import java.util.logging.Level;
+
+
+import net.citizensnpcs.api.CitizensAPI;
+import net.citizensnpcs.api.npc.character.CharacterFactory;
+import net.citizensnpcs.api.util.DataKey;
+
+import net.instinxx.blacksmith.util.Settings;
+import net.instinxx.blacksmith.util.Settings.Setting;
+import net.milkbowl.vault.economy.Economy;
+
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.RegisteredServiceProvider;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public class BlacksmithPlugin extends JavaPlugin {
+ private Settings config;
+ private Economy economy;
+
+ @Override
+ public void onDisable() {
+ config.save();
+
+ getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " disabled.");
+ }
+
+ @Override
+ public void onEnable() {
+ config = new Settings(this);
+ config.load();
+
+ // 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;
+ }
+
+ CitizensAPI.getCharacterManager().registerCharacter(
+ new CharacterFactory(Blacksmith.class).withName("blacksmith"));
+
+ 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 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
diff --git a/src/main/java/net/instinxx/blacksmith/util/Settings.java b/src/main/java/net/instinxx/blacksmith/util/Settings.java
new file mode 100644
index 0000000..94c7411
--- /dev/null
+++ b/src/main/java/net/instinxx/blacksmith/util/Settings.java
@@ -0,0 +1,100 @@
+package net.instinxx.blacksmith.util;
+
+import java.io.File;
+
+
+import net.citizensnpcs.api.util.DataKey;
+import net.citizensnpcs.api.util.YamlStorage;
+import net.instinxx.blacksmith.BlacksmithPlugin;
+
+public class Settings {
+ private final YamlStorage config;
+
+ public Settings(BlacksmithPlugin 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", "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!"),
+ COOLDOWN_UNEXPIRED_MESSAGE(
+ "defaults.messages.cooldown-not-expired",
+ "You'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),
+ 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?"),
+ 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!"),
+ ITEM_UNEXPECTEDLY_CHANGED_MESSAGE(
+ "defaults.messages.item-changed-during-reforge",
+ "That's not the item you wanted to reforge before!"),
+ MAX_ENCHANTMENTS("defaults.maximum-enchantments", 1),
+ 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!");
+
+ 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 3bf551e..87b9145 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,5 +1,5 @@
name: Blacksmith
author: aPunch
version: 1.0
-main: net.apunch.blacksmith.BlacksmithPlugin
+main: net.instinxx.blacksmith.BlacksmithPlugin
depend: [Citizens, Vault]
\ No newline at end of file