Merge branch 'pr/11'

This commit is contained in:
SeanOMik 2020-03-30 10:55:52 -05:00
commit 4bcb141a42
No known key found for this signature in database
GPG Key ID: FA4D55AC05268A88
18 changed files with 618 additions and 544 deletions

2
.gitignore vendored
View File

@ -5,7 +5,7 @@
### Intellij ### ### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea
.idea/** .idea/**
# User-specific stuff # User-specific stuff

View File

@ -5,6 +5,9 @@
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" /> <item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list> </list>
</component> </component>
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="MavenProjectsManager"> <component name="MavenProjectsManager">
<option name="originalFiles"> <option name="originalFiles">
<list> <list>
@ -12,7 +15,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8 (2)" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -3,22 +3,18 @@
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="dcab9632-7b1a-44d7-9283-be9b37640afc" name="Default Changelist" comment=""> <list default="true" id="dcab9632-7b1a-44d7-9283-be9b37640afc" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/config.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/config.yml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/language.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/language.yml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/target/classes/config.yml" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/config.yml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/target/classes/plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/plugin.yml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/target/maven-archiver/pom.properties" beforeDir="false" afterPath="$PROJECT_DIR$/target/maven-archiver/pom.properties" afterDir="false" />
<change beforePath="$PROJECT_DIR$/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst" beforeDir="false" afterPath="$PROJECT_DIR$/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="LAST_RESOLUTION" value="IGNORE" />
</component> </component>
<component name="ComposerSettings">
<execution>
<executable />
</execution>
</component>
<component name="FileTemplateManagerImpl"> <component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES"> <option name="RECENT_TEMPLATES">
<list> <list>
@ -46,13 +42,21 @@
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../DexunGUI" /> <property name="WebServerToolWindowFactoryState" value="true" />
<property name="project.structure.last.edited" value="Modules" /> <property name="aspect.path.notification.shown" value="true" />
<property name="project.structure.proportion" value="0.0" /> <property name="last_opened_file_path" value="$USER_HOME$/Desktop/Servers/SMP/Paper.jar" />
<property name="project.structure.side.proportion" value="0.0" /> <property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.tslint" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="project.structure.last.edited" value="Project" />
<property name="project.structure.proportion" value="0.15" />
<property name="project.structure.side.proportion" value="0.2" />
<property name="restartRequiresConfirmation" value="false" /> <property name="restartRequiresConfirmation" value="false" />
<property name="run.code.analysis.last.selected.profile" value="pProject Default" /> <property name="run.code.analysis.last.selected.profile" value="pProject Default" />
<property name="settings.editor.selected.configurable" value="configurable.group.appearance" /> <property name="settings.editor.selected.configurable" value="editor.preferences.jsOptions" />
</component> </component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
@ -62,26 +66,26 @@
</component> </component>
<component name="RunManager" selected="JAR Application.Spigot-1.15.2"> <component name="RunManager" selected="JAR Application.Spigot-1.15.2">
<configuration name="Paper-1.15.1" type="JarApplication"> <configuration name="Paper-1.15.1" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../../_TEST_SERVER_PAPER_1.15.1_/paper-62.jar" /> <option name="JAR_PATH" value="$USER_HOME$/_TEST_SERVER_PAPER_1.15.1_/paper-62.jar" />
<option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.15.1_" /> <option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.15.1_" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="Paper-1.15.2" type="JarApplication"> <configuration name="Paper-1.15.2" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../../_TEST_SERVER_PAPER_1.15.2_/paper-77.jar" /> <option name="JAR_PATH" value="$USER_HOME$/_TEST_SERVER_PAPER_1.15.2_/paper-77.jar" />
<option name="PROGRAM_PARAMETERS" value="nogui" /> <option name="PROGRAM_PARAMETERS" value="nogui" />
<option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.15.2_" /> <option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.15.2_" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="Spigot-1.15.1" type="JarApplication"> <configuration name="Spigot-1.15.1" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../../_TEST_SERVER_1.15.1_/spigot-1.15.1.jar" /> <option name="JAR_PATH" value="$USER_HOME$/Desktop/vps/smp/SMP/Paper.jar" />
<option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.1_" /> <option name="WORKING_DIRECTORY" value="C:\Users\Checkium\Desktop\vps\smp\SMP\" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="Spigot-1.15.2" type="JarApplication"> <configuration name="Spigot-1.15.2" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../../_TEST_SERVER_1.15.2_/spigot-1.15.2.jar" /> <option name="JAR_PATH" value="$USER_HOME$/_TEST_SERVER_1.15.2_/spigot-1.15.2.jar" />
<option name="PROGRAM_PARAMETERS" value="nogui" /> <option name="PROGRAM_PARAMETERS" value="nogui" />
<option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.2_" /> <option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.2_" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
@ -149,74 +153,171 @@
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1579657428994</updated> <updated>1579657428994</updated>
<workItem from="1580167223251" duration="11834000" />
<workItem from="1582324367334" duration="782000" />
</task> </task>
<task id="LOCAL-00001" summary="Attempt at implementing NBT">
<created>1580168789486</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1580168789486</updated>
</task>
<task id="LOCAL-00002" summary="EntityTamableFox recode and a few changes&#10;&#10;- Recoded EntityTamableFox to clean the pathfinder bloat&#10;- Removed sleeping and chosenName as this data is already handled by vanilla&#10;- Improved some logic around interact event&#10;- Added a config option to enable and disable the anvil name GUI&#10;- Fixed a bug where item counts would go to zero if just one was present">
<created>1580233945505</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1580233945505</updated>
</task>
<task id="LOCAL-00003" summary="New way of implementing foxes">
<created>1582326723752</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1582326723759</updated>
</task>
<option name="localTasksCounter" value="4" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="Attempt at implementing NBT" />
<MESSAGE value="EntityTamableFox recode and a few changes&#10;&#10;- Recoded EntityTamableFox to clean the pathfinder bloat&#10;- Removed sleeping and chosenName as this data is already handled by vanilla&#10;- Improved some logic around interact event&#10;- Added a config option to enable and disable the anvil name GUI&#10;- Fixed a bug where item counts would go to zero if just one was present" />
<MESSAGE value="New way of implementing foxes" />
<option name="LAST_COMMIT_MESSAGE" value="New way of implementing foxes" />
</component>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1580081956712"> <state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1580229888801">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580081956712" /> <state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580081956712" />
<state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580229888801" />
<state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579710781130" /> <state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579710781130" />
<state x="765" y="230" key="#com.intellij.ide.util.MemberChooser" timestamp="1580580882620"> <state x="765" y="230" key="#com.intellij.ide.util.MemberChooser" timestamp="1580580882620">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="765" y="230" key="#com.intellij.ide.util.MemberChooser/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580580882620" /> <state x="765" y="230" key="#com.intellij.ide.util.MemberChooser/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580580882620" />
<state x="765" y="230" key="#com.intellij.ide.util.MemberChooser/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579708181770" /> <state x="765" y="230" key="#com.intellij.ide.util.MemberChooser/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579708181770" />
<state x="740" y="274" key="FileChooserDialogImpl" timestamp="1580081289890"> <state x="2415" y="104" key="CommitChangelistDialog2" timestamp="1582326721037">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state x="495" y="104" key="CommitChangelistDialog2/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580233943125" />
<state x="2415" y="104" key="CommitChangelistDialog2/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582326721037" />
<state x="184" y="92" key="DiffContextDialog" timestamp="1580232320365">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="184" y="92" key="DiffContextDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580232320365" />
<state x="740" y="274" key="FileChooserDialogImpl" timestamp="1580229674681">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="740" y="274" key="FileChooserDialogImpl/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580081289890" /> <state x="740" y="274" key="FileChooserDialogImpl/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580081289890" />
<state x="740" y="274" key="FileChooserDialogImpl/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580229674681" />
<state x="794" y="418" key="Github.CreateGistDialog" timestamp="1580081718270"> <state x="794" y="418" key="Github.CreateGistDialog" timestamp="1580081718270">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="794" y="418" width="356" height="203" key="Github.CreateGistDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580081718270" /> <state x="794" y="418" width="356" height="203" key="Github.CreateGistDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580081718270" />
<state width="1877" height="221" key="GridCell.Tab.0.bottom" timestamp="1580583328931"> <state width="1879" height="282" key="GridCell.Tab.0.bottom" timestamp="1582226910732">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.0.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328931" /> <state width="1877" height="237" key="GridCell.Tab.0.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="939" height="355" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<state width="1879" height="282" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910732" />
<state width="1877" height="199" key="GridCell.Tab.0.bottom/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668965" /> <state width="1877" height="199" key="GridCell.Tab.0.bottom/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668965" />
<state width="1877" height="221" key="GridCell.Tab.0.center" timestamp="1580583328930"> <state width="1879" height="282" key="GridCell.Tab.0.center" timestamp="1582226910732">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.0.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328930" /> <state width="1877" height="237" key="GridCell.Tab.0.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="939" height="355" key="GridCell.Tab.0.center/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020858" />
<state width="1879" height="282" key="GridCell.Tab.0.center/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910732" />
<state width="1877" height="199" key="GridCell.Tab.0.center/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668964" /> <state width="1877" height="199" key="GridCell.Tab.0.center/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668964" />
<state width="1877" height="221" key="GridCell.Tab.0.left" timestamp="1580583328930"> <state width="1879" height="282" key="GridCell.Tab.0.left" timestamp="1582226910732">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.0.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328930" /> <state width="1877" height="237" key="GridCell.Tab.0.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="939" height="355" key="GridCell.Tab.0.left/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020858" />
<state width="1879" height="282" key="GridCell.Tab.0.left/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910732" />
<state width="1877" height="199" key="GridCell.Tab.0.left/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668964" /> <state width="1877" height="199" key="GridCell.Tab.0.left/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668964" />
<state width="1877" height="221" key="GridCell.Tab.0.right" timestamp="1580583328931"> <state width="1879" height="282" key="GridCell.Tab.0.right" timestamp="1582226910732">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.0.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328931" /> <state width="1877" height="237" key="GridCell.Tab.0.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="939" height="355" key="GridCell.Tab.0.right/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020858" />
<state width="1879" height="282" key="GridCell.Tab.0.right/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910732" />
<state width="1877" height="199" key="GridCell.Tab.0.right/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668964" /> <state width="1877" height="199" key="GridCell.Tab.0.right/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580134668964" />
<state width="1877" height="221" key="GridCell.Tab.1.bottom" timestamp="1580583328827"> <state width="1879" height="282" key="GridCell.Tab.1.bottom" timestamp="1582226910717">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.1.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328827" /> <state width="1877" height="237" key="GridCell.Tab.1.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="1877" height="221" key="GridCell.Tab.1.center" timestamp="1580583328827"> <state width="939" height="355" key="GridCell.Tab.1.bottom/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<screen x="0" y="0" width="1920" height="1040" /> <state width="1879" height="282" key="GridCell.Tab.1.bottom/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910717" />
<state width="1879" height="282" key="GridCell.Tab.1.center" timestamp="1582226910716">
<screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.1.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328827" /> <state width="1877" height="237" key="GridCell.Tab.1.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="1877" height="221" key="GridCell.Tab.1.left" timestamp="1580583328827"> <state width="939" height="355" key="GridCell.Tab.1.center/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<screen x="0" y="0" width="1920" height="1040" /> <state width="1879" height="282" key="GridCell.Tab.1.center/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910716" />
<state width="1879" height="282" key="GridCell.Tab.1.left" timestamp="1582226910716">
<screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.1.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328827" /> <state width="1877" height="237" key="GridCell.Tab.1.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="1877" height="221" key="GridCell.Tab.1.right" timestamp="1580583328827"> <state width="939" height="355" key="GridCell.Tab.1.left/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<screen x="0" y="0" width="1920" height="1040" /> <state width="1879" height="282" key="GridCell.Tab.1.left/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910716" />
<state width="1879" height="282" key="GridCell.Tab.1.right" timestamp="1582226910716">
<screen x="1920" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="221" key="GridCell.Tab.1.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580583328827" /> <state width="1877" height="237" key="GridCell.Tab.1.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580083439451" />
<state width="939" height="355" key="GridCell.Tab.1.right/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<state width="1879" height="282" key="GridCell.Tab.1.right/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910716" />
<state width="1879" height="282" key="GridCell.Tab.2.bottom" timestamp="1582226910717">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state width="939" height="355" key="GridCell.Tab.2.bottom/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<state width="1879" height="282" key="GridCell.Tab.2.bottom/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910717" />
<state width="1879" height="282" key="GridCell.Tab.2.center" timestamp="1582226910717">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state width="939" height="355" key="GridCell.Tab.2.center/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<state width="1879" height="282" key="GridCell.Tab.2.center/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910717" />
<state width="1879" height="282" key="GridCell.Tab.2.left" timestamp="1582226910717">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state width="939" height="355" key="GridCell.Tab.2.left/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<state width="1879" height="282" key="GridCell.Tab.2.left/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910717" />
<state width="1879" height="282" key="GridCell.Tab.2.right" timestamp="1582226910717">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state width="939" height="355" key="GridCell.Tab.2.right/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234020859" />
<state width="1879" height="282" key="GridCell.Tab.2.right/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582226910717" />
<state x="490" y="174" key="Maven.ArtifactSearchDialog" timestamp="1579373377880"> <state x="490" y="174" key="Maven.ArtifactSearchDialog" timestamp="1579373377880">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="498" height="446" key="SwitcherDM/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579469022098" /> <state x="649" y="243" key="RollbackChangesDialog" timestamp="1580234562831">
<state width="498" height="446" key="SwitcherDM/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579705820492" />
<state x="656" y="343" key="com.intellij.ide.util.TipDialog" timestamp="1580582504511">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="656" y="343" key="com.intellij.ide.util.TipDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580582504511" /> <state x="649" y="243" key="RollbackChangesDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234562831" />
<state x="440" y="95" key="SettingsEditor" timestamp="1580234010294">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="440" y="95" key="SettingsEditor/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234010294" />
<state width="498" height="446" key="SwitcherDM/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579469022098" />
<state width="498" height="446" key="SwitcherDM/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579705820492" />
<state x="552" y="254" key="Vcs.Push.Dialog.v2" timestamp="1580234030515">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="552" y="254" key="Vcs.Push.Dialog.v2/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234030515" />
<state x="2576" y="343" key="com.intellij.ide.util.TipDialog" timestamp="1582324367326">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state x="656" y="343" key="com.intellij.ide.util.TipDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580171129088" />
<state x="2576" y="343" key="com.intellij.ide.util.TipDialog/0.0.1920.1040/1920.0.1920.1040@1920.0.1920.1040" timestamp="1582324367326" />
<state x="656" y="343" key="com.intellij.ide.util.TipDialog/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580132930429" /> <state x="656" y="343" key="com.intellij.ide.util.TipDialog/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580132930429" />
<state x="458" y="257" width="1003" height="602" key="com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory$2" timestamp="1580233159142">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="458" y="257" width="1003" height="602" key="com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory$2/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580233159142" />
<state x="-781" y="188" width="1359" height="1028" key="dock-window-1" timestamp="1580017524734"> <state x="-781" y="188" width="1359" height="1028" key="dock-window-1" timestamp="1580017524734">
<screen x="-1920" y="0" width="1920" height="1040" /> <screen x="-1920" y="0" width="1920" height="1040" />
</state> </state>
@ -225,11 +326,28 @@
<screen x="-1920" y="0" width="1920" height="1040" /> <screen x="-1920" y="0" width="1920" height="1040" />
</state> </state>
<state x="-809" y="141" width="1359" height="1028" key="dock-window-2/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580018302720" /> <state x="-809" y="141" width="1359" height="1028" key="dock-window-2/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580018302720" />
<state x="656" y="125" width="624" height="789" key="find.popup" timestamp="1580133295803"> <state x="656" y="125" width="834" height="789" key="find.popup" timestamp="1580233407819">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="656" y="125" width="607" height="789" key="find.popup/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580018609474" /> <state x="656" y="125" width="607" height="789" key="find.popup/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580018609474" />
<state x="656" y="125" width="834" height="789" key="find.popup/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580233407819" />
<state x="656" y="125" width="624" height="789" key="find.popup/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580133295803" /> <state x="656" y="125" width="624" height="789" key="find.popup/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1580133295803" />
<state x="698" y="312" key="git4idea.merge.GitMergeDialog" timestamp="1580234410981">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="698" y="312" key="git4idea.merge.GitMergeDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234410981" />
<state x="633" y="312" key="git4idea.merge.GitPullDialog" timestamp="1580234511781">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="633" y="312" key="git4idea.merge.GitPullDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234511781" />
<state x="730" y="385" key="git4idea.rebase.GitRebaseDialog" timestamp="1580234534356">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="730" y="385" key="git4idea.rebase.GitRebaseDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234534356" />
<state x="709" y="415" key="git4idea.ui.GitResetDialog" timestamp="1580234483885">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="709" y="415" key="git4idea.ui.GitResetDialog/0.0.1920.1040/1920.0.1920.1040@0.0.1920.1040" timestamp="1580234483885" />
<state x="342" y="189" key="new project wizard" timestamp="1579657428699"> <state x="342" y="189" key="new project wizard" timestamp="1579657428699">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
@ -239,4 +357,25 @@
</state> </state>
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580063483764" /> <state x="623" y="225" width="672" height="678" key="search.everywhere.popup/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1580063483764" />
</component> </component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java</url>
<line>219</line>
<option name="timeStamp" value="8" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java</url>
<line>220</line>
<option name="timeStamp" value="9" />
</line-breakpoint>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java</url>
<line>110</line>
<option name="timeStamp" value="13" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project> </project>

19
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>net.seanomik</groupId> <groupId>net.seanomik</groupId>
<artifactId>tamablefoxes</artifactId> <artifactId>tamablefoxes</artifactId>
<version>1.5.4-SNAPSHOT</version> <version>1.6.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Tamablefoxes</name> <name>Tamablefoxes</name>
@ -40,7 +40,7 @@
</goals> </goals>
<configuration> <configuration>
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.1_\plugins\TamableFoxes-MC-v1.15.1-v${project.version}.jar</outputFile>--> <!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.1_\plugins\TamableFoxes-MC-v1.15.1-v${project.version}.jar</outputFile>-->
<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.2_\plugins\TamableFoxes-MC-v1.15.X-v${project.version}.jar</outputFile> <outputFile>C:\Users\Checkium\Desktop\vps\smp\SMP\plugins\TamableFoxes-MC-v1.15.X-v${project.version}.jar</outputFile>
<createDependencyReducedPom>false</createDependencyReducedPom> <createDependencyReducedPom>false</createDependencyReducedPom>
</configuration> </configuration>
</execution> </execution>
@ -71,23 +71,18 @@
</repositories> </repositories>
<dependencies> <dependencies>
<dependency> <!--<dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>
<version>1.15.1-R0.1-SNAPSHOT</version> <version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>-->
<!--<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>
<scope>system</scope> <scope>system</scope>
<version>1.15.2</version> <version>1.15.2</version>
<systemPath>${project.basedir}/../spigot-1.15.2.jar</systemPath> <systemPath>C:/Users/Checkium/Desktop/Servers/SMP/cache/patched_1.15.2.jar</systemPath>
</dependency>-->
<dependency>
<groupId>com.github.WesJD.AnvilGUI</groupId>
<artifactId>anvilgui</artifactId>
<version>478e0c1</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,59 +1,137 @@
package net.seanomik.tamablefoxes; package net.seanomik.tamablefoxes;
import com.google.common.collect.Lists;
import net.minecraft.server.v1_15_R1.*; import net.minecraft.server.v1_15_R1.*;
import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.Config;
import net.seanomik.tamablefoxes.io.LanguageConfig;
import net.seanomik.tamablefoxes.versions.version_1_15.pathfinding.*; import net.seanomik.tamablefoxes.versions.version_1_15.pathfinding.*;
import org.bukkit.NamespacedKey; import org.apache.commons.lang.reflect.FieldUtils;
import org.bukkit.OfflinePlayer; import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_15_R1.persistence.CraftPersistentDataContainer; import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.entity.Item;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
import javax.annotation.Nullable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.function.Predicate;
public class EntityTamableFox extends EntityFox { public class EntityTamableFox extends EntityFox {
List<PathfinderGoal> untamedGoals = new ArrayList<>(); protected static final DataWatcherObject<Byte> tamed;
private boolean tamed; protected static final DataWatcherObject<Optional<UUID>> ownerUUID;
private boolean sitting; private static final Predicate<Entity> bD;
private EntityLiving owner;
private UUID ownerUUID; static {
tamed = DataWatcher.a(EntityTamableFox.class, DataWatcherRegistry.a);
ownerUUID = DataWatcher.a(EntityTamableFox.class, DataWatcherRegistry.o);
bD = (entity) -> !entity.bm() && IEntitySelector.e.test(entity);
}
List<PathfinderGoal> untamedGoals;
private FoxPathfinderGoalSit goalSit; private FoxPathfinderGoalSit goalSit;
private String customName = "";
public EntityTamableFox(EntityTypes<? extends EntityFox> entitytypes, World world) { public EntityTamableFox(EntityTypes<? extends EntityFox> entitytypes, World world) {
super(entitytypes, world); super(entitytypes, world);
// clearPathFinderGoals();
clearPathFinderGoals(); //initPathfinderGoals();
initPathfinderGoals();
} }
public static Object getPrivateField(String fieldName, Class clazz, Object object) { @Override
Field field; public void initPathfinder() {
Object o = null;
try { try {
field = clazz.getDeclaredField(fieldName); this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FloatGoal
field.setAccessible(true);
o = field.get(object); this.goalSit = new FoxPathfinderGoalSit(this);
} catch (NoSuchFieldException | IllegalAccessException e) { this.goalSelector.a(1, goalSit);
this.goalSelector.a(2, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
this.goalSelector.a(3, new FoxPathfinderGoalPanic(this, 2.2D)); // PanicGoal
this.goalSelector.a(4, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // BreedGoal
// Avoid human only if not tamed
this.goalSelector.a(5, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
return !isTamed() && bD.test((EntityLiving) entityliving);
}));
// Avoid wolf if it is not tamed
this.goalSelector.a(5, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> {
try {
Method eFMethod = EntityFox.class.getDeclaredMethod("eF");
eFMethod.setAccessible(true);
boolean eF = (boolean) eFMethod.invoke(this);
eFMethod.setAccessible(false);
return !((EntityWolf) entityliving).isTamed() && !eF;
} catch (Exception e) {
return !((EntityWolf) entityliving).isTamed();
}
}));
this.goalSelector.a(8, new FoxPathfinderGoalMeleeAttack(this, 1.2000000476837158D, true));
this.goalSelector.a(9, new FoxPathfinderGoalFollowOwner(this, 1.3D, 10.0F, 2.0F, false));
this.goalSelector.a(6, getFoxInnerPathfinderGoal("u")); // StalkPrey
this.goalSelector.a(7, new o()); // Pounce
this.goalSelector.a(9, getFoxInnerPathfinderGoal("h", Arrays.asList(this, 1.25D), Arrays.asList(EntityFox.class, double.class))); // FollowParent
this.goalSelector.a(11, new PathfinderGoalLeapAtTarget(this, 0.4F));
this.goalSelector.a(12, new PathfinderGoalRandomStrollLand(this, 1.15D));
this.goalSelector.a(12, getFoxInnerPathfinderGoal("p")); // SearchForItems
this.goalSelector.a(13, getFoxInnerPathfinderGoal("j", Arrays.asList(this, EntityHuman.class, 24.0f), Arrays.asList(EntityInsentient.class, Class.class, float.class))); // LookAtPlayer
this.targetSelector.a(1, new FoxPathfinderGoalOwnerHurtByTarget(this));
this.targetSelector.a(2, new FoxPathfinderGoalOwnerHurtTarget(this));
this.targetSelector.a(3, (new FoxPathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0]));
// Wild animal attacking
Field bE = this.getClass().getSuperclass().getDeclaredField("bE");
bE.setAccessible(true);
bE.set(this, new PathfinderGoalNearestAttackableTarget(this, EntityAnimal.class, 10, false, false, (entityliving) -> {
return (!isTamed() || (Config.doesTamedAttackWildAnimals() && isTamed())) && (entityliving instanceof EntityChicken || entityliving instanceof EntityRabbit);
}));
Field bF = this.getClass().getSuperclass().getDeclaredField("bF");
bF.setAccessible(true);
bF.set(this, new PathfinderGoalNearestAttackableTarget(this, EntityTurtle.class, 10, false, false, (entityLiving) -> {
return (!isTamed() || (Config.doesTamedAttackWildAnimals() && isTamed())) && EntityTurtle.bw.test((EntityLiving) entityLiving);
}));
Field bG = this.getClass().getSuperclass().getDeclaredField("bG");
bG.setAccessible(true);
bG.set(this, new PathfinderGoalNearestAttackableTarget(this, EntityFish.class, 20, false, false, (entityliving) -> {
return (!isTamed() || (Config.doesTamedAttackWildAnimals() && isTamed())) && entityliving instanceof EntityFishSchool;
}));
untamedGoals = new ArrayList<>();
// Sleep
PathfinderGoal sleep = getFoxInnerPathfinderGoal("t");
this.goalSelector.a(8, sleep);
untamedGoals.add(sleep);
// PerchAndSearch (Random sitting?)
PathfinderGoal perchAndSearch = getFoxInnerPathfinderGoal("r");
this.goalSelector.a(14, perchAndSearch);
untamedGoals.add(perchAndSearch);
// EatBerries (Pick berry bushes)
PathfinderGoal eatBerries = new f(1.2000000476837158D, 12, 2);
this.goalSelector.a(11, eatBerries);
untamedGoals.add(eatBerries); // Maybe this should be configurable too?
PathfinderGoal seekShelter = getFoxInnerPathfinderGoal("s", Arrays.asList(1.25D), Arrays.asList(double.class));
this.goalSelector.a(7, seekShelter); // SeekShelter
untamedGoals.add(seekShelter);
PathfinderGoal strollThroughVillage = getFoxInnerPathfinderGoal("q", Arrays.asList(32, 200), Arrays.asList(int.class, int.class));
this.goalSelector.a(10, strollThroughVillage); // StrollThroughVillage
untamedGoals.add(strollThroughVillage);
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return o;
}
private PathfinderGoal getFoxInnerPathfinderGoal(String innerName, List<Object> args, List<Class<?>> argTypes) {
return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, args, argTypes);
}
private PathfinderGoal getFoxInnerPathfinderGoal(String innerName) {
return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, Arrays.asList(), Arrays.asList());
} }
@Override @Override
@ -71,87 +149,284 @@ public class EntityTamableFox extends EntityFox {
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
// Default value is 10, might want to make this configurable in the future if (!isTamed()) {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D); this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D);
// Default value is 2, might want to make this configurable in the future } else {
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D); this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
}
} }
private void initPathfinderGoals() { public static Object getPrivateField(String fieldName, Class clazz, Object object) {
Field field;
Object o = null;
try { try {
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FloatGoal field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
this.goalSit = new FoxPathfinderGoalSit(this); o = field.get(object);
this.goalSelector.a(1, goalSit); } catch (NoSuchFieldException | IllegalAccessException e) {
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D)); // PanicGoal
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // BreedGoal
// Avoid human only if not tamed
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> !tamed));
// Avoid wolf if it is not tamed
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> {
try {
Method eFMethod = EntityFox.class.getDeclaredMethod("eF");
eFMethod.setAccessible(true);
boolean eF = (boolean) eFMethod.invoke(this);
eFMethod.setAccessible(false);
return !((EntityWolf) entityliving).isTamed() && !eF;
} catch (Exception e) {
return !((EntityWolf) entityliving).isTamed();
}
}));
this.goalSelector.a(4, new FoxPathfinderGoalMeleeAttack(this, 1.2000000476837158D, true));
this.goalSelector.a(5, new FoxPathfinderGoalFollowOwner(this, 1.3D, 10.0F, 2.0F, false));
this.goalSelector.a(6, getFoxInnerPathfinderGoal("u")); // StalkPrey
this.goalSelector.a(7, new EntityFox.o()); // Pounce
PathfinderGoal seekShelter = getFoxInnerPathfinderGoal("s", Arrays.asList(1.25D), Arrays.asList(double.class));
this.goalSelector.a(7, seekShelter); // SeekShelter
untamedGoals.add(seekShelter);
this.goalSelector.a(8, getFoxInnerPathfinderGoal("t")); // Sleep
this.goalSelector.a(9, getFoxInnerPathfinderGoal("h", Arrays.asList(this, 1.25D), Arrays.asList(EntityFox.class, double.class))); // FollowParent
PathfinderGoal strollThroughVillage = getFoxInnerPathfinderGoal("q", Arrays.asList(32, 200), Arrays.asList(int.class, int.class));
this.goalSelector.a(9, strollThroughVillage); // StrollThroughVillage
untamedGoals.add(strollThroughVillage);
// EatBerries (Pick berry bushes)
PathfinderGoal eatBerries = new EntityFox.f(1.2000000476837158D, 12, 2);
this.goalSelector.a(10, eatBerries);
untamedGoals.add(eatBerries); // Maybe this should be configurable too?
this.goalSelector.a(10, new PathfinderGoalLeapAtTarget(this, 0.4F));
this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 1.15D));
this.goalSelector.a(11, getFoxInnerPathfinderGoal("p")); // SearchForItems
this.goalSelector.a(12, getFoxInnerPathfinderGoal("j", Arrays.asList(this, EntityHuman.class, 24.0f), Arrays.asList(EntityInsentient.class, Class.class, float.class))); // LookAtPlayer
// PerchAndSearch (Random sitting?)
PathfinderGoal perchAndSearch = getFoxInnerPathfinderGoal("r");
this.goalSelector.a(13, perchAndSearch);
untamedGoals.add(perchAndSearch);
this.targetSelector.a(1, new FoxPathfinderGoalOwnerHurtByTarget(this));
this.targetSelector.a(2, new FoxPathfinderGoalOwnerHurtTarget(this));
this.targetSelector.a(3, (new FoxPathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0]));
// Wild animal attacking
this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false,
entityLiving -> (!tamed || (Config.doesTamedAttackWildAnimals() && tamed)) && (
entityLiving instanceof EntityChicken ||
entityLiving instanceof EntityRabbit ||
(entityLiving instanceof EntityTurtle && EntityTurtle.bw.test((EntityLiving) entityLiving)) ||
entityLiving instanceof EntityFishSchool)));
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return o;
}
protected void initDatawatcher() {
super.initDatawatcher();
this.datawatcher.register(tamed, (byte) 0);
this.datawatcher.register(ownerUUID, Optional.empty());
}
// addAdditionalSaveData
public void b(NBTTagCompound compound) {
super.b(compound);
if (this.getOwnerUUID() == null) {
compound.setString("OwnerUUID", "");
} else {
compound.setString("OwnerUUID", this.getOwnerUUID().toString());
}
compound.setBoolean("Sitting", this.isSitting());
}
// readAdditionalSaveData
public void a(NBTTagCompound compound) {
super.a(compound);
String ownerUuid;
if (compound.hasKeyOfType("OwnerUUID", 8)) {
ownerUuid = compound.getString("OwnerUUID");
} else {
String var2 = compound.getString("Owner");
ownerUuid = NameReferencingFileConverter.a(this.getMinecraftServer(), var2);
}
if (!ownerUuid.isEmpty()) {
try {
this.setOwnerUUID(UUID.fromString(ownerUuid));
this.setTamed(true);
} catch (Throwable throwable) {
this.setTamed(false);
}
}
if (this.goalSit != null) {
this.goalSit.setSitting(compound.getBoolean("Sitting"));
}
this.setSitting(compound.getBoolean("Sitting"));
}
public boolean isTamed() {
return ((Byte) this.datawatcher.get(tamed) & 4) != 0;
}
public void setTamed(boolean tamed_) {
byte isTamed = this.datawatcher.get(tamed);
if (tamed_) {
this.datawatcher.set(tamed, (byte) (isTamed | 4));
} else {
this.datawatcher.set(tamed, (byte) (isTamed & -5));
}
this.reassessTameGoals();
if (tamed_) {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
this.setHealth(this.getMaxHealth());
} else {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D);
this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D);
}
}
private void reassessTameGoals() {
if (!isTamed()) return;
for (PathfinderGoal untamedGoal : untamedGoals) {
this.goalSelector.a(untamedGoal);
}
}
// deobf: mobInteract
public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
ItemStack itemstack = entityhuman.b(enumhand);
Item item = itemstack.getItem();
if (itemstack.getItem() instanceof ItemMonsterEgg) {
return super.a(entityhuman, enumhand);
} else {
if (this.isTamed()) {
if (item.isFood() && item.getFoodInfo().c() && this.getHealth() < this.getMaxHealth()) {
if (!entityhuman.abilities.canInstantlyBuild) {
itemstack.subtract(1);
}
this.heal((float)item.getFoodInfo().getNutrition(), EntityRegainHealthEvent.RegainReason.EATING);
return true;
}
if (isOwnedBy(entityhuman)) {
boolean flag = super.a(entityhuman, enumhand);
if (!entityhuman.isSneaking() && (!flag || this.isBaby())) {
this.goalSit.setSitting(!this.isSitting());
return flag;
} else if (entityhuman.isSneaking()) {
if (!this.getEquipment(EnumItemSlot.MAINHAND).isEmpty()) {
getBukkitEntity().getWorld().dropItem(getBukkitEntity().getLocation(), CraftItemStack.asBukkitCopy(this.getEquipment(EnumItemSlot.MAINHAND)));
this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
}
if (item != Items.AIR) {
ItemStack c = itemstack.cloneItemStack();
c.setCount(1);
itemstack.subtract(1);
this.setSlot(EnumItemSlot.MAINHAND, c);
}
}
}
// TODO: take/give items
} else if (item == Items.SWEET_BERRIES) {
if (!entityhuman.abilities.canInstantlyBuild) {
itemstack.subtract(1);
}
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
this.tame(entityhuman);
this.navigation.o();
this.setGoalTarget(null);
this.goalSit.setSitting(true);
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
} else {
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.SMOKE_NORMAL, getBukkitEntity().getLocation(), 10, 0.2D, 0.2D, 0.2D, 0.15D);
}
return true;
}
return super.a(entityhuman, enumhand);
}
}
// deobf: isFood (used for breeding)
public boolean i(ItemStack itemstack) {
Item item = itemstack.getItem();
return item.isFood() && item.getFoodInfo().c();
}
public EntityTamableFox createChild(EntityAgeable entityageable) {
EntityTamableFox entityFox = (EntityTamableFox) EntityTypes.FOX.a(this.world);
UUID uuid = this.getOwnerUUID();
if (uuid != null) {
entityFox.setOwnerUUID(uuid);
entityFox.setTamed(true);
}
return entityFox;
}
public boolean mate(EntityAnimal entityanimal) {
if (entityanimal == this) {
return false;
} else if (!(entityanimal instanceof EntityTamableFox)) {
return false;
} else {
EntityTamableFox entitywolf = (EntityTamableFox)entityanimal;
return (!entitywolf.isSitting() && (this.isInLove() && entitywolf.isInLove()));
}
}
@Nullable
public UUID getOwnerUUID() {
return (UUID) ((Optional) this.datawatcher.get(ownerUUID)).orElse(null);
}
public void setOwnerUUID(@Nullable UUID ownerUuid) {
this.datawatcher.set(ownerUUID, Optional.ofNullable(ownerUuid));
}
public void tame(EntityHuman owner) {
this.setTamed(true);
this.setOwnerUUID(owner.getUniqueID());
/*
* The following code appears to be for the taming advancement, will investigate how to change that in the future
if (owner instanceof EntityPlayer) {
CriterionTriggers.x.a((EntityPlayer)owner, this);
}
*/
}
@Nullable
public EntityLiving getOwner() {
try {
UUID ownerUuid = this.getOwnerUUID();
return ownerUuid == null ? null : this.world.b(ownerUuid);
} catch (IllegalArgumentException var2) {
return null;
}
}
// deobf: canAttack
public boolean c(EntityLiving entity) {
return !this.isOwnedBy(entity) && super.c(entity);
}
public boolean isOwnedBy(EntityLiving entity) {
return entity == this.getOwner();
}
/*
deobf: wantsToAttack (copied from EntityWolf)
This code being from EntityWolf also means that wolves will want to attack foxes
Our life would be so much easier if we could extend both EntityFox and EntityTameableAnimal
*/
public boolean a(EntityLiving entityliving, EntityLiving entityliving1) {
if (!(entityliving instanceof EntityCreeper) && !(entityliving instanceof EntityGhast)) {
if (entityliving instanceof EntityTamableFox) {
EntityTamableFox entityFox = (EntityTamableFox) entityliving;
return !entityFox.isTamed() || entityFox.getOwner() != entityliving1;
} else {
return (!(entityliving instanceof EntityHuman)
|| !(entityliving1 instanceof EntityHuman) ||
((EntityHuman) entityliving1).a((EntityHuman) entityliving)) && ((!(entityliving instanceof EntityHorseAbstract)
|| !((EntityHorseAbstract) entityliving).isTamed()) && (!(entityliving instanceof EntityTameableAnimal)
|| !((EntityTameableAnimal) entityliving).isTamed()));
}
} else {
return false;
}
}
public ScoreboardTeamBase getScoreboardTeam() {
if (this.isTamed()) {
EntityLiving var0 = this.getOwner();
if (var0 != null) {
return var0.getScoreboardTeam();
}
}
return super.getScoreboardTeam();
}
// override isAlliedTo
public boolean r(Entity entity) {
if (this.isTamed()) {
EntityLiving entityOwner = this.getOwner();
if (entity == entityOwner) {
return true;
}
if (entityOwner != null) {
return entityOwner.r(entity);
}
}
return super.r(entity);
}
public void die(DamageSource damageSource) {
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage());
}
super.die(damageSource);
}
private PathfinderGoal getFoxInnerPathfinderGoal(String innerName, List<Object> args, List<Class<?>> argTypes) {
return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, args, argTypes);
}
private PathfinderGoal getFoxInnerPathfinderGoal(String innerName) {
return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, Arrays.asList(), Arrays.asList());
} }
private void clearPathFinderGoals() { private void clearPathFinderGoals() {
@ -171,125 +446,4 @@ public class EntityTamableFox extends EntityFox {
targetEnumSet.clear(); targetEnumSet.clear();
} }
public boolean isTamed() {
return tamed;
}
public void setTamed(boolean tamed) {
this.tamed = tamed;
// Remove goals that are not needed when named, or defeats the purpose of taming
try {
untamedGoals.forEach(goal -> goalSelector.a(goal));
} catch (Exception e) {}
}
public EntityLiving getOwner() {
if (Objects.isNull(owner)) {
if (ownerUUID == null) return null;
OfflinePlayer opOwner = TamableFoxes.getPlugin().getServer().getOfflinePlayer(UUID.fromString(ownerUUID.toString()));
if (opOwner.isOnline()) this.owner = (EntityLiving) ((CraftEntity) opOwner).getHandle();
}
return owner;
}
public void setOwner(EntityLiving entityLiving) {
this.owner = entityLiving;
this.ownerUUID = entityLiving.getUniqueID();
updateFoxVisual();
}
public void setOwnerUUID(UUID ownerUUID) {
this.ownerUUID = ownerUUID;
}
public boolean isOtherFoxFamily(EntityLiving living) {
if (living instanceof EntityTamableFox) {
EntityTamableFox tamableFox = (EntityTamableFox) living;
return (tamableFox.isTamed() && tamableFox.getOwner() != null && tamableFox.getOwner().getUniqueID() == this.getOwner().getUniqueID());
} else {
return false;
}
}
// This is needed for the updateFoxVisual runnable to set the foxes name.
void setCustomName(String customName) {
this.customName = customName;
updateFoxVisual();
}
public void updateFoxVisual() {
new BukkitRunnable() {
@Override
public void run() {
goalSit.setSitting(sitting);
if (tamed && owner != null && !customName.isEmpty()) {
if (Config.doesShowOwnerFoxName()) {
getBukkitEntity().setCustomName(LanguageConfig.getFoxNameFormat().replaceAll("%OWNER%", owner.getName()).replaceAll("%FOX_NAME%", customName));
} else {
getBukkitEntity().setCustomName(LanguageConfig.getFoxNameFormat().replaceAll("%FOX_NAME%", customName));
}
}
}
}.runTask(TamableFoxes.getPlugin());
}
public void setHardSitting(boolean hardSitting) {
super.setSitting(hardSitting);
this.sitting = hardSitting;
if (super.isSleeping()) super.setSleeping(false);
updateFoxVisual();
}
public boolean toggleSitting() {
this.sitting = !this.sitting;
setHardSitting(sitting);
return this.sitting;
}
public ItemStack getMouthItem() {
return getEquipment(EnumItemSlot.MAINHAND);
}
public void setMouthItem(ItemStack item) {
item.setCount(1);
setSlot(EnumItemSlot.MAINHAND, item);
saveNbt();
}
public void setMouthItem(org.bukkit.inventory.ItemStack item) {
ItemStack itemNMS = CraftItemStack.asNMSCopy(item);
setMouthItem(itemNMS);
}
public org.bukkit.entity.Item dropMouthItem() {
Item droppedItem = getBukkitEntity().getWorld().dropItem(getBukkitEntity().getLocation(), CraftItemStack.asBukkitCopy(getMouthItem()));
setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
return droppedItem;
}
public void saveNbt() {
NamespacedKey rootKey = new NamespacedKey(TamableFoxes.getPlugin(), "tamableFoxes");
CraftPersistentDataContainer persistentDataContainer = getBukkitEntity().getPersistentDataContainer();
PersistentDataContainer tamableFoxesData;
if (persistentDataContainer.has(rootKey, PersistentDataType.TAG_CONTAINER)) {
tamableFoxesData = persistentDataContainer.get(rootKey, PersistentDataType.TAG_CONTAINER);
} else {
tamableFoxesData = persistentDataContainer.getAdapterContext().newPersistentDataContainer();
}
NamespacedKey ownerKey = new NamespacedKey(TamableFoxes.getPlugin(), "owner");
NamespacedKey sittingKey = new NamespacedKey(TamableFoxes.getPlugin(), "sitting");
tamableFoxesData.set(ownerKey, PersistentDataType.STRING, getOwner() == null ? "none" : getOwner().getUniqueID().toString());
tamableFoxesData.set(sittingKey, PersistentDataType.BYTE, (byte) (isSitting() ? 1 : 0));
persistentDataContainer.set(rootKey, PersistentDataType.TAG_CONTAINER, tamableFoxesData);
}
} }

