Rewrite and got the custom entity replacing the EntityFox

I found out how to get my custom entity to replace the vanilla EntityFox. This should fix most of the errors people were getting.

I also rewrote the entire plugin. It saves some data with SQLite and some parts of it are cleaned up, optimized, or certain things moved in an appropriate class.
This commit is contained in:
SeanOMik 2020-01-24 10:21:13 -06:00
parent 4fa1bef8fb
commit ba48f8e468
39 changed files with 1141 additions and 1742 deletions

View File

@ -6,9 +6,11 @@
<sourceOutputDir name="target/generated-sources/annotations" /> <sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" /> <outputRelativeToContentRoot value="true" />
<module name="GitTamableFoxes" /> <module name="TamableFoxesCustomEntity" />
<module name="tamableFoxes" />
</profile> </profile>
</annotationProcessing> </annotationProcessing>
<bytecodeTargetLevel>
<module name="TamableFoxesCustomEntity" target="1.8" />
</bytecodeTargetLevel>
</component> </component>
</project> </project>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Encoding"> <component name="Encoding">
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component> </component>

View File

@ -5,7 +5,6 @@
<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="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager"> <component name="MavenProjectsManager">
<option name="originalFiles"> <option name="originalFiles">
<list> <list>
@ -13,7 +12,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" 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" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -1,31 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="dcab9632-7b1a-44d7-9283-be9b37640afc" name="Default Changelist" comment=""> <list default="true" id="1e646e82-3081-41be-8f2b-5b16afa0760d" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteHandler.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/compiler.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/compiler.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/encodings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/encodings.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<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$/src/main/java/net/seanomilk/tamablefoxes/EntityTamableFox.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java" 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/seanomilk/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/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/seanomilk/tamablefoxes/command/CommandSpawnTamableFox.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/command/CommandSpawnTamableFox.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/seanomilk/tamablefoxes/io/FileManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/io/FileManager.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/command/CommandSpawnTamableFox.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/command/CommandSpawnTamableFox.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/io/FileManager.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalSit.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalSit.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalSit.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.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/foxes.yml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/plugin.yml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/resources/plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/plugin.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/foxes.yml" beforeDir="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/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" />
<change beforePath="$PROJECT_DIR$/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst" beforeDir="false" afterPath="$PROJECT_DIR$/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.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" />
@ -45,59 +55,81 @@
<component name="MavenImportPreferences"> <component name="MavenImportPreferences">
<option name="importingSettings"> <option name="importingSettings">
<MavenImportingSettings> <MavenImportingSettings>
<option name="downloadDocsAutomatically" value="true" />
<option name="downloadSourcesAutomatically" value="true" />
<option name="importAutomatically" value="true" /> <option name="importAutomatically" value="true" />
</MavenImportingSettings> </MavenImportingSettings>
</option> </option>
</component> </component>
<component name="ProjectId" id="1WXR7SMZcGllgYVjIOg98VPV9wX" /> <component name="ProjectId" id="1WjKBUPOi3VX3mNa4prdDEUI26s" />
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showExcludedFiles" value="true" /> <option name="showExcludedFiles" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="ASKED_ADD_EXTERNAL_FILES" value="true" />
<property name="JavaMethodFindUsagesOptions.isOverridingMethods" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> <property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="WebServerToolWindowFactoryState" value="false" /> <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="$PROJECT_DIR$/../DexunGUI" /> <property name="project.structure.side.proportion" value="0.0" />
<property name="node.js.detected.package.eslint" value="true" /> <property name="restartRequiresConfirmation" value="false" />
<property name="node.js.detected.package.tslint" value="true" /> <property name="settings.editor.selected.configurable" value="configurable.group.appearance" />
<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="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
</component> </component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="D:\Ellie\ProjectDirectory\tamablefoxes-1\TamableFoxes-1" /> <recent name="E:\TamableFoxesCustomEntity\src\main\resources" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\Ellie\ProjectDirectory\tamablefoxes-1\TamableFoxes-1" />
</key> </key>
</component> </component>
<component name="RunManager"> <component name="RunManager" selected="JAR Application.Spigot1.15.1">
<configuration name="Spigot-1.15.1" type="JarApplication"> <configuration name="Spigot1.15.1" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../../TEST_SERVER/spigot-1.15.1.jar" /> <option name="JAR_PATH" value="$PROJECT_DIR$/../_TEST_SERVER_1.15.1_/spigot-1.15.1.jar" />
<option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\TEST_SERVER" /> <option name="WORKING_DIRECTORY" value="E:\_TEST_SERVER_1.15.1_\" />
<option name="ALTERNATIVE_JRE_PATH" />
<method v="2" />
</configuration>
<configuration name="Spigot1.15.1" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../_TEST_SERVER_1.15.1_/spigot-1.15.1.jar" />
<option name="WORKING_DIRECTORY" value="E:\_TEST_SERVER_1.15.1_" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<module name="GitTamableFoxes" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration default="true" type="JarApplication"> <configuration default="true" type="JarApplication">
<option name="JAR_PATH" value="$PROJECT_DIR$/../../TEST_SERVER/spigot-1.15.1.jar" /> <option name="JAR_PATH" value="$PROJECT_DIR$/../../_TEST_SERVER_2_/spigot-1.15.1.jar" />
<option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\TEST_SERVER" /> <option name="WORKING_DIRECTORY" value="D:\Code\java\spigotPlugins\_TEST_SERVER_2_" />
<option name="ALTERNATIVE_JRE_PATH" /> <option name="ALTERNATIVE_JRE_PATH" />
<module name="GitTamableFoxes" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="TamableFoxesCustomEntity build" type="MavenRunConfiguration" factoryName="Maven">
<MavenSettings>
<option name="myGeneralSettings" />
<option name="myRunnerSettings" />
<option name="myRunnerParameters">
<MavenRunnerParameters>
<option name="profiles">
<set />
</option>
<option name="goals">
<list>
<option value="clean" />
<option value="package" />
</list>
</option>
<option name="pomFileName" />
<option name="profilesMap">
<map />
</option>
<option name="resolveToWorkspace" value="false" />
<option name="workingDirPath" value="$PROJECT_DIR$" />
</MavenRunnerParameters>
</option>
</MavenSettings>
<method v="2" />
</configuration>
<list>
<item itemvalue="JAR Application.Spigot1.15.1" />
<item itemvalue="Maven.TamableFoxesCustomEntity build" />
</list>
</component> </component>
<component name="ServiceViewManager"> <component name="ServiceViewManager">
<option name="viewStates"> <option name="viewStates">
@ -116,107 +148,94 @@
</component> </component>
<component name="TaskManager"> <component name="TaskManager">
<task active="true" id="Default" summary="Default task"> <task active="true" id="Default" summary="Default task">
<changelist id="dcab9632-7b1a-44d7-9283-be9b37640afc" name="Default Changelist" comment="" /> <changelist id="1e646e82-3081-41be-8f2b-5b16afa0760d" name="Default Changelist" comment="" />
<created>1579293785651</created> <created>1579657428994</created>
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1579293785651</updated> <updated>1579657428994</updated>
<workItem from="1579293791372" duration="603000" />
<workItem from="1579301287898" duration="48000" />
<workItem from="1579301468407" duration="1926000" />
</task> </task>
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="COLUMN_ORDER" />
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
</component>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1579378826331"> <state x="552" y="179" key="#Project_Structure" timestamp="1579701669361">
<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="1579378826331" /> <state x="552" y="179" key="#Project_Structure/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579701669361" />
<state x="765" y="229" key="#com.intellij.ide.util.MemberChooser" timestamp="1579568884135"> <state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1579738103949">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="765" y="229" key="#com.intellij.ide.util.MemberChooser/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579568884135" /> <state x="414" y="174" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579738103949" />
<state x="740" y="274" key="FileChooserDialogImpl" timestamp="1579570099439"> <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="1579737522244">
<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="1579570099439" /> <state x="765" y="230" key="#com.intellij.ide.util.MemberChooser/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579737522244" />
<state x="794" y="418" width="356" height="203" key="Github.CreateGistDialog" timestamp="1579471488647"> <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="1579710595269">
<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="1579471488647" /> <state x="740" y="274" key="FileChooserDialogImpl/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579659182275" />
<state width="1877" height="256" key="GridCell.Tab.0.bottom" timestamp="1579581388624"> <state x="740" y="274" key="FileChooserDialogImpl/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579710595269" />
<state width="1877" height="205" key="GridCell.Tab.0.bottom" timestamp="1579882557469">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.0.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="233" key="GridCell.Tab.0.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907504" />
<state width="1877" height="256" key="GridCell.Tab.0.center" timestamp="1579581388624"> <state width="1877" height="205" key="GridCell.Tab.0.bottom/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882557469" />
<state width="1877" height="205" key="GridCell.Tab.0.center" timestamp="1579882557469">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.0.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="233" key="GridCell.Tab.0.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907503" />
<state width="1877" height="256" key="GridCell.Tab.0.left" timestamp="1579581388624"> <state width="1877" height="205" key="GridCell.Tab.0.center/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882557469" />
<state width="1877" height="205" key="GridCell.Tab.0.left" timestamp="1579882557469">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.0.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="233" key="GridCell.Tab.0.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907503" />
<state width="1877" height="256" key="GridCell.Tab.0.right" timestamp="1579581388624"> <state width="1877" height="205" key="GridCell.Tab.0.left/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882557469" />
<state width="1877" height="205" key="GridCell.Tab.0.right" timestamp="1579882557469">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.0.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="233" key="GridCell.Tab.0.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907503" />
<state width="1877" height="256" key="GridCell.Tab.1.bottom" timestamp="1579581388624"> <state width="1877" height="205" key="GridCell.Tab.0.right/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882557469" />
<state width="1877" height="203" key="GridCell.Tab.1.bottom" timestamp="1579882187586">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.1.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="254" key="GridCell.Tab.1.bottom/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907501" />
<state width="1877" height="256" key="GridCell.Tab.1.center" timestamp="1579581388624"> <state width="1877" height="203" key="GridCell.Tab.1.bottom/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882187586" />
<state width="1877" height="203" key="GridCell.Tab.1.center" timestamp="1579882187586">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.1.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="254" key="GridCell.Tab.1.center/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907501" />
<state width="1877" height="256" key="GridCell.Tab.1.left" timestamp="1579581388624"> <state width="1877" height="203" key="GridCell.Tab.1.center/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882187586" />
<state width="1877" height="203" key="GridCell.Tab.1.left" timestamp="1579882187586">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.1.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="254" key="GridCell.Tab.1.left/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907501" />
<state width="1877" height="256" key="GridCell.Tab.1.right" timestamp="1579581388624"> <state width="1877" height="203" key="GridCell.Tab.1.left/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882187586" />
<state width="1877" height="203" key="GridCell.Tab.1.right" timestamp="1579882187586">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state width="1877" height="256" key="GridCell.Tab.1.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579581388624" /> <state width="1877" height="254" key="GridCell.Tab.1.right/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579753907501" />
<state x="490" y="174" key="Maven.ArtifactSearchDialog" timestamp="1579373377880"> <state width="1877" height="203" key="GridCell.Tab.1.right/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579882187586" />
<state width="498" height="446" key="SwitcherDM" timestamp="1579705820492">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="490" y="174" key="Maven.ArtifactSearchDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579373377880" /> <state width="498" height="446" key="SwitcherDM/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579705820492" />
<state width="498" height="446" key="SwitcherDM" timestamp="1579469022098"> <state x="2283" y="214" key="com.intellij.ide.util.TipDialog" timestamp="1579874695988">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state x="363" y="214" key="com.intellij.ide.util.TipDialog/0.0.1920.1040/-1920.0.1920.1040@0.0.1920.1040" timestamp="1579735032362" />
<state x="2283" y="214" key="com.intellij.ide.util.TipDialog/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579874695988" />
<state x="1920" y="0" width="1288" height="1025" maximized="true" key="dock-window-1" timestamp="1579875027681">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state x="1920" y="0" width="1288" height="1025" maximized="true" key="dock-window-1/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579875027681" />
<state x="1920" y="0" width="1330" height="777" maximized="true" key="dock-window-2" timestamp="1579791856516">
<screen x="1920" y="0" width="1920" height="1040" />
</state>
<state x="1920" y="0" width="1330" height="777" maximized="true" key="dock-window-2/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579791856516" />
<state x="616" y="240" key="run.anything.popup" timestamp="1579710297088">
<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="616" y="240" key="run.anything.popup/1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1579710297088" />
<state x="656" y="343" key="com.intellij.ide.util.TipDialog" timestamp="1579535914963">
<screen x="0" 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="1579535914963" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java</url>
<line>440</line>
<option name="timeStamp" value="6" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component> </component>
</project> </project>

22
pom.xml
View File

@ -5,11 +5,11 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>net.seanomik</groupId> <groupId>net.seanomik</groupId>
<artifactId>tamableFoxes</artifactId> <artifactId>tamablefoxes</artifactId>
<version>1.4.1-SNAPSHOT</version> <version>1.5-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>TamableFoxes</name> <name>Tamablefoxes</name>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
@ -24,8 +24,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version> <version>3.7.0</version>
<configuration> <configuration>
<source>1.8</source> <source>${java.version}</source>
<target>1.8</target> <target>${java.version}</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
@ -39,7 +39,8 @@
<goal>shade</goal> <goal>shade</goal>
</goals> </goals>
<configuration> <configuration>
<outputFile>D:\Code\java\spigotPlugins\TEST_SERVER\plugins\${project.artifactId}-${project.version}.jar</outputFile> <!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_2_\plugins\${project.artifactId}-MC-1.15.1-${project.version}.jar</outputFile>-->
<outputFile>E:\_TEST_SERVER_1.15.1_\plugins\${project.artifactId}-MC-1.15.1-${project.version}.jar</outputFile>
<createDependencyReducedPom>false</createDependencyReducedPom> <createDependencyReducedPom>false</createDependencyReducedPom>
</configuration> </configuration>
</execution> </execution>
@ -70,11 +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.1-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency>-->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.15.1</version>
<scope>system</scope>
<systemPath>E:/spigot-1.15.1.jar</systemPath>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.WesJD.AnvilGUI</groupId> <groupId>com.github.WesJD.AnvilGUI</groupId>