View File

@ -4,7 +4,6 @@ import net.minecraft.server.v1_15_R1.*;
import net.seanomik.tamablefoxes.versions.version_1_15.command.CommandSpawnTamableFox; import net.seanomik.tamablefoxes.versions.version_1_15.command.CommandSpawnTamableFox;
import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.Config;
import net.seanomik.tamablefoxes.io.LanguageConfig; import net.seanomik.tamablefoxes.io.LanguageConfig;
import net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
@ -44,7 +43,6 @@ import java.util.stream.Collectors;
*/ */
public final class TamableFoxes extends JavaPlugin implements Listener { public final class TamableFoxes extends JavaPlugin implements Listener {
private static TamableFoxes plugin; private static TamableFoxes plugin;
public List<EntityTamableFox> spawnedFoxes = new ArrayList<>();
private boolean versionSupported = true; private boolean versionSupported = true;
@ -104,157 +102,8 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
@Override @Override
public void onDisable() { public void onDisable() {
getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getSavingFoxMessage()); getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getSavingFoxMessage());
spawnedFoxes.forEach(EntityTamableFox::saveNbt);
} }
@EventHandler
public void onWorldSaveEvent(WorldSaveEvent event) {
spawnedFoxes.forEach(EntityTamableFox::saveNbt);
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) { // Wait for all the entities to load.
Bukkit.getScheduler().runTaskLaterAsynchronously(this, ()-> {
spawnedFoxes.addAll(Utils.loadFoxesInChunk(event.getChunk()));
}, 5L);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
for (EntityTamableFox fox : getFoxesOf(player)) {
fox.setOwner((EntityLiving) ((CraftEntity) player).getHandle());
}
}
@EventHandler
public void onEntitySpawn(EntitySpawnEvent event) {
Entity entity = event.getEntity();
if (Utils.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
spawnedFoxes.add(tamableFox);
}
}
@EventHandler
public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
Entity entity = event.getRightClicked();
Player player = event.getPlayer();
if (event.getHand() != EquipmentSlot.HAND) return;
ItemStack itemHand = player.getInventory().getItemInMainHand();
ItemMeta handMeta = itemHand.getItemMeta();
// Checks if the entity is EntityTamableFox and that the player is allowed to tame foxes
if (Utils.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
// Check if its tamed but ignore it if the player is holding sweet berries for breeding or nametag for renaming
if (tamableFox.isTamed() && tamableFox.getOwner() != null && itemHand.getType() != Material.SWEET_BERRIES) {
if (tamableFox.getOwner().getUniqueID() == player.getUniqueId()) {
event.setCancelled(true);
if (player.isSneaking()) {
net.minecraft.server.v1_15_R1.ItemStack foxMouth = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
if (!foxMouth.isEmpty()) tamableFox.dropMouthItem();
if (itemHand.getType() != Material.AIR) {
tamableFox.setMouthItem(itemHand);
if (itemHand.getAmount() == 1) player.getInventory().removeItem(itemHand);
else itemHand.setAmount(itemHand.getAmount() - 1);
}
} else if (itemHand.getType() == Material.NAME_TAG) {
if (itemHand.getAmount() == 1) player.getInventory().removeItem(itemHand);
else itemHand.setAmount(itemHand.getAmount() - 1);
tamableFox.setCustomName(handMeta.getDisplayName());
event.setCancelled(true);
} else {
tamableFox.toggleSitting();
}
}
} else if (itemHand.getType() == Material.CHICKEN && Config.canPlayerTameFox(player)) {
if (Math.random() < 0.33D) { // tamed
tamableFox.setTamed(true);
tamableFox.setOwner(((CraftPlayer) player).getHandle());
player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + LanguageConfig.getTamedMessage());
if (Config.askForNameAfterTaming()) {
player.sendMessage(ChatColor.RED + LanguageConfig.getTamingAskingName());
new AnvilGUI.Builder()
.onComplete((plr, text) -> { // Called when the inventory output slot is clicked
if (!text.equals("")) {
tamableFox.setCustomName(text);
tamableFox.setCustomNameVisible(true);
plr.sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text));
tamableFox.saveNbt();
}
return AnvilGUI.Response.close();
})
.text("Fox name") // Sets the text the GUI should start with
.plugin(this) // Set the plugin instance
.open(player); // Opens the GUI for the player provided
}
} else { // Tame failed
player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
}
if (!player.getGameMode().equals(GameMode.CREATIVE)) {
if (itemHand.getAmount() == 1) player.getInventory().removeItem(itemHand);
else itemHand.setAmount(itemHand.getAmount() - 1);
}
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
List<EntityTamableFox> foxesOf = getFoxesOf(player);
for (EntityTamableFox tamableFox : foxesOf) {
if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) {
tamableFox.setSleeping(true);
}
}
}
@EventHandler
public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
Player player = event.getPlayer();
List<EntityTamableFox> foxesOf = getFoxesOf(player);
for (EntityTamableFox tamableFox : foxesOf) {
tamableFox.setSleeping(false);
if (tamableFox.isSitting()) {
tamableFox.setSitting(true);
}
}
}
@EventHandler
public void onEntityDeathEvent(EntityDeathEvent event) {
Entity entity = event.getEntity();
if (!Utils.isTamableFox(entity)) return; // Is the entity a tamable fox?
// Remove the fox from storage
spawnedFoxes.remove(entity);
// Notify the owner
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.getOwner() != null) {
Player owner = ((EntityPlayer) tamableFox.getOwner()).getBukkitEntity();
owner.sendMessage(Utils.getPrefix() + ChatColor.RED + (tamableFox.hasCustomName() ? tamableFox.getBukkitEntity().getCustomName() : "Your fox") + " was killed!");
}
}
public EntityTamableFox spawnTamableFox(Location loc, EntityFox.Type type) { public EntityTamableFox spawnTamableFox(Location loc, EntityFox.Type type) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle(); EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
@ -263,9 +112,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
return tamableFox; return tamableFox;
} }
public List<EntityTamableFox> getFoxesOf(Player player) {
return spawnedFoxes.stream().filter(fox -> fox.getOwner() != null && fox.getOwner().getUniqueID().equals(player.getUniqueId())).collect(Collectors.toList());
}
public static TamableFoxes getPlugin() { public static TamableFoxes getPlugin() {
return plugin; return plugin;

View File

@ -1,27 +1,12 @@
package net.seanomik.tamablefoxes; package net.seanomik.tamablefoxes;
import net.minecraft.server.v1_15_R1.EntityLiving;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.persistence.CraftPersistentDataContainer;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class Utils { public class Utils {
public static boolean isTamableFox(org.bukkit.entity.Entity entity) {
return ((CraftEntity) entity).getHandle().getClass().getName().contains("TamableFox") || ((CraftEntity) entity).getHandle() instanceof EntityTamableFox;
}
public static String getPrefix() { public static String getPrefix() {
return ChatColor.RED + "[Tamable Foxes] "; return ChatColor.RED + "[Tamable Foxes] ";
} }
@ -64,41 +49,4 @@ public class Utils {
} }
} }
public static List<EntityTamableFox> loadFoxesInChunk(Chunk chunk) {
return Arrays.stream(chunk.getEntities()).filter(Utils::isTamableFox)
.map(entity -> (EntityTamableFox) ((CraftEntity) entity).getHandle())
.peek(tamableFox -> {
NamespacedKey rootKey = new NamespacedKey(TamableFoxes.getPlugin(), "tamableFoxes");
CraftPersistentDataContainer persistentDataContainer = tamableFox.getBukkitEntity().getPersistentDataContainer();
if (persistentDataContainer.has(rootKey, PersistentDataType.TAG_CONTAINER)) {
PersistentDataContainer tamableFoxesData = persistentDataContainer.get(rootKey, PersistentDataType.TAG_CONTAINER);
NamespacedKey ownerKey = new NamespacedKey(TamableFoxes.getPlugin(), "owner");
NamespacedKey sittingKey = new NamespacedKey(TamableFoxes.getPlugin(), "sitting");
String ownerUUIDString = tamableFoxesData.get(ownerKey, PersistentDataType.STRING);
boolean sitting = ((byte) 1) == tamableFoxesData.get(sittingKey, PersistentDataType.BYTE);
boolean tamed = false;
if (!ownerUUIDString.equals("none")) {
tamed = true;
OfflinePlayer owner = TamableFoxes.getPlugin().getServer().getOfflinePlayer(UUID.fromString(ownerUUIDString));
if (owner.isOnline()) {
EntityLiving livingOwner = (EntityLiving) ((CraftEntity) owner).getHandle();
tamableFox.setOwner(livingOwner);
} else {
tamableFox.setOwnerUUID(UUID.fromString(ownerUUIDString));
}
tamableFox.setTamed(true);
}
if (sitting && tamed) {
tamableFox.setHardSitting(true);
} else {
tamableFox.setSitting(false);
tamableFox.setSleeping(false);
}
}
}).collect(Collectors.toList());
}
} }