View File

@ -0,0 +1,24 @@
package net.seanomik.tamablefoxes;
import org.bukkit.entity.Player;
public class Config {
private static TamableFoxes plugin = TamableFoxes.getPlugin();
public static boolean doesShowOwnerFoxName() {
return plugin.getConfig().getBoolean("show-owner-in-fox-name");
}
public static boolean doesShowNameTags() {
return plugin.getConfig().getBoolean("show-nametags");
}
public static boolean doesTamedAttackWildAnimals() {
return plugin.getConfig().getBoolean("tamed-behavior.attack-wild-animals");
}
public static boolean canPlayerTameFox(Player player) {
return !plugin.getConfig().getBoolean("enable-taming-permission") || (plugin.getConfig().getBoolean("enable-taming-permission") && (player.hasPermission("tamablefoxes.tame") || player.isOp()));
}
}

View File

@ -1,80 +1,120 @@
package net.seanomik.tamablefoxes; package net.seanomik.tamablefoxes;
import com.mojang.datafixers.Dynamic;
import net.minecraft.server.v1_15_R1.*; import net.minecraft.server.v1_15_R1.*;
import net.seanomik.tamablefoxes.pathfinding.*; import net.seanomik.tamablefoxes.pathfinding.*;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; import org.bukkit.entity.Item;
import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
import org.bukkit.entity.Fox;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.lang.reflect.Field; import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class EntityTamableFox extends EntityFox { public class EntityTamableFox extends EntityFox {
private static Fox thisFox; private boolean tamed;
private final TamableFoxes plugin; private boolean sitting;
private boolean sleeping;
private boolean isTamed;
private EntityLiving owner;
private String chosenName; private String chosenName;
private boolean sit = false; private EntityLiving owner;
private BukkitTask sittingRunnable; private UUID ownerUUID;
private FoxPathfindGoalSit goalSit; private FoxPathfinderGoalSit goalSit;
private PathfinderGoalNearestAttackableTarget goalAttack; private PathfinderGoal goalRandomSitting;
private PathfinderGoal goalBerryPicking;
private PathfinderGoal goalFleeSun;
private PathfinderGoal goalNearestVillage;
public int databaseID = -1; public EntityTamableFox(EntityTypes<? extends EntityFox> entitytypes, World world) {
super(entitytypes, world);
}
public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) { private PathfinderGoal getFoxInnerPathfinderGoal(String innerName, List<Object> args, List<Class<?>> argTypes) {
super(EntityTypes.FOX, world); return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, args, argTypes);
this.plugin = plugin; }
thisFox = (Fox) this.getBukkitEntity();
if (!plugin.getFoxUUIDs().containsKey(thisFox.getUniqueId())) { private PathfinderGoal getFoxInnerPathfinderGoal(String innerName) {
plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null); return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, Arrays.asList(), Arrays.asList());
}
this.setPersistent();
} }
@Override @Override
protected void initPathfinder() { protected void initPathfinder() {
this.goalSit = new FoxPathfindGoalSit(this); try {
this.goalSelector.a(1, new FoxPathfindGoalFloat(this)); this.goalSit = new FoxPathfinderGoalSit(this);
this.goalSelector.a(2, this.goalSit); this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // Swim
this.goalSelector.a(3, new FoxPathfindGoalMeleeAttack(this, 1.2000000476837158D, true)); this.goalSelector.a(1, this.goalSit);
this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // Unknown
entityliving -> !((EntityWolf) entityliving).isTamed()));
this.goalSelector.a(4, new FoxPathfindGoalFollowOwner(this, 1.35D, 10.0F, 2.0F));
this.goalSelector.a(4, new FoxPathfindGoalLungeUNKNOWN_USE(this));
this.goalSelector.a(5, new FoxPathfindGoalLunge(this));
this.goalSelector.a(5, new FoxPathfindGoalFleeSun(this, 1.25D));
this.goalSelector.a(5, new FoxPathfindGoalBreed(this, 1.0D));
this.goalSelector.a(7, new PathfinderGoalFollowParent(this, 1.1D));
this.goalSelector.a(7, new FoxPathfindGoalBeg(this, 8.0F));
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2));
this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2));
this.goalSelector.a(10, new FoxPathfindGoalRandomStrollLand(this, 1.0D));
this.targetSelector.a(1, new FoxPathfindGoalHurtByTarget(this));
this.targetSelector.a(2, new FoxPathfindGoalOwnerHurtByTarget(this));
this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false, // Panic
entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit)); this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) { // Breed
this.targetSelector.a(4, goalAttack); this.goalSelector.a(3, getFoxInnerPathfinderGoal("n", Arrays.asList(1.0D), Arrays.asList(double.class)));
// 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")); // Lunge shake
this.goalSelector.a(7, new EntityFox.o()); // Lunge
// Flee sun
goalFleeSun = getFoxInnerPathfinderGoal("s", Arrays.asList(1.25D), Arrays.asList(double.class));
this.goalSelector.a(7, goalFleeSun);
this.goalSelector.a(8, getFoxInnerPathfinderGoal("t")); // Sleeping under trees
this.goalSelector.a(9, getFoxInnerPathfinderGoal("h", Arrays.asList(this, 1.25D), Arrays.asList(EntityFox.class, double.class))); // Follow parent
// Nearest village
goalNearestVillage = getFoxInnerPathfinderGoal("q", Arrays.asList(32, 200), Arrays.asList(int.class, int.class));
this.goalSelector.a(9, goalNearestVillage);
// Pick berry bushes
goalBerryPicking = new EntityFox.f(1.2000000476837158D, 12, 2);
this.goalSelector.a(10, goalBerryPicking);
this.goalSelector.a(10, new PathfinderGoalLeapAtTarget(this, 0.4F));
this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 1.15D));
this.goalSelector.a(11, getFoxInnerPathfinderGoal("p")); // If a item is on the ground, go to it and take it
this.goalSelector.a(12, getFoxInnerPathfinderGoal("j", Arrays.asList(this, EntityHuman.class, 24.0f), Arrays.asList(EntityInsentient.class, Class.class, float.class))); // Look at player
// The random sitting(?)
this.goalRandomSitting = getFoxInnerPathfinderGoal("r");
this.goalSelector.a(13, goalRandomSitting);
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();
} }
this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0]));
} }
@Override @Override
@ -84,106 +124,311 @@ public class EntityTamableFox extends EntityFox {
this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED); this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
this.getAttributeMap().b(GenericAttributes.ARMOR); this.getAttributeMap().b(GenericAttributes.ARMOR);
this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS); this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D); this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(16.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK); this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D); this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D); this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
} }
public EntityFox createChild(EntityAgeable entityageable) { public boolean isOtherFoxFamily(EntityLiving living) {
WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle(); if (living instanceof EntityTamableFox) {
Location location = entityageable.getBukkitEntity().getLocation(); EntityTamableFox tamableFox = (EntityTamableFox) living;
Entity b = plugin.getCustomType().b(world, null, null, null,
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
EntityFox entityfox = (EntityFox) b;
entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType());
return entityfox;
}
protected void a(EntityItem entityitem) { return (tamableFox.isTamed() && tamableFox.getOwner().getUniqueID() == this.getOwner().getUniqueID());
ItemStack itemstack = entityitem.getItemStack(); } else {
if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem, return false;
itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
try {
int i = itemstack.getCount();
Method method;
if (i > 1) {
method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
method.setAccessible(true);
method.invoke(this, itemstack.cloneAndSubtract(i - 1));
method.setAccessible(false);
}
method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class);
method.setAccessible(true);
method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND));
method.setAccessible(false);
this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1));
this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F;
this.receive(entityitem, itemstack.getCount());
entityitem.die();
Field field = this.getClass().getSuperclass().getDeclaredField("bL");
field.setAccessible(true);
field.set(this, 0);
field.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
} }
}
public TamableFoxes getPlugin() {
return plugin;
}
public boolean isTamed() {
return this.isTamed;
} }
public void setTamed(boolean tamed) { public void setTamed(boolean tamed) {
this.isTamed = tamed; this.tamed = tamed;
// Remove attack goal if tamed // Remove goals that are not needed when named, or defeats the purpose of taming
if (isTamed && plugin.isTamedAttackRabbitChicken()) { this.goalSelector.a(goalRandomSitting);
this.targetSelector.a(goalAttack); this.goalSelector.a(goalBerryPicking);
} else { // Adds it this.goalSelector.a(goalFleeSun);
this.targetSelector.a(4, goalAttack); this.goalSelector.a(goalNearestVillage);
} }
public boolean isTamed() {
return tamed;
}
public void setOwner(EntityLiving entityLiving) {
this.owner = entityLiving;
updateFoxVisual();
}
public EntityLiving getOwner() {
return owner;
}
public void setOwnerUUID(UUID uuid) {
this.ownerUUID = uuid;
}
public UUID getOwnerUUID() {
return ownerUUID;
}
public void setChosenName(String name) {
this.chosenName = name;
updateFoxVisual();
} }
public String getChosenName() { public String getChosenName() {
return chosenName; return chosenName;
} }
public void setChosenName(String chosenName) { public void setMouthItem(ItemStack item) {
this.chosenName = chosenName; item.setCount(1);
setSlot(EnumItemSlot.MAINHAND, item);
TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(this);
}
public void setMouthItem(org.bukkit.inventory.ItemStack item) {
ItemStack itemNMS = CraftItemStack.asNMSCopy(item);
setMouthItem(itemNMS);
}
public ItemStack getMouthItem() {
return getEquipment(EnumItemSlot.MAINHAND);
}
public Item dropMouthItem() {
Item droppedItem = getBukkitEntity().getWorld().dropItem(getBukkitEntity().getLocation().add(0, 0, 0), CraftItemStack.asBukkitCopy(getMouthItem()));
setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
return droppedItem;
}
@Override
public void setSitting(boolean sit) {
super.setSitting(sit);
if (sleeping) {
sleeping = false;
super.setSleeping(false);
}
updateFoxVisual(); updateFoxVisual();
} }
public EntityLiving getOwner() { public void setHardSitting(boolean sit) {
return this.owner; super.setSitting(sit);
} this.sitting = sit;
if (sleeping) {
sleeping = false;
super.setSleeping(false);
}
public void setOwner(EntityLiving owner) {
this.owner = owner;
updateFoxVisual(); updateFoxVisual();
} }
public boolean toggleSitting() { public boolean toggleSitting() {
this.sit = !this.sit; this.sitting = !this.sitting;
updateFoxVisual(); setHardSitting(sitting);
plugin.sqLiteSetterGetter.saveFox(this); return this.sitting;
return this.sit;
} }
public void updateFox() { public boolean isJumping() {
updateFoxVisual(); return this.jumping;
} }
private void updateFoxVisual() {
new UpdateFoxRunnable().runTask(TamableFoxes.getPlugin());
}
private class UpdateFoxRunnable extends BukkitRunnable {
UpdateFoxRunnable() {
}
public void run() {
goalSit.setSitting(sitting);
if (tamed) {
getBukkitEntity().setCustomName((chosenName != null ? chosenName : "")
+ (owner != null && Config.doesShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : ""));
getBukkitEntity().setCustomNameVisible(Config.doesShowNameTags());
}
}
}
// Used for all the nasty stuff below.
private static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
}
// To remove a call to initializePathFinderGoals()
// This is all from every super class that has a method like this.
// This was needed because you cant call a "super.super.method()"
@Override
public void a(NBTTagCompound nbttagcompound) {
try {
// EntityLiving
this.setAbsorptionHearts(nbttagcompound.getFloat("AbsorptionAmount"));
if (nbttagcompound.hasKeyOfType("Attributes", 9) && this.world != null && !this.world.isClientSide) {
GenericAttributes.a(this.getAttributeMap(), nbttagcompound.getList("Attributes", 10));
}
if (nbttagcompound.hasKeyOfType("ActiveEffects", 9)) {
NBTTagList nbttaglist = nbttagcompound.getList("ActiveEffects", 10);
for(int i = 0; i < nbttaglist.size(); ++i) {
NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i);
MobEffect mobeffect = MobEffect.b(nbttagcompound1);
if (mobeffect != null) {
this.effects.put(mobeffect.getMobEffect(), mobeffect);
}
}
}
if (nbttagcompound.hasKey("Bukkit.MaxHealth")) {
NBTBase nbtbase = nbttagcompound.get("Bukkit.MaxHealth");
if (nbtbase.getTypeId() == 5) {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(((NBTTagFloat)nbtbase).asDouble());
} else if (nbtbase.getTypeId() == 3) {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(((NBTTagInt)nbtbase).asDouble());
}
}
if (nbttagcompound.hasKeyOfType("Health", 99)) {
this.setHealth(nbttagcompound.getFloat("Health"));
}
this.hurtTicks = nbttagcompound.getShort("HurtTime");
this.deathTicks = nbttagcompound.getShort("DeathTime");
this.hurtTimestamp = nbttagcompound.getInt("HurtByTimestamp");
if (nbttagcompound.hasKeyOfType("Team", 8)) {
String s = nbttagcompound.getString("Team");
ScoreboardTeam scoreboardteam = this.world.getScoreboard().getTeam(s);
boolean flag = scoreboardteam != null && this.world.getScoreboard().addPlayerToTeam(this.getUniqueIDString(), scoreboardteam);
if (!flag) {
LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", s);
}
}
if (nbttagcompound.getBoolean("FallFlying")) {
this.setFlag(7, true);
}
if (nbttagcompound.hasKeyOfType("SleepingX", 99) && nbttagcompound.hasKeyOfType("SleepingY", 99) && nbttagcompound.hasKeyOfType("SleepingZ", 99)) {
BlockPosition blockposition = new BlockPosition(nbttagcompound.getInt("SleepingX"), nbttagcompound.getInt("SleepingY"), nbttagcompound.getInt("SleepingZ"));
this.d(blockposition);
this.datawatcher.set(POSE, EntityPose.SLEEPING);
if (!this.justCreated) {
this.a(blockposition);
}
}
if (nbttagcompound.hasKeyOfType("Brain", 10)) {
this.bo = this.a(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("Brain")));
}
// EntityInsentient
NonNullList<ItemStack> by = (NonNullList<ItemStack>) Utils.getPrivateFieldValue(EntityInsentient.class, "by", this);
NonNullList<ItemStack> bx = (NonNullList<ItemStack>) Utils.getPrivateFieldValue(EntityInsentient.class, "bx", this);
boolean data;
if (nbttagcompound.hasKeyOfType("CanPickUpLoot", 1)) {
data = nbttagcompound.getBoolean("CanPickUpLoot");
if (isLevelAtLeast(nbttagcompound, 1) || data) {
this.setCanPickupLoot(data);
}
}
data = nbttagcompound.getBoolean("PersistenceRequired");
if (isLevelAtLeast(nbttagcompound, 1) || data) {
this.persistent = data;
}
NBTTagList nbttaglist;
int i;
if (nbttagcompound.hasKeyOfType("ArmorItems", 9)) {
nbttaglist = nbttagcompound.getList("ArmorItems", 10);
for(i = 0; i < by.size(); ++i) {
by.set(i, ItemStack.a(nbttaglist.getCompound(i)));
}
}
if (nbttagcompound.hasKeyOfType("HandItems", 9)) {
nbttaglist = nbttagcompound.getList("HandItems", 10);
for(i = 0; i < bx.size(); ++i) {
bx.set(i, ItemStack.a(nbttaglist.getCompound(i)));
}
}
if (nbttagcompound.hasKeyOfType("ArmorDropChances", 9)) {
nbttaglist = nbttagcompound.getList("ArmorDropChances", 5);
for(i = 0; i < nbttaglist.size(); ++i) {
this.dropChanceArmor[i] = nbttaglist.i(i);
}
}
if (nbttagcompound.hasKeyOfType("HandDropChances", 9)) {
nbttaglist = nbttagcompound.getList("HandDropChances", 5);
for(i = 0; i < nbttaglist.size(); ++i) {
this.dropChanceHand[i] = nbttaglist.i(i);
}
}
if (nbttagcompound.hasKeyOfType("Leash", 10)) {
//this.bG = nbttagcompound.getCompound("Leash");
Utils.setPrivateFieldValue(EntityInsentient.class, "bG", this, nbttagcompound.getCompound("Leash"));
}
this.p(nbttagcompound.getBoolean("LeftHanded"));
if (nbttagcompound.hasKeyOfType("DeathLootTable", 8)) {
this.lootTableKey = new MinecraftKey(nbttagcompound.getString("DeathLootTable"));
this.lootTableSeed = nbttagcompound.getLong("DeathLootTableSeed");
}
this.setNoAI(nbttagcompound.getBoolean("NoAI"));
// EntityAgeable
this.setAgeRaw(nbttagcompound.getInt("Age"));
this.c = nbttagcompound.getInt("ForcedAge");
this.ageLocked = nbttagcompound.getBoolean("AgeLocked");
// EntityAnimal
this.loveTicks = nbttagcompound.getInt("InLove");
this.breedCause = nbttagcompound.b("LoveCause") ? nbttagcompound.a("LoveCause") : null;
NBTTagList foxNBTTagList = nbttagcompound.getList("TrustedUUIDs", 10);
Method method = this.getClass().getSuperclass().getDeclaredMethod("b", UUID.class);
method.setAccessible(true);
for (int index = 0; index < foxNBTTagList.size(); ++index) {
//this.b(GameProfileSerializer.b(nbttaglist.getCompound(i)));
method.invoke(this, GameProfileSerializer.b(foxNBTTagList.getCompound(index)));
}
method.setAccessible(false);
this.setSleeping(nbttagcompound.getBoolean("Sleeping"));
this.setFoxType(EntityFox.Type.a(nbttagcompound.getString("Type")));
// Use super class due to the new set sitting causing errors
super.setSitting(nbttagcompound.getBoolean("Sitting"));
this.setCrouching(nbttagcompound.getBoolean("Crouching"));
} catch (Exception e) {
e.printStackTrace();
}
}
// To remove the last call to initializePathFinderGoals()
// Cant just override because its a private method
@Override
@Nullable
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler,
EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) { EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) {
BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this)); BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
@ -218,31 +463,4 @@ public class EntityTamableFox extends EntityFox {
return groupdataentity; return groupdataentity;
} }
public boolean isJumping() {
return this.jumping;
}
private void updateFoxVisual() {
this.sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
}
private class UpdateFoxRunnable extends BukkitRunnable {
private final TamableFoxes plugin;
UpdateFoxRunnable(TamableFoxes plugin) {
this.plugin = plugin;
}
public void run() {
goalSit.setSitting(sit);
thisFox.setVelocity(new Vector(0, 0, 0));
setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
getBukkitEntity().setCustomName((chosenName != null ? chosenName : "")
+ (owner != null && plugin.isShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : ""));
getBukkitEntity().setCustomNameVisible(plugin.isShowNameTags());
}
}
} }