View File

@ -41,8 +41,6 @@ public class CommandSpawnTamableFox implements TabExecutor {
case "red": case "red":
try { try {
EntityTamableFox fox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED); EntityTamableFox fox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED);
fox.saveNbt();
player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.RED)); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.RED));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -52,8 +50,6 @@ public class CommandSpawnTamableFox implements TabExecutor {
case "snow": case "snow":
try { try {
EntityTamableFox spawnedFox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW); EntityTamableFox spawnedFox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW);
spawnedFox.saveNbt();
player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.SNOW)); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + LanguageConfig.getSpawnedFoxMessage(EntityFox.Type.SNOW));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -51,7 +51,7 @@ public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
} }
public boolean b() { public boolean b() {
return this.e.m() ? false : (this.a.isSitting() ? false : this.a.h(this.b) > (double)(this.g * this.g)); return !this.e.m() && (!this.a.isSitting() && this.a.h(this.b) > (double) (this.g * this.g));
} }
public void c() { public void c() {

View File

@ -32,6 +32,6 @@ public class FoxPathfinderGoalMeleeAttack extends PathfinderGoalMeleeAttack {
} }
public boolean a() { public boolean a() {
return !tamableFox.isSitting() && !tamableFox.isSleeping() && !tamableFox.isCrouching() && !tamableFox.es() && !tamableFox.isOtherFoxFamily(enemy) && super.a(); return !tamableFox.isSitting() && !tamableFox.isSleeping() && !tamableFox.isCrouching() && !tamableFox.es() && super.a();
} }
} }

View File

@ -28,7 +28,7 @@ public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget {
} else { } else {
this.b = entityliving.getLastDamager(); this.b = entityliving.getLastDamager();
int i = entityliving.cI(); int i = entityliving.cI();
return i != this.c && this.a(this.b, PathfinderTargetCondition.a); //&& this.a.a(this.b, entityliving); // Returns true in any condition return i != this.c && this.a(this.b, PathfinderTargetCondition.a) && this.a.a(this.b, entityliving);
} }
} else { } else {
return false; return false;

View File

@ -1,9 +1,9 @@
package net.seanomik.tamablefoxes.versions.version_1_15.pathfinding; package net.seanomik.tamablefoxes.versions.version_1_15.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.EntityLiving; import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.PathfinderGoalTarget; import net.minecraft.server.v1_15_R1.PathfinderGoalTarget;
import net.minecraft.server.v1_15_R1.PathfinderTargetCondition; import net.minecraft.server.v1_15_R1.PathfinderTargetCondition;
import net.seanomik.tamablefoxes.EntityTamableFox;
import org.bukkit.event.entity.EntityTargetEvent.TargetReason; import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
import java.util.EnumSet; import java.util.EnumSet;
@ -25,13 +25,10 @@ public class FoxPathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget {
if (entityliving == null) { if (entityliving == null) {
e.setGoalTarget(null); e.setGoalTarget(null);
return false; return false;
} else if (fox.isOtherFoxFamily(hitEntity)) {
e.setGoalTarget(null);
return false;
} else { } else {
hitEntity = entityliving.cJ(); hitEntity = entityliving.cJ();
int i = entityliving.cK(); int i = entityliving.cK();
return i != this.c && this.a(hitEntity, PathfinderTargetCondition.a);// && fox.a.a(hitEntity, entityliving); // Just returns true in any case return i != this.c && this.a(hitEntity, PathfinderTargetCondition.a) && fox.a(hitEntity, entityliving);
} }
} else { } else {
return false; return false;
@ -39,16 +36,12 @@ public class FoxPathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget {
} }
public void c() { public void c() {
if (!fox.isOtherFoxFamily(hitEntity)) { this.e.setGoalTarget(hitEntity, TargetReason.OWNER_ATTACKED_TARGET, true);
this.e.setGoalTarget(hitEntity, TargetReason.OWNER_ATTACKED_TARGET, true); EntityLiving entityliving = fox.getOwner();
EntityLiving entityliving = fox.getOwner(); if (entityliving != null) {
if (entityliving != null) { this.c = entityliving.cK();
this.c = entityliving.cK();
}
super.c();
} else {
e.setGoalTarget(null);
} }
super.c();
} }
} }