View File

@ -1,232 +1,132 @@
package net.seanomik.tamablefoxes; package net.seanomik.tamablefoxes;
import com.google.common.collect.Maps; import com.google.common.collect.Iterables;
import com.mojang.datafixers.DataFixUtils; import com.google.common.collect.Lists;
import com.mojang.datafixers.types.Type; import net.minecraft.server.v1_15_R1.EntityFox;
import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.EnumItemSlot;
import net.seanomik.tamablefoxes.command.CommandSpawnTamableFox; import net.seanomik.tamablefoxes.command.CommandSpawnTamableFox;
import net.seanomik.tamablefoxes.io.FileManager;
import net.minecraft.server.v1_15_R1.*;
import net.seanomik.tamablefoxes.sqlite.SQLiteHandler; import net.seanomik.tamablefoxes.sqlite.SQLiteHandler;
import net.seanomik.tamablefoxes.sqlite.SQLiteSetterGetter; import net.seanomik.tamablefoxes.sqlite.SQLiteSetterGetter;
import net.wesjd.anvilgui.AnvilGUI; import net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftFox;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Fox; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.*; import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import java.util.Arrays; import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
// @TODO: Add language.yml // @TODO: Add language.yml
// Foxes will be loaded in as sitting, even if they weren't when the server was shutdown
// Add fox sleeping when the player sleeps
public final class TamableFoxes extends JavaPlugin implements Listener {
private static TamableFoxes plugin;
public List<EntityTamableFox> spawnedFoxes = new ArrayList<>();
public class TamableFoxes extends JavaPlugin implements Listener { public SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter();
public SQLiteHandler sqLiteHandler = new SQLiteHandler();
public static final String ITEM_INSPECTOR_LORE = ChatColor.BLUE + "Tamable Fox Inspector"; @Override
public static final String TAG_TAME_FOX = "tameablefox"; public void onLoad() {
String version = Bukkit.getServer().getClass().getPackage().getName();
private FileManager fileManager = new FileManager(this); if (!version.equals("org.bukkit.craftbukkit.v1_15_R1")) {
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + "This plugin version only supports 1.15.1! Not registering entity!");
return;
}
private Map<UUID, UUID> foxUUIDs = Maps.newHashMap(); // FoxUUID, OwnerUUID try { // Replace the fox entity
private EntityTypes customType; Field field = EntityTypes.FOX.getClass().getDeclaredField("ba");
private boolean isOnLoad = true; field.setAccessible(true);
private Map<UUID, Entity> lookupCache = Maps.newHashMap();
private List<EntityTamableFox> spawnedFoxes; // Remove the final modifier from the "ba" variable
private FileManager.Config config;//, configFoxes; Field fieldMutable = field.getClass().getDeclaredField("modifiers");
public static SQLiteHandler sqLiteHandler = new SQLiteHandler(); fieldMutable.setAccessible(true);
public static SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter(); fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL);
fieldMutable.setAccessible(false);
field.set(EntityTypes.FOX, (EntityTypes.b<EntityFox>) (type, world) -> new EntityTamableFox(type, world));
field.setAccessible(false);
getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + "Replaced tamable fox entity!");
} catch (Exception e) {
e.printStackTrace();
getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + "Failed to replace tamable fox entity!");
}
}
@Override @Override
public void onEnable() { public void onEnable() {
String version = Bukkit.getServer().getClass().getPackage().getName(); String version = Bukkit.getServer().getClass().getPackage().getName();
if (!version.equals("org.bukkit.craftbukkit.v1_15_R1")) { if (!version.equals("org.bukkit.craftbukkit.v1_15_R1")) {
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "This plugin version only supports 1.15.1!"); Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + "This plugin version only supports 1.15.1! Disabling plugin!");
getServer().getPluginManager().disablePlugin(this); getServer().getPluginManager().disablePlugin(this);
return; return;
} }
this.config = fileManager.getConfig("config.yml"); plugin = this;
this.config.copyDefaults(true).save();
sqLiteHandler.connect(); getServer().getPluginManager().registerEvents(this, this);
sqLiteSetterGetter.createTablesIfNotExist();
this.getServer().getPluginManager().registerEvents(this, this);
this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this)); this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this));
final Map<String, Type<?>> types = (Map<String, Type<?>>) DataConverterRegistry.a() sqLiteSetterGetter.createTablesIfNotExist();
.getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion())) this.saveDefaultConfig();
.findChoiceType(DataConverterTypes.ENTITY).types(); getConfig().options().copyDefaults(true);
types.put("minecraft:" + TAG_TAME_FOX, types.get("minecraft:fox")); saveConfig();
EntityTypes.a<net.minecraft.server.v1_15_R1.Entity> a = EntityTypes.a.a((entityTypes, world) -> spawnedFoxes = sqLiteSetterGetter.loadFoxes();
new EntityTamableFox(this, entityTypes, world), EnumCreatureType.AMBIENT);
customType = IRegistry.a(IRegistry.ENTITY_TYPE, "tameablefox", a.a("tameablefox"));
this.replaceFoxesOnLoad();
} }
@Override @Override
public void onDisable() { public void onDisable() {
try { getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + "Saving foxes.");
for (EntityTamableFox fox : spawnedFoxes) { sqLiteSetterGetter.saveFoxes(spawnedFoxes);
sqLiteSetterGetter.saveFox(fox);
fox.getBukkitEntity().remove();
}
getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.GREEN + "Saved all foxes successfully!");
} catch (Exception e) {
getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.RED + "Failed to save foxes!");
}
} }
private void replaceFoxesOnLoad() { @EventHandler
/*int amountReplaced = 0; public void onWorldSaveEvent(WorldSaveEvent event) {
sqLiteSetterGetter.saveFoxes(spawnedFoxes);
for (World world : Bukkit.getWorlds()) {
Chunk[] loadedChunks = world.getLoadedChunks();
for (Chunk chunk : loadedChunks) {
Entity[] entities = chunk.getEntities();
for (Entity entity : entities) {
if (!(entity instanceof Fox))
continue;
if (this.isTamableFox(entity))
continue;
EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
//final YamlConfiguration configuration = configFoxes.get();
// get living entity data
if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner");
// make new data
if (owner.equals("none")) {
foxUUIDs.replace(tamableFox.getUniqueID(), null);
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
} else {
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
tamableFox.setTamed(true);
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
}
// set name
if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
final String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
tamableFox.setChosenName(name);
}
// delete old data
configuration.set("Foxes." + entity.getUniqueId(), null);
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
tamableFox.updateFox();
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
entityMouthItem.setAmount(1);
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(entityMouthItem));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
} else {
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
entityMouthItem.setAmount(1);
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(entityMouthItem));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
}
entity.remove();
++amountReplaced;
}
}
}
configFoxes.save();*/
spawnedFoxes = sqLiteSetterGetter.spawnFoxes();
this.isOnLoad = false;
}
public net.minecraft.server.v1_15_R1.Entity spawnTamableFox(Location location, net.minecraft.server.v1_15_R1.EntityFox.Type type) {
WorldServer world = ((CraftWorld) location.getWorld()).getHandle();
EntityTamableFox spawnedFox = (EntityTamableFox) customType.b(world, null, null, null,
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
if (!world.addEntity(spawnedFox)) { // Throw a error if the fox failed to spawn
throw new RuntimeException("Failed to spawn fox!");
}
spawnedFox.setFoxType(type);
sqLiteSetterGetter.saveFox((EntityTamableFox) spawnedFox);
return spawnedFox;
}
private class SaveFoxRunnable extends BukkitRunnable {
private final TamableFoxes plugin;
SaveFoxRunnable(TamableFoxes plugin) {
this.plugin = plugin;
}
public void run() {
try {
sqLiteSetterGetter.saveFoxes(spawnedFoxes);
getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.GREEN + "Saved all foxes successfully!");
} catch (Exception e) {
getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.RED + "Failed to save foxes!");
}
}
} }
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
getFoxesOf(player).forEach(uuid -> { for (EntityTamableFox fox : getFoxesOf(player)) {
EntityTamableFox tamableFox = getSpawnedFox(uuid); fox.setOwner((EntityLiving) ((CraftEntity) player).getHandle());
tamableFox.setOwner(((CraftPlayer) player).getHandle()); }
tamableFox.setTamed(true); }
foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
}); @EventHandler
public void onEntitySpawn(EntitySpawnEvent event) {
Entity entity = event.getEntity();
if (Utils.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
spawnedFoxes.add(tamableFox);
}
} }
@EventHandler @EventHandler
@ -234,76 +134,35 @@ public class TamableFoxes extends JavaPlugin implements Listener {
Entity entity = event.getRightClicked(); Entity entity = event.getRightClicked();
Player player = event.getPlayer(); Player player = event.getPlayer();
if (event.getHand() != EquipmentSlot.HAND) if (event.getHand() != EquipmentSlot.HAND) return;
return;
final ItemStack playerHand = player.getInventory().getItemInMainHand(); ItemStack itemHand = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = playerHand.getItemMeta(); ItemMeta handMeta = itemHand.getItemMeta();
if (itemMeta != null && playerHand.getType() == Material.REDSTONE_TORCH // Checks if the entity is EntityTamableFox and that the player is allowed to tame foxes
&& itemMeta.hasLore() && itemMeta.getLore().contains(ITEM_INSPECTOR_LORE)) { if (Utils.isTamableFox(entity)) {
List<String> lore;
if (!this.isTamableFox(entity)) {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId(),
"Entity type: " + ((CraftEntity) entity).getHandle());
} else {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId(),
"Tamable",
"Owner: " + ((tamableFox.getOwner() == null) ? "none" : tamableFox.getOwner().getName()));
}
// Update item
itemMeta.setLore(lore);
playerHand.setItemMeta(itemMeta);
player.getInventory().setItemInMainHand(playerHand);
event.setCancelled(true);
player.sendMessage(getPrefix() + "Inspected Entity.");
return;
}
if (this.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle(); EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.isTamed() && tamableFox.getOwner() != null && // Check if its tamed but ignore it if the player is holding sweet berries for breeding
playerHand.getType() != Material.SWEET_BERRIES) { if (tamableFox.isTamed() && tamableFox.getOwner() != null && itemHand.getType() != Material.SWEET_BERRIES) {
// if this fox is theirs if (tamableFox.getOwner().getUniqueID() == player.getUniqueId()) {
if (foxUUIDs.get(entity.getUniqueId()).equals(player.getUniqueId())) {
if (player.isSneaking()) { if (player.isSneaking()) {
net.minecraft.server.v1_15_R1.ItemStack wolfHolding = tamableFox.getEquipment(EnumItemSlot.MAINHAND); net.minecraft.server.v1_15_R1.ItemStack foxMouth = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
net.minecraft.server.v1_15_R1.ItemStack playerItemInHandNMS;
if (wolfHolding.isEmpty()) {
if (playerHand.getType() == Material.AIR) {
return;
}
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand); if (foxMouth.isEmpty() && itemHand.getType() != Material.AIR) { // Giving an item
playerItemInHandNMS.setCount(1); tamableFox.setMouthItem(itemHand);
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS); itemHand.setAmount(itemHand.getAmount() - 1);
playerHand.setAmount(playerHand.getAmount() - 1); } else if (!foxMouth.isEmpty() && itemHand.getType() == Material.AIR) { // Taking the item
player.getInventory().setItemInMainHand(playerHand); tamableFox.dropMouthItem();
} else if (playerHand.getType() == Material.AIR) { } else if (!foxMouth.isEmpty() && itemHand.getType() != Material.AIR){ // Swapping items
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D), // Drop item
CraftItemStack.asBukkitCopy(wolfHolding)); tamableFox.dropMouthItem();
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
} else { // Give item and take one away from player
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand); tamableFox.setMouthItem(itemHand);
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D), itemHand.setAmount(itemHand.getAmount() - 1);
CraftItemStack.asBukkitCopy(wolfHolding));
playerItemInHandNMS.setCount(1);
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
playerHand.setAmount(playerHand.getAmount() - 1);
player.getInventory().setItemInMainHand(playerHand);
} }
} else if (playerHand.getType() == Material.NAME_TAG) { } else if (itemHand.getType() == Material.NAME_TAG) {
ItemMeta handMeta = playerHand.getItemMeta();
tamableFox.setChosenName(handMeta.getDisplayName()); tamableFox.setChosenName(handMeta.getDisplayName());
} else { } else {
tamableFox.toggleSitting(); tamableFox.toggleSitting();
@ -311,39 +170,42 @@ public class TamableFoxes extends JavaPlugin implements Listener {
event.setCancelled(true); event.setCancelled(true);
} }
} else if (playerHand.getType() == Material.CHICKEN) { } else if (itemHand.getType() == Material.CHICKEN && Config.canPlayerTameFox(player)) {
if (Math.random() < 0.33D) { if (Math.random() < 0.33D) { // tamed
tamableFox.setTamed(true); tamableFox.setTamed(true);
tamableFox.setOwner(((CraftPlayer) player).getHandle()); tamableFox.setOwner(((CraftPlayer) player).getHandle());
foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId()); // store uuid
player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D); player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
// Name process // Name fox
player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + "You just tamed a wild fox!"); player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + "You just tamed a wild fox!");
player.sendMessage(ChatColor.RED + "What do you want to call it?"); player.sendMessage(ChatColor.RED + "What do you want to call it?");
tamableFox.setChosenName("???"); tamableFox.setChosenName("???");
//TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(tamableFox);
event.setCancelled(true); event.setCancelled(true);
new AnvilGUI.Builder() new AnvilGUI.Builder()
.onComplete((plr, text) -> { // Called when the inventory output slot is clicked .onComplete((plr, text) -> { // Called when the inventory output slot is clicked
if(!text.equals("")) { if(!text.equals("")) {
tamableFox.setChosenName(text); tamableFox.setChosenName(text);
plr.sendMessage(getPrefix() + ChatColor.GREEN + text + " is perfect!"); plr.sendMessage(Utils.getPrefix() + ChatColor.GREEN + text + " is perfect!");
TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(tamableFox);
} }
return AnvilGUI.Response.close(); return AnvilGUI.Response.close();
}) })
//.preventClose() // Prevents the inventory from being closed //.preventClose() // Prevents the inventory from being closed
.text("Fox name") // Sets the text the GUI should start with .text("Fox name") // Sets the text the GUI should start with
.plugin(this) // Set the plugin instance .plugin(this) // Set the plugin instance
.open(player); // Opens the GUI for the player provided .open(player); // Opens the GUI for the player provided
} else { // Tame failed
} else { // Failed to tame
player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D); player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
} }
if (!player.getGameMode().equals(GameMode.CREATIVE)) { if (!player.getGameMode().equals(GameMode.CREATIVE)) {
playerHand.setAmount(playerHand.getAmount() - 1); itemHand.setAmount(itemHand.getAmount() - 1);
} }
event.setCancelled(true); event.setCancelled(true);
@ -351,112 +213,18 @@ public class TamableFoxes extends JavaPlugin implements Listener {
} }
} }
@EventHandler public EntityTamableFox spawnTamableFox(Location loc, EntityFox.Type type) {
public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) { EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
Player player = event.getPlayer(); tamableFox.setFoxType(type);
getFoxesOf(player).forEach(uuid -> { return tamableFox;
EntityTamableFox tamableFox = getSpawnedFox(uuid);
if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) {
tamableFox.setSleeping(true);
} else return; // Stop the loop, no point of iterating through all the foxes if the condition will be the same.
});
} }
@EventHandler public List<EntityTamableFox> getFoxesOf(Player player) {
public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) { return spawnedFoxes.stream().filter(fox -> fox.getOwnerUUID() != null && fox.getOwnerUUID().equals(player.getUniqueId())).collect(Collectors.toList());
Player player = event.getPlayer();
getFoxesOf(player).forEach(uuid -> {
EntityTamableFox tamableFox = getSpawnedFox(uuid);
tamableFox.setSleeping(false);
});
} }
@EventHandler public static TamableFoxes getPlugin() {
public void onCreatureSpawnEvent(CreatureSpawnEvent event) { return plugin;
org.bukkit.entity.Entity entity = event.getEntity();
if (entity instanceof Fox && !this.isTamableFox(entity)) {
net.minecraft.server.v1_15_R1.EntityFox.Type foxType = ((EntityFox) ((CraftEntity) entity).getHandle()).getFoxType();
spawnTamableFox(entity.getLocation(), foxType);
event.setCancelled(true);
}
} }
@EventHandler
public void onEntityDeathEvent(EntityDeathEvent event) {
Entity entity = event.getEntity();
if (!this.isTamableFox(entity)) return; // Is the entity a tamable fox?
// Remove the fox from storage
lookupCache.remove(entity.getUniqueId());
foxUUIDs.remove(entity.getUniqueId());
spawnedFoxes.remove(entity.getUniqueId());
// Notify the owner
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.getOwner() != null) {
Player owner = ((EntityPlayer)tamableFox.getOwner()).getBukkitEntity();
owner.sendMessage(getPrefix() + ChatColor.RED + tamableFox.getChosenName() + " was killed!");
}
// Remove the fox from database
sqLiteSetterGetter.removeFox(tamableFox);
}
public EntityTamableFox getSpawnedFox(UUID uniqueId) {
for (EntityTamableFox fox : spawnedFoxes) {
if (fox.getUniqueID() == uniqueId) {
return fox;
}
}
return null;
}
public boolean isTamableFox(org.bukkit.entity.Entity entity) {
return ((CraftEntity) entity).getHandle().getClass().getName().contains("TamableFox") || ((CraftEntity) entity).getHandle() instanceof EntityTamableFox;
}
public List<UUID> getFoxesOf(Player player) {
return foxUUIDs.entrySet().stream().filter(foxPlayer -> foxPlayer.getValue() != null && foxPlayer.getValue().equals(player.getUniqueId())).map(Map.Entry::getKey).collect(Collectors.toList());
}
public FileManager getFileManager() {
return fileManager;
}
public FileManager.Config getMainConfig() {
return config;
}
public EntityTypes getCustomType() {
return customType;
}
public Map<UUID, UUID> getFoxUUIDs() {
return foxUUIDs;
}
public List<EntityTamableFox> getSpawnedFoxes() {
return spawnedFoxes;
}
public static String getPrefix() {
//return ChatColor.translateAlternateColorCodes('&', (String) config.get("prefix"));
return ChatColor.RED + "[Tamable Foxes] ";
}
public boolean isShowOwnerFoxName() {
return (boolean) config.get("show-owner-in-fox-name");
}
public boolean isShowNameTags() {
return (boolean) config.get("show-nametags");
}
public boolean isTamedAttackRabbitChicken() {
return (boolean) config.get("tamed-behavior.attack-chicken-rabbit");
}
} }