View File

@ -1,5 +1,5 @@
# Config for Tamable Foxes # Config for Tamable Foxes
show-owner-in-fox-name: true show-owner-in-fox-name: false
enable-taming-permission: true enable-taming-permission: true
ask-for-name-after-taming: true ask-for-name-after-taming: true

View File

@ -2,7 +2,7 @@ name: Tamablefoxes
version: ${project.version} version: ${project.version}
main: net.seanomik.tamablefoxes.TamableFoxes main: net.seanomik.tamablefoxes.TamableFoxes
api-version: 1.15 api-version: 1.15
load: POSTWORLD load: STARTUP
description: Adds tamable foxes to Minecraft! description: Adds tamable foxes to Minecraft!
commands: commands:

View File

@ -1,7 +1,7 @@
# Config for Tamable Foxes # Config for Tamable Foxes
show-owner-in-fox-name: true show-owner-in-fox-name: false
enable-taming-permission: true enable-taming-permission: true
ask-for-name-after-taming: true ask-for-name-after-taming: false
tamed-behavior: tamed-behavior:
attack-wild-animals: true attack-wild-animals: true

View File

@ -1,8 +1,8 @@
name: Tamablefoxes name: Tamablefoxes
version: 1.5.4-SNAPSHOT version: 1.6.0-SNAPSHOT
main: net.seanomik.tamablefoxes.TamableFoxes main: net.seanomik.tamablefoxes.TamableFoxes
api-version: 1.15 api-version: 1.15
load: POSTWORLD load: STARTUP
description: Adds tamable foxes to Minecraft! description: Adds tamable foxes to Minecraft!
commands: commands:

View File

@ -1,5 +1,5 @@
#Generated by Maven #Generated by Maven
#Sat Feb 01 12:07:47 CST 2020 #Tue Feb 18 22:29:20 GMT 2020
version=1.5.4-SNAPSHOT version=1.6.0-SNAPSHOT
groupId=net.seanomik groupId=net.seanomik
artifactId=tamablefoxes artifactId=tamablefoxes

View File

@ -1,13 +1,13 @@
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalHurtByTarget.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\io\LanguageConfig.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalPanic.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalMeleeAttack.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalOwnerHurtByTarget.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalHurtByTarget.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\command\CommandSpawnTamableFox.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalOwnerHurtTarget.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalSit.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalFollowOwner.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\Utils.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalOwnerHurtByTarget.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalFollowOwner.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalSit.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\TamableFoxes.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalPanic.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\io\Config.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\EntityTamableFox.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalOwnerHurtTarget.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\command\CommandSpawnTamableFox.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\versions\version_1_15\pathfinding\FoxPathfinderGoalMeleeAttack.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\Utils.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\EntityTamableFox.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\TamableFoxes.java
D:\Code\java\spigotPlugins\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\io\LanguageConfig.java C:\Users\Checkium\IdeaProjects\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\io\Config.java