View File

@ -0,0 +1,89 @@
package net.seanomik.tamablefoxes;
import org.bukkit.ChatColor;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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() {
return ChatColor.RED + "[Tamable Foxes] ";
}
public static Object getPrivateFieldValue(Class c, String field, Object instance) {
Object value = null;
try {
Field f = c.getDeclaredField(field);
f.setAccessible(true);
value = f.get(instance);
f.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
public static void setPrivateFieldValue(Class c, String field, Object instance, Object value) {
try {
Field f = c.getDeclaredField(field);
f.setAccessible(true);
f.set(instance, value);
f.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sendConsoleMessage(String message) {
TamableFoxes.getPlugin().getServer().getConsoleSender().sendMessage(message);
}
public static Class<?> getPrivateInnerClass(Class outer, String innerName) {
for (Class<?> declaredClass : outer.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals(innerName)) return declaredClass;
}
return null;
}
public static Object instantiatePrivateInnerClass(Class outer, String innerName, Object outerObject, List<Object> args, List<Class<?>> argTypes) {
try {
Class<?> innerClass = getPrivateInnerClass(outer, innerName);
Object[] argObjects = new Object[args.size()+1];
Class<?>[] argClasses = new Class<?>[argTypes.size()+1];
// Needed due to how List#toArray() converts the classes to objects
for (int i = 0; i < argClasses.length; i++) {
if (i == argClasses.length-1) continue;
argObjects[i+1] = args.get(i);
argClasses[i+1] = argTypes.get(i);
}
argObjects[0] = outerObject;
argClasses[0] = outer;
Constructor<?> innerConstructor = innerClass.getDeclaredConstructor(argClasses);
innerConstructor.setAccessible(true);
Object instantiatedClass = innerConstructor.newInstance(argObjects);
innerConstructor.setAccessible(false);
return instantiatedClass;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -1,8 +1,11 @@
package net.seanomik.tamablefoxes.command; package net.seanomik.tamablefoxes.command;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
import net.seanomik.tamablefoxes.Config;
import net.seanomik.tamablefoxes.EntityTamableFox; import net.seanomik.tamablefoxes.EntityTamableFox;
import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.TamableFoxes;
import net.minecraft.server.v1_15_R1.EntityFox; import net.minecraft.server.v1_15_R1.EntityFox;
import net.seanomik.tamablefoxes.Utils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -42,56 +45,37 @@ public class CommandSpawnTamableFox implements TabExecutor {
switch (args[0]) { switch (args[0]) {
case "red": case "red":
try { try {
EntityTamableFox fox = (EntityTamableFox) plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED); EntityTamableFox fox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED);
plugin.getSpawnedFoxes().add(fox); //plugin.getSpawnedFoxes().add(fox);
plugin.sqLiteSetterGetter.saveFox(fox); plugin.sqLiteSetterGetter.saveFox(fox);
player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.RED + "Red" + ChatColor.WHITE + " fox."); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.RED + "Red" + ChatColor.WHITE + " fox.");
} catch (Exception e) { } catch (Exception e) {
player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!"); e.printStackTrace();
player.sendMessage(Utils.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!");
} }
break; break;
case "snow": case "snow":
try { try {
EntityTamableFox spawnedFox = (EntityTamableFox) plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW); EntityTamableFox spawnedFox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW);
plugin.getSpawnedFoxes().add(spawnedFox); //plugin.getSpawnedFoxes().add(spawnedFox);
plugin.sqLiteSetterGetter.saveFox(spawnedFox); plugin.sqLiteSetterGetter.saveFox(spawnedFox);
player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.AQUA + "Snow" + ChatColor.WHITE + " fox."); player.sendMessage(Utils.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.AQUA + "Snow" + ChatColor.WHITE + " fox.");
} catch (Exception e) { } catch (Exception e) {
player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!"); e.printStackTrace();
} player.sendMessage(Utils.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!");
break;
case "verbose":
player.sendMessage(plugin.getFoxUUIDs().toString());
break;
case "inspect":
ItemStack itemStack = new ItemStack(Material.REDSTONE_TORCH, 1);
ItemMeta itemMeta = itemStack.getItemMeta();
List<String> lore = Collections.singletonList(TamableFoxes.ITEM_INSPECTOR_LORE);
itemMeta.setLore(lore);
itemStack.setItemMeta(itemMeta);
if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
player.getInventory().setItemInMainHand(itemStack);
player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Gave Inspector item.");
} else if (player.getInventory().firstEmpty() == -1) {
player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Your inventory is full!");
} else {
player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Added item to inventory.");
player.getInventory().addItem(itemStack);
} }
break; break;
case "reload": case "reload":
plugin.getMainConfig().reload(); plugin.reloadConfig();
//plugin.getConfigFoxes().reload(); player.sendMessage(Utils.getPrefix() + ChatColor.GREEN + "Reloaded.");
player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Reloaded.");
break; break;
default: default:
player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | verbose | inspect | reload]"); player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | reload]");
} }
} else { } else {
player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | verbose | inspect | reload]"); player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | reload]");
} }
return true; return true;
@ -102,8 +86,6 @@ public class CommandSpawnTamableFox implements TabExecutor {
return new LinkedList<>(Arrays.asList( return new LinkedList<>(Arrays.asList(
"red", "red",
"snow", "snow",
"verbose",
"inspect",
"reload" "reload"
)); ));
} }

View File

@ -1,113 +0,0 @@
package net.seanomik.tamablefoxes.io;
import com.google.common.collect.Maps;
import net.seanomik.tamablefoxes.TamableFoxes;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
public class FileManager {
private final TamableFoxes plugin;
private HashMap<String, Config> configs;
public FileManager(TamableFoxes plugin) {
this.plugin = plugin;
this.configs = Maps.newHashMap();
}
public Config getConfig(String name) {
if (!this.configs.containsKey(name)) {
this.configs.put(name, new Config(name));
}
return this.configs.get(name);
}
public Config saveConfig(String name) {
return this.getConfig(name).save();
}
public Config reloadConfig(String name) {
return this.getConfig(name).reload();
}
public class Config {
private String name;
private File file;
private YamlConfiguration config;
public Config(String name) {
this.name = name;
}
public Config save() {
if (this.config != null && this.file != null) {
try {
if (this.config.getKeys(true).size() != 0) {
this.config.save(this.file);
}
} catch (IOException e) {
e.printStackTrace();
}
return this;
} else {
return this;
}
}
public YamlConfiguration get() {
if (this.config == null) {
this.reload();
}
return this.config;
}
public Config saveDefaultConfig() {
this.file = new File(plugin.getDataFolder(), this.name);
plugin.saveResource(this.name, false);
return this;
}
public Config reload() {
if (this.file == null) {
this.file = new File(plugin.getDataFolder(), this.name);
}
this.config = YamlConfiguration.loadConfiguration(this.file);
try {
Reader defConfigStream = new InputStreamReader(plugin.getResource(this.name), StandardCharsets.UTF_8);
if (defConfigStream != null) {
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
this.config.setDefaults(defConfig);
}
} catch (NullPointerException ignored) {
}
return this;
}
public Config copyDefaults(boolean force) {
this.get().options().copyDefaults(force);
return this;
}
public Config set(String key, Object value) {
this.get().set(key, value);
return this;
}
public Object get(String key) {
return this.get().get(key);
}
}
}

View File

@ -1,64 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.*;
import java.util.EnumSet;
public class FoxPathfindGoalBeg extends PathfinderGoal {
private final EntityFox a;
private final EntityTamableFox z;
private final World c;
private final float d;
private final PathfinderTargetCondition f;
private EntityHuman b;
private int e;
public FoxPathfindGoalBeg(EntityTamableFox tamableFox, float var1) {
this.a = tamableFox;
this.c = tamableFox.world;
this.d = var1;
this.f = (new PathfinderTargetCondition()).a((double) var1).a().b().d();
this.a(EnumSet.of(PathfinderGoal.Type.LOOK));
this.z = tamableFox;
}
public boolean a() {
this.b = this.c.a(this.f, this.a);
return this.b != null && this.a(this.b);
}
public boolean b() {
if (!this.b.isAlive()) {
return false;
} else if (this.a.h(this.b) > (double) (this.d * this.d)) {
return false;
} else {
return this.e > 0 && this.a(this.b);
}
}
public void e() {
this.a.getControllerLook().a(this.b.locX(), this.b.locY() + (double) this.b.getHeadHeight(), this.b.locZ(), 10.0F, (float) this.a.dU());
--this.e;
}
private boolean a(EntityHuman var0) {
EnumHand[] var2 = EnumHand.values();
int var3 = var2.length;
for (int var4 = 0; var4 < var3; ++var4) {
if (this.z.isTamed() && var0.getItemInMainHand().getItem() == Items.SWEET_BERRIES) {
return true;
}
if (this.a.i(var0.getItemInMainHand())) {
return true;
}
}
return false;
}
}

View File

@ -1,113 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.*;
import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityBreedEvent;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.List;
public class FoxPathfindGoalBreed extends PathfinderGoal {
private static final PathfinderTargetCondition d = new PathfinderTargetCondition().a(8.0D).a().b().c();
protected final EntityTamableFox animal;
protected final World b;
private final Class<? extends EntityAnimal> e;
private final double g;
protected EntityAnimal partner;
private int f;
public FoxPathfindGoalBreed(EntityTamableFox entity, double d0) {
this(entity, d0, entity.getClass());
}
public FoxPathfindGoalBreed(EntityTamableFox entity, double d0, Class<? extends EntityAnimal> oclass) {
this.animal = entity;
this.b = entity.world;
this.e = oclass;
this.g = d0;
a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK));
}
public boolean a() {
if (!this.animal.isInLove()) {
return false;
}
this.partner = h();
return this.partner != null;
}
public boolean b() {
return (this.partner.isAlive()) && (this.partner.isInLove()) && (this.f < 60);
}
public void d() {
this.partner = null;
this.f = 0;
}
public void e() {
this.animal.getControllerLook().a(this.partner, 10.0F, this.animal.dU());
this.animal.getNavigation().a(this.partner, this.g);
this.f += 1;
if ((this.f >= 60) && (this.animal.h(this.partner) < 9.0D)) {
g();
}
}
@Nullable
private EntityAnimal h() {
List<EntityAnimal> list = this.b.a(this.e, d, this.animal, this.animal.getBoundingBox().g(8.0D));
double d0 = Double.MAX_VALUE;
EntityAnimal entityanimal = null;
for (EntityAnimal entityAnimal : list) {
if ((this.animal.mate(entityAnimal)) && (this.animal.h(entityAnimal) < d0)) {
entityanimal = entityAnimal;
d0 = this.animal.h(entityAnimal);
}
}
return entityanimal;
}
protected void g() {
EntityAgeable entityAgeable = this.animal.createChild(this.animal);
EntityTamableFox tamableFoxAgeable = (EntityTamableFox) entityAgeable.getBukkitEntity().getHandle();
if (tamableFoxAgeable != null) {
EntityPlayer entityplayer = this.animal.getBreedCause();
if ((entityplayer == null) && (this.partner.getBreedCause() != null)) {
entityplayer = this.partner.getBreedCause();
}
int experience = this.animal.getRandom().nextInt(7) + 1;
EntityBreedEvent entityBreedEvent = CraftEventFactory.callEntityBreedEvent(entityAgeable, this.animal, this.partner, entityplayer, this.animal.breedItem, experience);
if (entityBreedEvent.isCancelled()) {
return;
}
experience = entityBreedEvent.getExperience();
if (entityplayer != null) {
entityplayer.a(StatisticList.ANIMALS_BRED);
CriterionTriggers.o.a(entityplayer, this.animal, this.partner, entityAgeable);
}
this.animal.setAgeRaw(6000);
this.partner.setAgeRaw(6000);
this.animal.resetLove();
this.partner.resetLove();
entityAgeable.setAgeRaw(41536);
entityAgeable.setPositionRotation(this.animal.locX(), this.animal.locY(), this.animal.locZ(), 0.0F, 0.0F);
this.b.addEntity(entityAgeable, CreatureSpawnEvent.SpawnReason.BREEDING);
this.b.broadcastEntityEffect(this.animal, (byte) 18);
EntityTamableFox tamableFoxBaby = (EntityTamableFox) entityAgeable;
tamableFoxBaby.setTamed(Boolean.TRUE);
tamableFoxBaby.setOwner(entityplayer);
animal.getPlugin().getFoxUUIDs().replace(tamableFoxBaby.getUniqueID(), null, entityplayer.getUniqueID());
if ((this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) && (experience > 0)) {
this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience));
}
}
}
}

View File

@ -1,55 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.PathfinderGoalFleeSun;
import net.minecraft.server.v1_15_R1.WorldServer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class FoxPathfindGoalFleeSun extends PathfinderGoalFleeSun {
protected EntityTamableFox tamableFox;
private int c = 100;
public FoxPathfindGoalFleeSun(EntityTamableFox tamableFox, double d0) {
super(tamableFox, d0);
this.tamableFox = tamableFox;
}
public boolean a() {
if (this.tamableFox.isTamed()) {
return false;
} else if (!this.tamableFox.isSleeping() && this.a.getGoalTarget() == null) {
if (this.tamableFox.world.U()) {
return true;
} else if (this.c > 0) {
--this.c;
return false;
} else {
this.c = 100;
BlockPosition blockposition = new BlockPosition(this.a);
return this.tamableFox.world.isDay() && this.tamableFox.world.f(blockposition) && !((WorldServer) this.tamableFox.world).b_(blockposition)
&& this.g();
}
} else {
return false;
}
}
public void c() {
try {
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
Method method = entityFoxClass.getDeclaredMethod("eH");
method.setAccessible(true);
method.invoke(this.tamableFox);
method.setAccessible(false);
} catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException var3) {
var3.printStackTrace();
}
super.c();
}
}

View File

@ -1,34 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.PathfinderGoalFloat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class FoxPathfindGoalFloat extends PathfinderGoalFloat {
protected EntityTamableFox tamableFox;
public FoxPathfindGoalFloat(EntityTamableFox tamableFox) {
super(tamableFox);
this.tamableFox = tamableFox;
}
public void c() {
try {
super.c();
Method method = this.tamableFox.getClass().getSuperclass().getDeclaredMethod("eH");
method.setAccessible(true);
method.invoke(this.tamableFox);
method.setAccessible(false);
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
}
public boolean a() {
return this.tamableFox.isInWater() && this.tamableFox.co() > 0.25D || this.tamableFox.aH();
}
}

View File

@ -1,105 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.*;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.event.entity.EntityTeleportEvent;
import java.util.EnumSet;
public class FoxPathfindGoalFollowOwner extends PathfinderGoal {
protected final EntityTamableFox a;
protected final IWorldReader b;
private final double d;
private final NavigationAbstract e;
private final float g;
private final float h;
private EntityLiving c;
private int f;
private float i;
public FoxPathfindGoalFollowOwner(EntityTamableFox tamableFox, double d0, float f, float f1) {
this.a = tamableFox;
this.b = tamableFox.world;
this.d = d0;
this.e = tamableFox.getNavigation();
this.h = f;
this.g = f1;
this.a(EnumSet.of(Type.MOVE, Type.LOOK));
if (!(tamableFox.getNavigation() instanceof Navigation) && !(tamableFox.getNavigation() instanceof NavigationFlying)) {
throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
}
}
public boolean a() {
EntityLiving entityliving = this.a.getOwner();
if (entityliving == null) {
return false;
} else if (entityliving instanceof EntityHuman && entityliving.isSpectator()) {
return false;
} else if (this.a.isSitting()) {
return false;
} else if (this.a.h(entityliving) < (double) (this.h * this.h)) {
return false;
} else {
this.c = entityliving;
return true;
}
}
public boolean b() {
return !this.e.n() && this.a.h(this.c) > (double) (this.g * this.g) && !this.a.isSitting();
}
public void c() {
this.f = 0;
this.i = this.a.a(PathType.WATER);
this.a.a(PathType.WATER, 0.0F);
}
public void d() {
this.c = null;
this.e.o();
this.a.a(PathType.WATER, this.i);
}
public void e() {
this.a.getControllerLook().a(this.c, 10.0F, (float) this.a.dU());
if (!this.a.isSitting() && --this.f <= 0) {
this.f = 10;
if (!this.e.a(this.c, this.d) && !this.a.isLeashed() && !this.a.isPassenger() && this.a.h(this.c) >= 144.0D) {
int i = MathHelper.floor(this.c.locX()) - 2;
int j = MathHelper.floor(this.c.locZ()) - 2;
int k = MathHelper.floor(this.c.getBoundingBox().minY);
for (int l = 0; l <= 4; ++l) {
for (int i1 = 0; i1 <= 4; ++i1) {
if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.a(new BlockPosition(i + l, k - 1, j + i1))) {
CraftEntity entity = this.a.getBukkitEntity();
Location to = new Location(entity.getWorld(), (double) ((float) (i + l) + 0.5F), k, ((float) (j + i1) + 0.5F), this.a.yaw, this.a.pitch);
EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to);
this.a.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
to = event.getTo();
this.a.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
this.e.o();
return;
}
}
}
}
}
}
protected boolean a(BlockPosition blockposition) {
IBlockData iblockdata = this.b.getType(blockposition);
return iblockdata.a(this.b, blockposition, this.a.getEntityType()) && this.b.isEmpty(blockposition.up()) && this.b.isEmpty(blockposition.up(2));
}
}

View File

@ -1,125 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class FoxPathfindGoalLunge extends PathfinderGoalWaterJumpAbstract {
protected EntityTamableFox tamableFox;
public FoxPathfindGoalLunge(EntityTamableFox tamableFox) {
this.tamableFox = tamableFox;
}
public boolean a() {
if (!this.tamableFox.ez()) {
return false;
} else {
EntityLiving entityliving = this.tamableFox.getGoalTarget();
if (entityliving != null && entityliving.isAlive()) {
if (entityliving.getAdjustedDirection() != entityliving.getDirection()) {
return false;
} else {
boolean flag = EntityFox.a(this.tamableFox, entityliving);
if (!flag) {
this.tamableFox.getNavigation().a(entityliving, 0);
this.tamableFox.setCrouching(false);
this.tamableFox.u(false);
}
return flag;
}
} else {
return false;
}
}
}
public boolean b() {
EntityLiving entityliving = this.tamableFox.getGoalTarget();
if (entityliving != null && entityliving.isAlive()) {
double d0 = this.tamableFox.getMot().y;
return (d0 * d0 >= 0.05000000074505806D || Math.abs(this.tamableFox.pitch) >= 15.0F || !this.tamableFox.onGround) && !this.tamableFox.es();
} else {
return false;
}
}
public boolean E_() {
return false;
}
public void c() {
this.tamableFox.setJumping(true);
this.tamableFox.s(true);
this.tamableFox.u(false);
EntityLiving entityliving = this.tamableFox.getGoalTarget();
this.tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
Vec3D vec3d = (new Vec3D(entityliving.locX() - this.tamableFox.locX(),
entityliving.locY() - this.tamableFox.locY(), entityliving.locZ() - this.tamableFox.locZ())).d();
this.tamableFox.setMot(this.tamableFox.getMot().add(vec3d.x * 0.8D, 0.9D, vec3d.z * 0.8D));
this.tamableFox.getNavigation().o();
}
public void d() {
this.tamableFox.setCrouching(false);
try {
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
Field field = entityFoxClass.getDeclaredField("bK");
field.setAccessible(true);
field.set(this.tamableFox, 0.0F);
field.setAccessible(false);
field = entityFoxClass.getDeclaredField("bL");
field.setAccessible(true);
field.set(this.tamableFox, 0);
field.setAccessible(false);
} catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException var3) {
var3.printStackTrace();
}
this.tamableFox.u(false);
this.tamableFox.s(false);
}
public void e() {
EntityLiving entityliving = this.tamableFox.getGoalTarget();
if (entityliving != null) {
this.tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
}
if (!this.tamableFox.es()) {
Vec3D vec3d = this.tamableFox.getMot();
if (vec3d.y * vec3d.y < 0.029999999329447746D && this.tamableFox.pitch != 0.0F) {
this.tamableFox.pitch = MathHelper.j(this.tamableFox.pitch, 0.0F, 0.2F);
} else {
double d0 = Math.sqrt(Entity.b(vec3d));
double d1 = Math.signum(-vec3d.y) * Math.acos(d0 / vec3d.f()) * 57.2957763671875D;
this.tamableFox.pitch = (float) d1;
}
}
if (entityliving != null && this.tamableFox.g(entityliving) <= 2.0F) {
this.tamableFox.B(entityliving);
} else if (this.tamableFox.pitch > 0.0F && this.tamableFox.onGround && (float) this.tamableFox.getMot().y != 0.0F && this.tamableFox.world.getType(new BlockPosition(this.tamableFox)).getBlock() == Blocks.SNOW) {
this.tamableFox.pitch = 60.0F;
this.tamableFox.setGoalTarget(null);
try {
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
Method method = entityFoxClass.getDeclaredMethod("v", Boolean.TYPE);
method.setAccessible(true);
method.invoke(this.tamableFox, true);
method.setAccessible(false);
} catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException var7) {
var7.printStackTrace();
}
}
}
}

View File

@ -1,85 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.EntityFox;
import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.PathfinderGoal;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.EnumSet;
import java.util.function.Predicate;
public class FoxPathfindGoalLungeUNKNOWN_USE extends PathfinderGoal {
protected EntityTamableFox tamableFox;
public FoxPathfindGoalLungeUNKNOWN_USE(EntityTamableFox tamableFox) {
this.a(EnumSet.of(Type.MOVE, Type.LOOK));
this.tamableFox = tamableFox;
}
public boolean a() {
if (this.tamableFox.isSleeping()) {
return false;
} else {
EntityLiving entityliving = this.tamableFox.getGoalTarget();
try {
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
Field field = entityFoxClass.getDeclaredField("bD");
field.setAccessible(true);
Predicate<Entity> bG = (Predicate<Entity>) field.get(this.tamableFox);
field.setAccessible(false);
return entityliving != null && entityliving.isAlive() && bG.test(entityliving) && this.tamableFox.h(entityliving) > 36.0D
&& !this.tamableFox.isCrouching() && !this.tamableFox.eg() && !this.tamableFox.isJumping();
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException var5) {
var5.printStackTrace();
throw new NullPointerException();
}
}
}
public void c() {
this.tamableFox.setSitting(false);
try {
Method method = this.tamableFox.getClass().getSuperclass().getDeclaredMethod("v", Boolean.TYPE);
method.setAccessible(true);
method.invoke(this.tamableFox, false);
method.setAccessible(false);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException var2) {
var2.printStackTrace();
}
}
public void d() {
EntityLiving entityliving = this.tamableFox.getGoalTarget();
if (entityliving != null && EntityFox.a(this.tamableFox, entityliving)) {
this.tamableFox.u(true);
this.tamableFox.setCrouching(true);
this.tamableFox.getNavigation().o();
this.tamableFox.getControllerLook().a(entityliving, (float) this.tamableFox.dV(), (float) this.tamableFox.dU());
} else {
this.tamableFox.u(false);
this.tamableFox.setCrouching(false);
}
}
public void e() {
EntityLiving entityliving = this.tamableFox.getGoalTarget();
this.tamableFox.getControllerLook().a(entityliving, (float) this.tamableFox.dV(), (float) this.tamableFox.dU());
if (this.tamableFox.h(entityliving) <= 36.0D) {
this.tamableFox.u(true);
this.tamableFox.setCrouching(true);
this.tamableFox.getNavigation().o();
} else {
this.tamableFox.getNavigation().a(entityliving, 1.5D);
}
}
}

View File

@ -1,47 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.PathfinderGoalTarget;
import net.minecraft.server.v1_15_R1.PathfinderTargetCondition;
import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
import java.util.EnumSet;
public class FoxPathfindGoalOwnerHurtTarget extends PathfinderGoalTarget {
private final EntityTamableFox a;
private EntityLiving b;
private int c;
public FoxPathfindGoalOwnerHurtTarget(EntityTamableFox tamableFox) {
super(tamableFox, false);
this.a = tamableFox;
this.a(EnumSet.of(Type.TARGET));
}
public boolean a() {
if (this.a.isTamed() && !this.a.isSitting()) {
EntityLiving entityliving = this.a.getOwner();
if (entityliving == null) {
return false;
} else {
this.b = entityliving.cJ();
int i = entityliving.cK();
return i != this.c && this.a(this.b, PathfinderTargetCondition.a);
}
} else {
return false;
}
}
public void c() {
this.e.setGoalTarget(this.b, TargetReason.OWNER_ATTACKED_TARGET, true);
EntityLiving entityliving = this.a.getOwner();
if (entityliving != null) {
this.c = entityliving.cK();
}
super.c();
}
}

View File

@ -1,85 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.*;
import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
public class FoxPathfindGoalPickBushes extends PathfinderGoalGotoTarget {
protected int g;
protected EntityTamableFox tamableFox;
public FoxPathfindGoalPickBushes(EntityTamableFox tamableFox, double d0, int i, int j) {
super(tamableFox, d0, i, j);
this.tamableFox = tamableFox;
}
public double h() {
return 2.0D;
}
public boolean j() {
return this.d % 100 == 0;
}
protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) {
if (this.tamableFox.isTamed()) {
return false;
} else {
IBlockData iblockdata = iworldreader.getType(blockposition);
return iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH && (Integer) iblockdata.get(BlockSweetBerryBush.a) >= 2;
}
}
public void e() {
if (this.k()) {
if (this.g >= 40) {
this.m();
} else {
++this.g;
}
} else if (!this.k() && this.tamableFox.getRandom().nextFloat() < 0.05F && !this.tamableFox.isTamed()) {
this.tamableFox.a(SoundEffects.ENTITY_FOX_SNIFF, 1.0F, 1.0F);
}
super.e();
}
protected void m() {
if (this.tamableFox.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT) && !this.tamableFox.isTamed()) {
IBlockData iblockdata = this.tamableFox.world.getType(this.e);
if (iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH) {
int i = (Integer) iblockdata.get(BlockSweetBerryBush.a);
iblockdata.set(BlockSweetBerryBush.a, 1);
if (CraftEventFactory.callEntityChangeBlockEvent(this.tamableFox, this.e, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, 1)).isCancelled()) {
return;
}
int j = 1 + this.tamableFox.world.random.nextInt(2) + (i == 3 ? 1 : 0);
ItemStack itemstack = this.tamableFox.getEquipment(EnumItemSlot.MAINHAND);
if (itemstack.isEmpty()) {
this.tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.SWEET_BERRIES));
--j;
}
if (j > 0) {
Block.a(this.tamableFox.world, this.e, new ItemStack(Items.SWEET_BERRIES, j));
}
this.tamableFox.a(SoundEffects.ITEM_SWEET_BERRIES_PICK_FROM_BUSH, 1.0F, 1.0F);
this.tamableFox.world.setTypeAndData(this.e, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, 1), 2);
}
}
}
public boolean a() {
return !this.tamableFox.isSleeping() && super.a();
}
public void c() {
this.g = 0;
this.tamableFox.setSitting(false);
super.c();
}
}

View File

@ -1,98 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.PathfinderGoalRandomStroll;
import net.minecraft.server.v1_15_R1.RandomPositionGenerator;
import net.minecraft.server.v1_15_R1.Vec3D;
import javax.annotation.Nullable;
public class FoxPathfindGoalRandomStrollLand extends PathfinderGoalRandomStroll {
protected final float h;
protected EntityTamableFox tamableFox;
protected Vec3D vec3D;
public FoxPathfindGoalRandomStrollLand(EntityTamableFox var0, double var1) {
this(var0, var1, 0.001F);
this.tamableFox = var0;
}
public FoxPathfindGoalRandomStrollLand(EntityTamableFox var0, double var1, float var3) {
super(var0, var1);
this.h = var3;
this.tamableFox = var0;
}
public boolean a() {
if (this.a.isVehicle()) {
return false;
} else {
if (!this.g) {
if (this.a.cL() >= 100) {
return false;
}
if (this.a.getRandom().nextInt(this.f) != 0) {
return false;
}
}
if (!this.tamableFox.isSitting()) {
this.vec3D = this.g();
}
if (this.vec3D == null) {
return false;
} else {
this.b = this.vec3D.x;
this.c = this.vec3D.y;
this.d = this.vec3D.z;
this.g = false;
return true;
}
}
}
@Nullable
protected Vec3D g() {
if (this.a.az()) {
Vec3D var0 = RandomPositionGenerator.b(this.a, 15, 7);
return var0 == null ? super.g() : var0;
} else {
return this.a.getRandom().nextFloat() >= this.h ? RandomPositionGenerator.b(this.a, 10, 7) : super.g();
}
}
public boolean b() {
return !this.a.getNavigation().n();
}
public void c() {
this.a.getNavigation().a(this.b, this.c, this.d, this.e);
}
public void h() {
this.g = true;
}
public void setTimeBetweenMovement(int var0) {
this.f = var0;
}
public void e() {
if (this.tamableFox.isSitting()) {
this.vec3D = null;
}
}
public boolean E_() {
if (this.tamableFox.isSitting()) {
this.vec3D = null;
return false;
} else {
return true;
}
}
}

View File

@ -1,27 +0,0 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.PathfinderGoalNearestAttackableTarget;
import javax.annotation.Nullable;
import java.util.function.Predicate;
public class FoxPathfindGoalRandomTargetNonTamed<T extends EntityLiving> extends PathfinderGoalNearestAttackableTarget<T> {
private final EntityTamableFox tamableFox;
public FoxPathfindGoalRandomTargetNonTamed(EntityTamableFox tamableFox, Class<T> var1, boolean var2, @Nullable Predicate<EntityLiving> var3) {
super(tamableFox, var1, 10, var2, false, var3);
this.tamableFox = tamableFox;
}
public boolean a() {
return !this.tamableFox.isTamed() && super.a();
}
public boolean b() {
return this.d != null ? this.d.a(this.e, this.c) : super.b();
}
}

View File

@ -0,0 +1,139 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.*;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.event.entity.EntityTeleportEvent;
import java.util.EnumSet;
public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
private final EntityTamableFox a;
private EntityLiving b;
private final IWorldReader c;
private final double d;
private final NavigationAbstract e;
private int f;
private final float g;
private final float h;
private float i;
private final boolean j;
public FoxPathfinderGoalFollowOwner(EntityTamableFox entityTamableFox, double d0, float f, float f1, boolean flag) {
this.a = entityTamableFox;
this.c = entityTamableFox.world;
this.d = d0;
this.e = entityTamableFox.getNavigation();
this.h = f;
this.g = f1;
this.j = flag;
this.a(EnumSet.of(Type.MOVE, Type.LOOK));
if (!(entityTamableFox.getNavigation() instanceof Navigation) && !(entityTamableFox.getNavigation() instanceof NavigationFlying)) {
throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
}
}
public boolean a() {
EntityLiving entityliving = this.a.getOwner();
if (entityliving == null) {
return false;
} else if (entityliving.isSpectator()) {
return false;
} else if (this.a.isSitting()) {
return false;
} else if (this.a.h(entityliving) < (double)(this.h * this.h)) {
return false;
} else {
this.b = entityliving;
return true;
}
}
public boolean b() {
return this.e.m() ? false : (this.a.isSitting() ? false : this.a.h(this.b) > (double)(this.g * this.g));
}
public void c() {
this.f = 0;
this.i = this.a.a(PathType.WATER);
this.a.a(PathType.WATER, 0.0F);
}
public void d() {
this.b = null;
this.e.o();
this.a.a(PathType.WATER, this.i);
}
public void e() {
this.a.getControllerLook().a(this.b, 10.0F, (float)this.a.dU());
if (--this.f <= 0) {
this.f = 10;
if (!this.a.isLeashed() && !this.a.isPassenger()) {
if (this.a.h(this.b) >= 144.0D) {
this.g();
} else {
this.e.a(this.b, this.d);
}
}
}
}
private void g() {
BlockPosition blockposition = new BlockPosition(this.b);
for(int i = 0; i < 10; ++i) {
int j = this.a(-3, 3);
int k = this.a(-1, 1);
int l = this.a(-3, 3);
boolean flag = this.a(blockposition.getX() + j, blockposition.getY() + k, blockposition.getZ() + l);
if (flag) {
return;
}
}
}
private boolean a(int i, int j, int k) {
if (Math.abs((double)i - this.b.locX()) < 2.0D && Math.abs((double)k - this.b.locZ()) < 2.0D) {
return false;
} else if (!this.a(new BlockPosition(i, j, k))) {
return false;
} else {
CraftEntity entity = this.a.getBukkitEntity();
Location to = new Location(entity.getWorld(), (double)((float)i + 0.5F), (double)j, (double)((float)k + 0.5F), this.a.yaw, this.a.pitch);
EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to);
this.a.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
} else {
to = event.getTo();
this.a.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
this.e.o();
return true;
}
}
}
private boolean a(BlockPosition blockposition) {
PathType pathtype = PathfinderNormal.b(this.c, blockposition.getX(), blockposition.getY(), blockposition.getZ());
if (pathtype != PathType.WALKABLE) {
return false;
} else {
IBlockData iblockdata = this.c.getType(blockposition.down());
if (!this.j && iblockdata.getBlock() instanceof BlockLeaves) {
return false;
} else {
BlockPosition blockposition1 = blockposition.b(new BlockPosition(this.a));
return this.c.getCubes(this.a, this.a.getBoundingBox().a(blockposition1));
}
}
}
private int a(int i, int j) {
return this.a.getRandom().nextInt(j - i + 1) + i;
}
}

View File

@ -8,7 +8,7 @@ import java.util.EnumSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget { public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).c().e(); private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).c().e();
private final Class<?>[] d; private final Class<?>[] d;
@ -16,7 +16,7 @@ public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget {
private int c; private int c;
private Class<?>[] i; private Class<?>[] i;
public FoxPathfindGoalHurtByTarget(EntityTamableFox entitycreature, Class<?>... aclass) { public FoxPathfinderGoalHurtByTarget(EntityTamableFox entitycreature, Class<?>... aclass) {
super(entitycreature, true); super(entitycreature, true);
this.d = aclass; this.d = aclass;
this.a(EnumSet.of(Type.TARGET)); this.a(EnumSet.of(Type.TARGET));
@ -41,7 +41,7 @@ public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget {
} }
} }
public FoxPathfindGoalHurtByTarget a(Class<?>... aclass) { public FoxPathfinderGoalHurtByTarget a(Class<?>... aclass) {
this.b = true; this.b = true;
this.i = aclass; this.i = aclass;
return this; return this;

View File

@ -1,36 +1,38 @@
package net.seanomik.tamablefoxes.pathfinding; package net.seanomik.tamablefoxes.pathfinding;
import net.seanomik.tamablefoxes.EntityTamableFox; import net.minecraft.server.v1_15_R1.EntityFox;
import net.minecraft.server.v1_15_R1.EntityLiving; import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.PathfinderGoalMeleeAttack; import net.minecraft.server.v1_15_R1.PathfinderGoalMeleeAttack;
import net.minecraft.server.v1_15_R1.SoundEffects; import net.minecraft.server.v1_15_R1.SoundEffects;
import net.seanomik.tamablefoxes.EntityTamableFox;
public class FoxPathfindGoalMeleeAttack extends PathfinderGoalMeleeAttack { public class FoxPathfinderGoalMeleeAttack extends PathfinderGoalMeleeAttack {
EntityTamableFox tamableFox;
EntityLiving enemy;
protected EntityTamableFox tamableFox; public FoxPathfinderGoalMeleeAttack(EntityTamableFox tamableFox, double d0, boolean flag) {
public FoxPathfindGoalMeleeAttack(EntityTamableFox tamableFox, double d0, boolean flag) {
super(tamableFox, d0, flag); super(tamableFox, d0, flag);
this.tamableFox = tamableFox; this.tamableFox = tamableFox;
} }
protected void a(EntityLiving entityliving, double d0) { protected void a(EntityLiving entityliving, double d0) {
double d1 = this.a(entityliving); double d1 = this.a(entityliving);
this.enemy = entityliving;
if (d0 <= d1 && this.b <= 0) { if (d0 <= d1 && this.b <= 0) {
this.b = 20; this.b = 20;
this.a.B(entityliving); this.a.B(entityliving);
this.tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F); tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F);
} }
} }
public void c() { public void c() {
this.tamableFox.u(false); tamableFox.u(false);
super.c(); super.c();
} }
public boolean a() { public boolean a() {
return !this.tamableFox.isSitting() && !this.tamableFox.isSleeping() && !this.tamableFox.isCrouching() && !this.tamableFox.es() && super.a(); return !tamableFox.isSitting() && !tamableFox.isSleeping() && !tamableFox.isCrouching() && !tamableFox.es() && !tamableFox.isOtherFoxFamily(enemy) && super.a();
} }
} }

View File

@ -8,13 +8,13 @@ import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
import java.util.EnumSet; import java.util.EnumSet;
public class FoxPathfindGoalOwnerHurtByTarget extends PathfinderGoalTarget { public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget {
private final EntityTamableFox a; private final EntityTamableFox a;
private EntityLiving b; private EntityLiving b;
private int c; private int c;
public FoxPathfindGoalOwnerHurtByTarget(EntityTamableFox tamableFox) { public FoxPathfinderGoalOwnerHurtByTarget(EntityTamableFox tamableFox) {
super(tamableFox, false); super(tamableFox, false);
this.a = tamableFox; this.a = tamableFox;
this.a(EnumSet.of(Type.TARGET)); this.a(EnumSet.of(Type.TARGET));
@ -28,7 +28,7 @@ public class FoxPathfindGoalOwnerHurtByTarget 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); return i != this.c && this.a(this.b, PathfinderTargetCondition.a); //&& this.a.a(this.b, entityliving); // Returns true in any condition
} }
} else { } else {
return false; return false;

View File

@ -0,0 +1,57 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.minecraft.server.v1_15_R1.EntityTameableAnimal;
import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.PathfinderGoalTarget;
import net.minecraft.server.v1_15_R1.PathfinderTargetCondition;
import net.seanomik.tamablefoxes.Utils;
import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
import javax.rmi.CORBA.Util;
import java.util.EnumSet;
public class FoxPathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget {
private final EntityTamableFox fox;
private EntityLiving hitEntity;
private int c;
public FoxPathfinderGoalOwnerHurtTarget(EntityTamableFox entityTamableFox) {
super(entityTamableFox, false);
this.fox = entityTamableFox;
this.a(EnumSet.of(Type.TARGET));
}
public boolean a() {
if (fox.isTamed() && !fox.isSitting()) {
EntityLiving entityliving = fox.getOwner();
if (entityliving == null) {
e.setGoalTarget(null);
return false;
} else if (fox.isOtherFoxFamily(hitEntity)) {
e.setGoalTarget(null);
return false;
} else {
hitEntity = entityliving.cJ();
int i = entityliving.cK();
return i != this.c && this.a(hitEntity, PathfinderTargetCondition.a);// && fox.a.a(hitEntity, entityliving); // Just returns true in any case
}
} else {
return false;
}
}
public void c() {
if (!fox.isOtherFoxFamily(hitEntity)) {
this.e.setGoalTarget(hitEntity, TargetReason.OWNER_ATTACKED_TARGET, true);
EntityLiving entityliving = fox.getOwner();
if (entityliving != null) {
this.c = entityliving.cK();
}
super.c();
} else {
e.setGoalTarget(null);
}
}
}

View File

@ -0,0 +1,30 @@
package net.seanomik.tamablefoxes.pathfinding;
import net.minecraft.server.v1_15_R1.EntityFox;
import net.minecraft.server.v1_15_R1.PathfinderGoalPanic;
import net.seanomik.tamablefoxes.EntityTamableFox;
import java.lang.reflect.Method;
public class FoxPathfinderGoalPanic extends PathfinderGoalPanic {
EntityTamableFox tamableFox;
public FoxPathfinderGoalPanic(EntityTamableFox tamableFox, double d0) {
super(tamableFox, d0);
this.tamableFox = tamableFox;
}
public boolean a() {
try {
Method eFMethod = EntityFox.class.getDeclaredMethod("eF");
eFMethod.setAccessible(true);
boolean eF = (boolean) eFMethod.invoke(tamableFox);
eFMethod.setAccessible(false);
return !tamableFox.isTamed() && !eF && super.a();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -6,12 +6,12 @@ import net.minecraft.server.v1_15_R1.PathfinderGoal;
import java.util.EnumSet; import java.util.EnumSet;
public class FoxPathfindGoalSit extends PathfinderGoal { public class FoxPathfinderGoalSit extends PathfinderGoal {
private final EntityTamableFox entity; private final EntityTamableFox entity;
private boolean willSit; private boolean willSit;
public FoxPathfindGoalSit(EntityTamableFox tamableFox) { public FoxPathfinderGoalSit(EntityTamableFox tamableFox) {
this.entity = tamableFox; this.entity = tamableFox;
this.a(EnumSet.of(Type.JUMP, Type.MOVE)); this.a(EnumSet.of(Type.JUMP, Type.MOVE));
} }

View File

@ -1,16 +1,21 @@
package net.seanomik.tamablefoxes.sqlite; package net.seanomik.tamablefoxes.sqlite;
import net.minecraft.server.v1_15_R1.EntityFox; import net.minecraft.server.v1_15_R1.EntityFox;
import net.minecraft.server.v1_15_R1.EntityLiving;
import net.minecraft.server.v1_15_R1.EnumItemSlot; import net.minecraft.server.v1_15_R1.EnumItemSlot;
import net.seanomik.tamablefoxes.EntityTamableFox; import net.seanomik.tamablefoxes.EntityTamableFox;
import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.TamableFoxes;
import net.seanomik.tamablefoxes.Utils;
import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.ObjectUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
@ -25,19 +30,15 @@ public class SQLiteSetterGetter {
public void createTablesIfNotExist() { public void createTablesIfNotExist() {
plugin = TamableFoxes.getPlugin(TamableFoxes.class); plugin = TamableFoxes.getPlugin(TamableFoxes.class);
sqLiteHandler = TamableFoxes.sqLiteHandler; sqLiteHandler = plugin.sqLiteHandler;
//String pluginDatabase = Reference.SQLiteDatabase;
String foxesTable = String foxesTable =
"CREATE TABLE IF NOT EXISTS `foxes` ( " + "CREATE TABLE IF NOT EXISTS `foxes` ( " +
"`ID` INTEGER PRIMARY KEY AUTOINCREMENT , " + "`ENTITY_UUID` TEXT PRIMARY KEY , " +
"`OWNER_UUID` TEXT NOT NULL , " + "`OWNER_UUID` TEXT NOT NULL , " +
"`NAME` TEXT , " + "`NAME` TEXT, " +
"`LOCATION` TEXT NOT NULL , " +
"`TYPE` TEXT NOT NULL , " +
"`SITTING` INTEGER NOT NULL , " + "`SITTING` INTEGER NOT NULL , " +
"`SLEEPING` INTEGER NOT NULL , " + "`SLEEPING` INTEGER NOT NULL);";
"`MOUTH_ITEM` TEXT NOT NULL);";
try { try {
sqLiteHandler.connect(); sqLiteHandler.connect();
@ -48,7 +49,7 @@ public class SQLiteSetterGetter {
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(foxesTable); PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(foxesTable);
statement.executeUpdate(); statement.executeUpdate();
plugin.getServer().getConsoleSender().sendMessage(TamableFoxes.getPrefix() + "Created foxes table!"); plugin.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + "Created foxes table!");
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
@ -65,27 +66,37 @@ public class SQLiteSetterGetter {
public void saveFox(EntityTamableFox fox) { public void saveFox(EntityTamableFox fox) {
plugin = TamableFoxes.getPlugin(TamableFoxes.class); plugin = TamableFoxes.getPlugin(TamableFoxes.class);
// If the fox is null or not alive, delete it from the database
if (fox == null || !fox.isAlive()) {
removeFox(fox);
return;
}
try { try {
sqLiteHandler.connect(); sqLiteHandler.connect();
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("INSERT INTO foxes (OWNER_UUID,NAME,LOCATION,TYPE,MOUTH_ITEM,SITTING,SLEEPING) VALUES (?,?,?,?,?,?,?)"); PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("INSERT INTO foxes (ENTITY_UUID,OWNER_UUID,NAME,SITTING,SLEEPING) VALUES (?,?,?,?,?)");
if (fox.databaseID != -1) {
statement = sqLiteHandler.getConnection().prepareStatement("UPDATE foxes SET OWNER_UUID=?, NAME=?, LOCATION=?, TYPE=?, MOUTH_ITEM=?, SITTING=?, SLEEPING=? WHERE ID=" + fox.databaseID); // If the database does contain this fox, then change the statement to an update statement instead of insert.
PreparedStatement hasFoxStatement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes WHERE ENTITY_UUID=?");
hasFoxStatement.setString(1, fox.getUniqueID().toString());
ResultSet results = hasFoxStatement.executeQuery();
if (results.next()) {
statement = sqLiteHandler.getConnection().prepareStatement("UPDATE foxes SET OWNER_UUID=?, NAME=?, SITTING=?, SLEEPING=? WHERE ENTITY_UUID='" + fox.getUniqueID().toString() + "'");
statement.setString(1, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString());
statement.setString(2, fox.getChosenName());
statement.setInt(3, (fox.isSitting()) ? 1 : 0);
statement.setInt(4, (fox.isSleeping()) ? 1 : 0);
} else {
statement.setString(1, fox.getUniqueID().toString());
statement.setString(2, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString());
statement.setString(3, fox.getChosenName());
statement.setInt(4, (fox.isSitting()) ? 1 : 0);
statement.setInt(5, (fox.isSleeping()) ? 1 : 0);
} }
statement.setString(1, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString());
statement.setString(2, fox.getChosenName());
statement.setString(3, fox.getWorld().worldData.getName() + "," + fox.locX() + "," + fox.locY() + "," + fox.locZ());
statement.setString(4, fox.getFoxType().toString());
statement.setString(5, fox.getEquipment(EnumItemSlot.MAINHAND).toString().toUpperCase().substring(fox.getEquipment(EnumItemSlot.MAINHAND).toString().indexOf(' ')+1));
statement.setInt(6, (fox.isSitting()) ? 1 : 0);
statement.setInt(7, (fox.isSleeping()) ? 1 : 0);
statement.executeUpdate(); statement.executeUpdate();
ResultSet result = statement.getGeneratedKeys();
while (result.next()) {
fox.databaseID = result.getInt(1);
}
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
@ -99,48 +110,59 @@ public class SQLiteSetterGetter {
} }
} }
public void saveFoxes(List<EntityTamableFox> foxes) { // @TODO: Optimize public void saveFoxes(List<EntityTamableFox> foxes) { // @TODO: Optimize?
if (foxes == null || foxes.size() == 0) return;
for (EntityTamableFox fox : foxes) { for (EntityTamableFox fox : foxes) {
saveFox(fox); saveFox(fox);
} }
} }
public List<EntityTamableFox> spawnFoxes() { public List<EntityTamableFox> loadFoxes() {
plugin = TamableFoxes.getPlugin(TamableFoxes.class); plugin = TamableFoxes.getPlugin(TamableFoxes.class);
List<UUID> toRemoveLater = new ArrayList<>();
try { try {
sqLiteHandler.connect(); sqLiteHandler.connect();
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes"); PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes");
ResultSet results = statement.executeQuery(); ResultSet results = statement.executeQuery();
List<EntityTamableFox> foxList = new ArrayList<>(); List<EntityTamableFox> spawnedFoxes = new ArrayList<>();
while (results.next()) { // Loop through each row while (results.next()) { // Loop through each row
List<String> locationList = Arrays.asList(results.getString("LOCATION").split("\\s*,\\s*")); UUID entityUUID = UUID.fromString(results.getString("ENTITY_UUID"));
Location loc = new Location(Bukkit.getWorld(locationList.get(0)), Double.parseDouble(locationList.get(1)), Double.parseDouble(locationList.get(2)), Double.parseDouble(locationList.get(3))); String ownerUUIDString = results.getString("OWNER_UUID");
String name = results.getString("NAME");
boolean sitting = results.getInt("SITTING") == 1;
boolean sleeping = results.getInt("SLEEPING") == 1;
EntityTamableFox spawnedFox = (EntityTamableFox) plugin.spawnTamableFox(loc, EntityFox.Type.valueOf(results.getString("TYPE"))); // If the entity is null, it doesn't exist anymore so remove it from database
spawnedFox.databaseID = results.getInt("ID"); if (plugin.getServer().getEntity(entityUUID) == null) {
spawnedFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(Material.valueOf(results.getString("MOUTH_ITEM")), 1))); toRemoveLater.add(entityUUID);
continue;
spawnedFox.setSitting(results.getInt("SITTING") == 1); }
spawnedFox.setSleeping(results.getInt("SLEEPING") == 1); EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) plugin.getServer().getEntity(entityUUID)).getHandle();
if (!ownerUUIDString.equals("none")) {
if (!results.getString("OWNER_UUID").equals("none")) { OfflinePlayer owner = plugin.getServer().getOfflinePlayer(UUID.fromString(ownerUUIDString));
UUID ownerUUID = UUID.fromString(results.getString("OWNER_UUID"));
OfflinePlayer owner = plugin.getServer().getOfflinePlayer(ownerUUID);
if (owner.isOnline()) { if (owner.isOnline()) {
spawnedFox.setOwner(((CraftPlayer) owner.getPlayer()).getHandle()); EntityLiving livingOwner = (EntityLiving) ((CraftEntity) owner).getHandle();
tamableFox.setOwner(livingOwner);
} }
plugin.getFoxUUIDs().put(spawnedFox.getUniqueID(), ownerUUID); tamableFox.setOwnerUUID(owner.getUniqueId());
spawnedFox.setChosenName(results.getString("NAME")); tamableFox.setTamed(true);
spawnedFox.setTamed(true); tamableFox.setChosenName(name);
} }
foxList.add(spawnedFox); // Fox may spawn standing if the server was closed while it was sitting.
if (sitting) {
tamableFox.setHardSitting(true);
} else if (sleeping) {
tamableFox.setSleeping(true);
}
spawnedFoxes.add(tamableFox);
} }
return foxList; return spawnedFoxes;
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
@ -151,16 +173,21 @@ public class SQLiteSetterGetter {
e.printStackTrace(); e.printStackTrace();
} }
} }
// Remove those to remove later UUIDs
for (UUID uuid : toRemoveLater) {
removeFox(uuid);
}
} }
return null; return null;
} }
public void removeFox(int databaseID) { public void removeFox(UUID uuid) {
plugin = TamableFoxes.getPlugin(TamableFoxes.class); plugin = TamableFoxes.getPlugin(TamableFoxes.class);
try { try {
sqLiteHandler.connect(); sqLiteHandler.connect();
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("DELETE FROM foxes WHERE ID=" + databaseID); PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("DELETE FROM foxes WHERE ENTITY_UUID='" + uuid.toString() + "'");
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
@ -176,6 +203,6 @@ public class SQLiteSetterGetter {
} }
public void removeFox(EntityTamableFox fox) { public void removeFox(EntityTamableFox fox) {
removeFox(fox.databaseID); removeFox(fox.getUniqueID());
} }
} }

View File

@ -1,6 +1,7 @@
# Config for Tamable Foxes modified for 1.15.1 # Config for Tamable Foxes
show-owner-in-fox-name: true show-owner-in-fox-name: true
show-nametags: true show-nametags: true
enable-taming-permission: true
tamed-behavior: tamed-behavior:
attack-chicken-rabbit: true attack-wild-animals: true

View File

@ -1,2 +0,0 @@
# Foxes are saved here:
Foxes: {}

View File

@ -1,9 +1,9 @@
name: TamableFoxes name: Tamablefoxes
version: 1.4.1-SNAPSHOT version: ${project.version}
main: net.seanomik.tamablefoxes.TamableFoxes main: net.seanomik.tamablefoxes.TamableFoxes
api-version: 1.15 api-version: 1.15
#load: STARTUP
load: POSTWORLD load: POSTWORLD
description: Modified version of TamableFoxes for 1.15.1.
commands: commands:
spawntamablefox: spawntamablefox:
@ -14,3 +14,6 @@ permissions:
tamablefoxes.spawn: tamablefoxes.spawn:
description: "Gives the player the ability to spawn tamable foxes." description: "Gives the player the ability to spawn tamable foxes."
default: false default: false
tamablefoxes.tame:
description: "Gives the player the ability to tame a fox."
default: false

View File

@ -1,6 +1,7 @@
# Config for Tamable Foxes modified for 1.15.1 # Config for Tamable Foxes
show-owner-in-fox-name: true show-owner-in-fox-name: true
show-nametags: true show-nametags: true
enable-taming-permission: true
tamed-behavior: tamed-behavior:
attack-chicken-rabbit: true attack-wild-animals: true

View File

@ -1,2 +0,0 @@
# Foxes are saved here:
Foxes: {}

View File

@ -1,9 +1,9 @@
name: TamableFoxes name: Tamablefoxes
version: 1.4.1-SNAPSHOT version: 1.5-SNAPSHOT
main: net.seanomik.tamablefoxes.TamableFoxes main: net.seanomik.tamablefoxes.TamableFoxes
api-version: 1.15 api-version: 1.15
#load: STARTUP
load: POSTWORLD load: POSTWORLD
description: Modified version of TamableFoxes for 1.15.1.
commands: commands:
spawntamablefox: spawntamablefox:
@ -14,3 +14,6 @@ permissions:
tamablefoxes.spawn: tamablefoxes.spawn:
description: "Gives the player the ability to spawn tamable foxes." description: "Gives the player the ability to spawn tamable foxes."
default: false default: false
tamablefoxes.tame:
description: "Gives the player the ability to tame a fox."
default: false

View File

@ -1,5 +1,5 @@
#Generated by Maven #Generated by Maven
#Sat Jan 18 14:21:47 CST 2020 #Wed Jan 22 08:36:01 CST 2020
version=1.4.1-SNAPSHOT version=1.5-SNAPSHOT
groupId=net.seanomik groupId=net.seanomik
artifactId=tamableFoxes artifactId=tamablefoxes

View File

@ -1,24 +1,15 @@
net\seanomik\tamablefoxes\EntityTamableFox.class net\seanomik\tamablefoxes\EntityTamableFox.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtByTarget.class net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalOwnerHurtByTarget.class
net\seanomik\tamablefoxes\io\FileManager$Config.class
net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.class net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalSit.class net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalFollowOwner.class
net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.class net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalSit.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBeg.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomStrollLand.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLunge.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFloat.class
net\seanomik\tamablefoxes\TamableFoxes$SaveFoxRunnable.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalMeleeAttack.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomTargetNonTamed.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFleeSun.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtTarget.class
net\seanomik\tamablefoxes\io\FileManager.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBreed.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFollowOwner.class
net\seanomik\tamablefoxes\sqlite\SQLiteHandler.class net\seanomik\tamablefoxes\sqlite\SQLiteHandler.class
net\seanomik\tamablefoxes\TamableFoxes.class net\seanomik\tamablefoxes\TamableFoxes.class
net\seanomik\tamablefoxes\EntityTamableFox$UpdateFoxRunnable.class net\seanomik\tamablefoxes\EntityTamableFox$UpdateFoxRunnable.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLungeUNKNOWN_USE.class net\seanomik\tamablefoxes\Config.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalPickBushes.class net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalHurtByTarget.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalHurtByTarget.class net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalPanic.class
net\seanomik\tamablefoxes\Utils.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalOwnerHurtTarget.class
net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalMeleeAttack.class

View File

@ -1,21 +1,13 @@
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFloat.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteHandler.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomTargetNonTamed.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtByTarget.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalSit.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtByTarget.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalHurtByTarget.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteHandler.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\Config.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\EntityTamableFox.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalMeleeAttack.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalMeleeAttack.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\EntityTamableFox.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalHurtByTarget.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtTarget.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalSit.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtTarget.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\Utils.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalPickBushes.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBreed.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\TamableFoxes.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\io\FileManager.java E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFollowOwner.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBeg.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLungeUNKNOWN_USE.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\TamableFoxes.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLunge.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomStrollLand.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFollowOwner.java
C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFleeSun.java