1.15.1
Updated for 1.15.1 (see "1.14 TRANS.xlsx" for translated methods from 1.14 to 1.15) Added naming (after taming) supporting color codes Changed formatting of fox names. ("(name) (tamer)") - can be disabled in config. Showing of who tamed can be disabled in config. Improved usability of /spawntamablefox + added alias of /tamablefox Configurable option for tamed foxes to attack chickens and rabbits. Customisable plugin prefix
This commit is contained in:
parent
2bf2341c1a
commit
5ee1eab0b4
|
@ -0,0 +1,106 @@
|
||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/maven,intellij
|
||||||
|
# Edit at https://www.gitignore.io/?templates=maven,intellij
|
||||||
|
|
||||||
|
### Intellij ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### Intellij Patch ###
|
||||||
|
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||||
|
|
||||||
|
# *.iml
|
||||||
|
# modules.xml
|
||||||
|
# .idea/misc.xml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
.idea/**/sonarlint/
|
||||||
|
|
||||||
|
# SonarQube Plugin
|
||||||
|
.idea/**/sonarIssues.xml
|
||||||
|
|
||||||
|
# Markdown Navigator plugin
|
||||||
|
.idea/**/markdown-navigator.xml
|
||||||
|
.idea/**/markdown-navigator/
|
||||||
|
|
||||||
|
### Maven ###
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
.flattened-pom.xml
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/maven,intellij
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="masterDetails">
|
||||||
|
<states>
|
||||||
|
<state key="ProjectJDKs.UI">
|
||||||
|
<settings>
|
||||||
|
<last-edited>1.8</last-edited>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
</states>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
tamableFoxes
|
|
@ -1,8 +0,0 @@
|
||||||
<component name="ArtifactManager">
|
|
||||||
<artifact type="jar" build-on-make="true" name="TamableFoxes-SNAPSHOT:jar">
|
|
||||||
<output-path>$USER_HOME$/OneDrive/Desktop/minecraftSpigotServer/plugins</output-path>
|
|
||||||
<root id="archive" name="TamableFoxes.jar">
|
|
||||||
<element id="module-output" name="TamableFoxes" />
|
|
||||||
</root>
|
|
||||||
</artifact>
|
|
||||||
</component>
|
|
|
@ -6,11 +6,8 @@
|
||||||
<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="TamableFoxes" />
|
<module name="tamableFoxes" />
|
||||||
</profile>
|
</profile>
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
<bytecodeTargetLevel>
|
|
||||||
<module name="TamableFoxes" target="1.8" />
|
|
||||||
</bytecodeTargetLevel>
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -2,7 +2,5 @@
|
||||||
<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$" 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" />
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -1,13 +0,0 @@
|
||||||
<component name="libraryTable">
|
|
||||||
<library name="Maven: net.wesjd:anvilgui:1.2.1-SNAPSHOT">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/net/wesjd/anvilgui/1.2.1-SNAPSHOT/anvilgui-1.2.1-SNAPSHOT.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/net/wesjd/anvilgui/1.2.1-SNAPSHOT/anvilgui-1.2.1-SNAPSHOT-javadoc.jar!/" />
|
|
||||||
</JAVADOC>
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/net/wesjd/anvilgui/1.2.1-SNAPSHOT/anvilgui-1.2.1-SNAPSHOT-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<component name="libraryTable">
|
|
||||||
<library name="Maven: org.spigotmc:spigot:1.14.4-R0.1-SNAPSHOT">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot/1.14.4-R0.1-SNAPSHOT/spigot-1.14.4-R0.1-SNAPSHOT.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot/1.14.4-R0.1-SNAPSHOT/spigot-1.14.4-R0.1-SNAPSHOT-javadoc.jar!/" />
|
|
||||||
</JAVADOC>
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot/1.14.4-R0.1-SNAPSHOT/spigot-1.14.4-R0.1-SNAPSHOT-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
|
@ -1,10 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="EntryPointsManager">
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<list size="1">
|
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
|
|
||||||
</list>
|
|
||||||
</component>
|
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
<list>
|
<list>
|
||||||
|
@ -12,7 +8,7 @@
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" 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>
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/TamableFoxes.iml" filepath="$PROJECT_DIR$/TamableFoxes.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,124 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Palette2">
|
|
||||||
<group name="Swing">
|
|
||||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="Button" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="RadioButton" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="CheckBox" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
|
||||||
<initial-values>
|
|
||||||
<property name="text" value="Label" />
|
|
||||||
</initial-values>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
|
||||||
<preferred-size width="150" height="50" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
|
||||||
<preferred-size width="200" height="200" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
|
||||||
<preferred-size width="200" height="200" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
|
||||||
<preferred-size width="-1" height="20" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
|
||||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
|
||||||
</item>
|
|
||||||
</group>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -1,126 +1,106 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ArtifactsWorkspaceSettings">
|
|
||||||
<artifacts-to-build>
|
|
||||||
<artifact name="tamableFoxesFINAL:jar" />
|
|
||||||
</artifacts-to-build>
|
|
||||||
</component>
|
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="6bbf8d0d-5f70-4ba2-892e-894cfe06e144" name="Default Changelist" comment="" />
|
<list default="true" id="dcab9632-7b1a-44d7-9283-be9b37640afc" name="Default Changelist" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/.idea/$PRODUCT_WORKSPACE_FILE$" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/.idea/.name" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/1.14 TRANS.xlsx" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/lib/spigot-1.15.1.jar" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/EntityTamableFox.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/TamableFoxes.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/command/CommandSpawnTamableFox.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/io/FileManager.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/artifacts/TamableFoxes_SNAPSHOT_jar.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/compiler.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/compiler.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/encodings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/encodings.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/libraries/Maven__net_wesjd_anvilgui_1_2_1_SNAPSHOT.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/libraries/Maven__org_spigotmc_spigot_1_14_4_R0_1_SNAPSHOT.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/uiDesigner.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/TamableFoxes.iml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/Commands/CommandSpawnTamableFox.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/ConfigManager.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBeg.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBreed.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFleeSun.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFloat.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFollowOwner.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalHurtByTarget.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLunge.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLungeUNKNOWN_USE.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalMeleeAttack.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtByTarget.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtTarget.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalPickBushes.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomStrollLand.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomTargetNonTamed.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalSit.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalSit.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/NBTEditor.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/Reference.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/TamableFox.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/Utils/FileManager.java" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/net/seanomik/tamablefoxes/Utils/Utils.java" beforeDir="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/plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/plugin.yml" afterDir="false" />
|
||||||
|
</list>
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="DefaultGradleProjectSettings">
|
<component name="Git.Settings">
|
||||||
<option name="isMigrated" value="true" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
</component>
|
|
||||||
<component name="FileTemplateManagerImpl">
|
|
||||||
<option name="RECENT_TEMPLATES">
|
|
||||||
<list>
|
|
||||||
<option value="Class" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="MavenImportPreferences">
|
|
||||||
<option name="importingSettings">
|
|
||||||
<MavenImportingSettings>
|
|
||||||
<option name="downloadDocsAutomatically" value="true" />
|
|
||||||
<option name="downloadSourcesAutomatically" value="true" />
|
|
||||||
<option name="importAutomatically" value="true" />
|
|
||||||
</MavenImportingSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectId" id="1OWYeLNGlgghaOqU4xcfEvjJFGj" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showExcludedFiles" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProjectId" id="1WXR7SMZcGllgYVjIOg98VPV9wX" />
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="aspect.path.notification.shown" value="true" />
|
||||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
<property name="project.structure.last.edited" value="Artifacts" />
|
<property name="node.js.detected.package.eslint" value="true" />
|
||||||
<property name="project.structure.proportion" value="0.15" />
|
<property name="node.js.detected.package.tslint" value="true" />
|
||||||
<property name="project.structure.side.proportion" value="0.2" />
|
<property name="node.js.path.for.package.eslint" value="project" />
|
||||||
<property name="settings.editor.selected.configurable" value="configurable.group.editor" />
|
<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="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="D:\Code\java\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes" />
|
<recent name="D:\Ellie\ProjectDirectory\tamablefoxes-1\TamableFoxes-1" />
|
||||||
</key>
|
|
||||||
<key name="CopyClassDialog.RECENTS_KEY">
|
|
||||||
<recent name="net.seanomik.tamablefoxes.config" />
|
|
||||||
<recent name="net.seanomik.tamablefoxes.CustomPathfinding" />
|
|
||||||
</key>
|
</key>
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="D:\Code\java\myPlugins\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\config" />
|
<recent name="D:\Ellie\ProjectDirectory\tamablefoxes-1\TamableFoxes-1" />
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="JAR Application.Spigot1.14.4">
|
<component name="RunDashboard">
|
||||||
<configuration name="Spigot1.14.2" type="JarApplication">
|
<option name="ruleStates">
|
||||||
<option name="JAR_PATH" value="$USER_HOME$/OneDrive/Desktop/minecraftSpigotServer/spigot-1.14.2.jar" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="C:\Users\sean_\OneDrive\Desktop\minecraftSpigotServer" />
|
|
||||||
<option name="ALTERNATIVE_JRE_PATH" />
|
|
||||||
<module name="TamableFoxes" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="Spigot1.14.3" type="JarApplication">
|
|
||||||
<option name="JAR_PATH" value="$USER_HOME$/OneDrive/Desktop/minecraftSpigotServer/spigot-1.14.3.jar" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="C:\Users\sean_\OneDrive\Desktop\minecraftSpigotServer" />
|
|
||||||
<option name="ALTERNATIVE_JRE_PATH" />
|
|
||||||
<module name="TamableFoxes" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="Spigot1.14.4" type="JarApplication">
|
|
||||||
<option name="JAR_PATH" value="$USER_HOME$/OneDrive/Desktop/minecraftSpigotServer/spigot-1.14.4.jar" />
|
|
||||||
<option name="WORKING_DIRECTORY" value="C:\Users\sean_\OneDrive\Desktop\minecraftSpigotServer" />
|
|
||||||
<option name="ALTERNATIVE_JRE_PATH" />
|
|
||||||
<module name="TamableFoxes" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="TamableFoxes 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.14.2" />
|
|
||||||
<item itemvalue="JAR Application.Spigot1.14.3" />
|
|
||||||
<item itemvalue="JAR Application.Spigot1.14.4" />
|
|
||||||
<item itemvalue="Maven.TamableFoxes build" />
|
|
||||||
</list>
|
|
||||||
</component>
|
|
||||||
<component name="ServiceViewManager">
|
|
||||||
<option name="viewStates">
|
|
||||||
<list>
|
<list>
|
||||||
<serviceView>
|
<RuleState>
|
||||||
<treeState>
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
<expand />
|
</RuleState>
|
||||||
<select />
|
<RuleState>
|
||||||
</treeState>
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
</serviceView>
|
</RuleState>
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
@ -129,134 +109,31 @@
|
||||||
</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="6bbf8d0d-5f70-4ba2-892e-894cfe06e144" name="Default Changelist" comment="" />
|
<changelist id="dcab9632-7b1a-44d7-9283-be9b37640afc" name="Default Changelist" comment="" />
|
||||||
<created>1559787286537</created>
|
<created>1579293785651</created>
|
||||||
<option name="number" value="Default" />
|
<option name="number" value="Default" />
|
||||||
<option name="presentableId" value="Default" />
|
<option name="presentableId" value="Default" />
|
||||||
<updated>1559787286537</updated>
|
<updated>1579293785651</updated>
|
||||||
|
<workItem from="1579293791372" duration="603000" />
|
||||||
|
<workItem from="1579301287898" duration="48000" />
|
||||||
|
<workItem from="1579301468407" duration="1926000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
<breakpoint-manager>
|
<option name="version" value="1" />
|
||||||
<breakpoints>
|
|
||||||
<line-breakpoint enabled="true" type="java-line">
|
|
||||||
<condition expression="var1 == null" language="JAVA" />
|
|
||||||
<url>jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot/1.14.2-R0.1-SNAPSHOT/spigot-1.14.2-R0.1-SNAPSHOT.jar!/net/minecraft/server/v1_14_R1/PathfinderGoalWrapped.class</url>
|
|
||||||
<line>17</line>
|
|
||||||
<option name="timeStamp" value="36" />
|
|
||||||
</line-breakpoint>
|
|
||||||
</breakpoints>
|
|
||||||
</breakpoint-manager>
|
|
||||||
</component>
|
</component>
|
||||||
<component name="antWorkspaceConfiguration">
|
<component name="Vcs.Log.Tabs.Properties">
|
||||||
<option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
|
<option name="TAB_STATES">
|
||||||
<option name="FILTER_TARGETS" value="false" />
|
<map>
|
||||||
</component>
|
<entry key="MAIN">
|
||||||
<component name="debuggerHistoryManager">
|
<value>
|
||||||
<expressions id="breakpointCondition">
|
<State>
|
||||||
<expression>
|
<option name="COLUMN_ORDER" />
|
||||||
<expression-string>var1 == null</expression-string>
|
</State>
|
||||||
<language-id>JAVA</language-id>
|
</value>
|
||||||
<evaluation-mode>EXPRESSION</evaluation-mode>
|
</entry>
|
||||||
</expression>
|
</map>
|
||||||
<expression>
|
</option>
|
||||||
<expression-string>this.a == null</expression-string>
|
|
||||||
<language-id>JAVA</language-id>
|
|
||||||
<evaluation-mode>EXPRESSION</evaluation-mode>
|
|
||||||
</expression>
|
|
||||||
<expression>
|
|
||||||
<expression-string>this.targetSelector.a == null</expression-string>
|
|
||||||
<language-id>JAVA</language-id>
|
|
||||||
<evaluation-mode>EXPRESSION</evaluation-mode>
|
|
||||||
</expression>
|
|
||||||
<expression>
|
|
||||||
<expression-string>this.a</expression-string>
|
|
||||||
<language-id>JAVA</language-id>
|
|
||||||
<evaluation-mode>EXPRESSION</evaluation-mode>
|
|
||||||
</expression>
|
|
||||||
<expression>
|
|
||||||
<expression-string>null</expression-string>
|
|
||||||
<language-id>JAVA</language-id>
|
|
||||||
<evaluation-mode>EXPRESSION</evaluation-mode>
|
|
||||||
</expression>
|
|
||||||
</expressions>
|
|
||||||
</component>
|
|
||||||
<component name="masterDetails">
|
|
||||||
<states>
|
|
||||||
<state key="ArtifactsStructureConfigurable.UI">
|
|
||||||
<settings>
|
|
||||||
<artifact-editor>
|
|
||||||
<show-sorted>false</show-sorted>
|
|
||||||
</artifact-editor>
|
|
||||||
<last-edited>TamableFoxes-SNAPSHOT:jar</last-edited>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
<option value="0.5" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
<state key="FacetStructureConfigurable.UI">
|
|
||||||
<settings>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
<state key="GlobalLibrariesConfigurable.UI">
|
|
||||||
<settings>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
<state key="JdkListConfigurable.UI">
|
|
||||||
<settings>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
<state key="ModuleStructureConfigurable.UI">
|
|
||||||
<settings>
|
|
||||||
<last-edited>TamableFoxes</last-edited>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
<option value="0.6" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
<state key="ProjectLibrariesConfigurable.UI">
|
|
||||||
<settings>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
</states>
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
Binary file not shown.
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
|
||||||
<component name="FacetManager">
|
|
||||||
<facet type="minecraft" name="Minecraft">
|
|
||||||
<configuration>
|
|
||||||
<autoDetectTypes>
|
|
||||||
<platformType>SPIGOT</platformType>
|
|
||||||
</autoDetectTypes>
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
</component>
|
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
|
||||||
<output url="file://$MODULE_DIR$/target/classes" />
|
|
||||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot:1.14.4-R0.1-SNAPSHOT" level="project" />
|
|
||||||
<orderEntry type="library" name="Maven: net.wesjd:anvilgui:1.2.1-SNAPSHOT" level="project" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
Binary file not shown.
11
pom.xml
11
pom.xml
|
@ -72,8 +72,8 @@
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.14.4-R0.1-SNAPSHOT</version>
|
<version>1.15.1-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -81,5 +81,12 @@
|
||||||
<artifactId>anvilgui</artifactId>
|
<artifactId>anvilgui</artifactId>
|
||||||
<version>1.2.1-SNAPSHOT</version>
|
<version>1.2.1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- For CraftBukkit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${project.basedir}/lib/spigot-1.15.1.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.Commands;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityFox;
|
|
||||||
import net.seanomik.tamablefoxes.Reference;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFoxes;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CommandSpawnTamableFox implements CommandExecutor {
|
|
||||||
|
|
||||||
private TamableFoxes plugin = TamableFoxes.getPlugin(TamableFoxes.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
|
||||||
if (sender instanceof Player) {
|
|
||||||
Player player = (Player) sender;
|
|
||||||
TamableFoxes plugin = TamableFoxes.getPlugin(TamableFoxes.class);
|
|
||||||
|
|
||||||
if (player.hasPermission("tamableFoxes.spawntamablefox")) {
|
|
||||||
if (args.length != 0) {
|
|
||||||
if (args[0].equals("snow")) {
|
|
||||||
plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW);
|
|
||||||
player.sendMessage("Spawned snow fox.");
|
|
||||||
} else if (args[0].equals("verbose")) {
|
|
||||||
player.sendMessage(TamableFoxes.foxUUIDs.toString());
|
|
||||||
} else if (args[0].equals("inspect")) {
|
|
||||||
ItemStack itemStack = new ItemStack(Material.REDSTONE_TORCH, 1);
|
|
||||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
List<String> lore = new LinkedList<>(Arrays.asList(
|
|
||||||
ChatColor.BLUE + "Tamable Fox Inspector"
|
|
||||||
));
|
|
||||||
|
|
||||||
itemMeta.setLore(lore);
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
|
|
||||||
player.getInventory().setItemInMainHand(itemStack);
|
|
||||||
player.sendMessage(Reference.CHAT_PREFIX + ChatColor.GREEN + "Given item.");
|
|
||||||
} else {
|
|
||||||
if (player.getInventory().firstEmpty() == -1) {
|
|
||||||
player.sendMessage(Reference.CHAT_PREFIX + ChatColor.RED + "Inventory is full!");
|
|
||||||
} else {
|
|
||||||
player.sendMessage(Reference.CHAT_PREFIX + ChatColor.GREEN + "Added item to inventory.");
|
|
||||||
player.getInventory().addItem(itemStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//player.sendMessage(TamableFoxes.foxUUIDs.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED);
|
|
||||||
player.sendMessage("Spawned red fox.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
player.sendMessage(ChatColor.RED + "You do not have the permission for this command.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ConfigManager {
|
|
||||||
private TamableFoxes plugin = TamableFoxes.getPlugin(TamableFoxes.class);
|
|
||||||
|
|
||||||
//Files and File Configs Here
|
|
||||||
public FileConfiguration foxesSave;
|
|
||||||
public File foxesfile;
|
|
||||||
|
|
||||||
public void setup() {
|
|
||||||
if (!plugin.getDataFolder().exists()) {
|
|
||||||
plugin.getDataFolder().mkdir();
|
|
||||||
}
|
|
||||||
|
|
||||||
foxesfile = new File(plugin.getDataFolder(), "Foxes.yml");
|
|
||||||
|
|
||||||
if (!foxesfile.exists()) {
|
|
||||||
try {
|
|
||||||
foxesfile.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "Could not create the Foxes.yml file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foxesSave = YamlConfiguration.loadConfiguration(foxesfile);
|
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.GREEN + "The Foxes.yml file has been created successfully!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileConfiguration getFoxes() {
|
|
||||||
return foxesSave;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveFoxes() {
|
|
||||||
try {
|
|
||||||
foxesSave.save(foxesfile);
|
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.AQUA + "The Foxes.yml file has been saved successfully!");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "Could not save the Foxes.yml file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reloadFoxes() {
|
|
||||||
foxesSave = YamlConfiguration.loadConfiguration(foxesfile);
|
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.BLUE + "The Foxes.yml file has been reloaded successfully!");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalBeg extends PathfinderGoal {
|
|
||||||
private final EntityFox a;
|
|
||||||
private final TamableFox z;
|
|
||||||
private EntityHuman b;
|
|
||||||
private final World c;
|
|
||||||
private final float d;
|
|
||||||
private int e;
|
|
||||||
private final PathfinderTargetCondition f;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalBeg(TamableFox 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(Type.LOOK));
|
|
||||||
this.z = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
this.b = this.c.a(this.f, this.a);
|
|
||||||
return this.b == null ? false : 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 c() {
|
|
||||||
((EntityFox)this.a).v(true);
|
|
||||||
this.e = 40 + this.a.getRandom().nextInt(40);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void d() {
|
|
||||||
this.a.v(false);
|
|
||||||
this.b = null;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
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.M());
|
|
||||||
--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) { //var5.getItem() == Items.SWEET_BERRIES) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.a.i(var0.getItemInMainHand())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFoxes;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_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.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalBreed extends PathfinderGoal {
|
|
||||||
private static final PathfinderTargetCondition d = (new PathfinderTargetCondition()).a(8.0D).a().b().c();
|
|
||||||
protected final TamableFox animal;
|
|
||||||
private final Class<? extends EntityAnimal> e;
|
|
||||||
protected final World b;
|
|
||||||
protected EntityAnimal partner;
|
|
||||||
private int f;
|
|
||||||
private final double g;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalBreed(TamableFox entityanimal, double d0) {
|
|
||||||
this(entityanimal, d0, entityanimal.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
public FoxPathfinderGoalBreed(TamableFox entityanimal, double d0, Class<? extends EntityAnimal> oclass) {
|
|
||||||
this.animal = entityanimal;
|
|
||||||
this.b = entityanimal.world;
|
|
||||||
this.e = oclass;
|
|
||||||
this.g = d0;
|
|
||||||
this.a(EnumSet.of(Type.MOVE, Type.LOOK));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
if (!this.animal.isInLove()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
this.partner = this.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, (float)this.animal.M());
|
|
||||||
this.animal.getNavigation().a(this.partner, this.g);
|
|
||||||
++this.f;
|
|
||||||
if (this.f >= 60 && this.animal.h(this.partner) < 9.0D) {
|
|
||||||
this.g();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private EntityAnimal h() {
|
|
||||||
List<EntityAnimal> list = this.b.a(this.e, d, this.animal, this.animal.getBoundingBox().g(8.0D));
|
|
||||||
double d0 = 1.7976931348623157E308D;
|
|
||||||
EntityAnimal entityanimal = null;
|
|
||||||
Iterator iterator = list.iterator();
|
|
||||||
|
|
||||||
while(iterator.hasNext()) {
|
|
||||||
EntityAnimal entityanimal1 = (EntityAnimal)iterator.next();
|
|
||||||
if (this.animal.mate(entityanimal1) && this.animal.h(entityanimal1) < d0) {
|
|
||||||
entityanimal = entityanimal1;
|
|
||||||
d0 = this.animal.h(entityanimal1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return entityanimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void g() {
|
|
||||||
EntityAgeable entityageable = this.animal.createChild(animal);
|
|
||||||
TamableFox tamableFoxAgeable = (TamableFox) entityageable.getBukkitEntity().getHandle();
|
|
||||||
|
|
||||||
if (entityageable != null) {
|
|
||||||
if (entityageable instanceof EntityTameableAnimal && ((EntityTameableAnimal)entityageable).isTamed()) {
|
|
||||||
entityageable.persistent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(-24000);
|
|
||||||
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);
|
|
||||||
|
|
||||||
TamableFox tamableFoxBaby = (TamableFox) entityageable;
|
|
||||||
tamableFoxBaby.setTamed(true);
|
|
||||||
tamableFoxBaby.setOwner(entityplayer);
|
|
||||||
|
|
||||||
// Add fox to foxUUIDs to get their owner and other things
|
|
||||||
TamableFoxes.foxUUIDs.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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockPosition;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoalFleeSun;
|
|
||||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalFleeSun extends PathfinderGoalFleeSun {
|
|
||||||
private int c = 100;
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalFleeSun(TamableFox tamableFox, double d0) {
|
|
||||||
super(tamableFox, d0);
|
|
||||||
this.tamableFox = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
if (tamableFox.isTamed()) {
|
|
||||||
return false;
|
|
||||||
} else if (!tamableFox.isSleeping() && this.a.getGoalTarget() == null) {
|
|
||||||
if (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 tamableFox.world.J() && tamableFox.world.f(blockposition) && !((WorldServer)tamableFox.world).b_(blockposition) && this.g();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
try {
|
|
||||||
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
|
|
||||||
Method method = entityFoxClass.getDeclaredMethod("en");
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(tamableFox);
|
|
||||||
method.setAccessible(false);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
super.c();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityFox;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoalFloat;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalFloat extends PathfinderGoalFloat {
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
public FoxPathfinderGoalFloat(TamableFox tamableFox) {
|
|
||||||
super(tamableFox);
|
|
||||||
this.tamableFox = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
try {
|
|
||||||
super.c();
|
|
||||||
Method method = tamableFox.getClass().getSuperclass().getDeclaredMethod("en");
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(tamableFox);
|
|
||||||
method.setAccessible(false);
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
//tamableFox.en();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
return tamableFox.isInWater() && tamableFox.cf() > 0.25D || tamableFox.aD();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalLunge extends PathfinderGoalWaterJumpAbstract {
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalLunge(TamableFox tamableFox) {
|
|
||||||
this.tamableFox = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
if (!tamableFox.ee()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
if (entityliving != null && entityliving.isAlive()) {
|
|
||||||
if (entityliving.getAdjustedDirection() != entityliving.getDirection()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
boolean flag = EntityFox.a((EntityFox)tamableFox, (EntityLiving)entityliving);
|
|
||||||
if (!flag) {
|
|
||||||
tamableFox.getNavigation().a(entityliving, 0);
|
|
||||||
tamableFox.setCrouching(false);
|
|
||||||
tamableFox.u(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean b() {
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
if (entityliving != null && entityliving.isAlive()) {
|
|
||||||
double d0 = tamableFox.getMot().y;
|
|
||||||
return (d0 * d0 >= 0.05000000074505806D || Math.abs(tamableFox.pitch) >= 15.0F || !tamableFox.onGround) && !tamableFox.dX();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean C_() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
tamableFox.setJumping(true);
|
|
||||||
tamableFox.s(true);
|
|
||||||
tamableFox.u(false);
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
|
|
||||||
Vec3D vec3d = (new Vec3D(entityliving.locX - tamableFox.locX, entityliving.locY - tamableFox.locY, entityliving.locZ - tamableFox.locZ)).d();
|
|
||||||
tamableFox.setMot(tamableFox.getMot().add(vec3d.x * 0.8D, 0.9D, vec3d.z * 0.8D));
|
|
||||||
tamableFox.getNavigation().o();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void d() {
|
|
||||||
tamableFox.setCrouching(false);
|
|
||||||
try {
|
|
||||||
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
|
|
||||||
Field field = entityFoxClass.getDeclaredField("bN");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(tamableFox, 0.0F);
|
|
||||||
field.setAccessible(false);
|
|
||||||
|
|
||||||
field = entityFoxClass.getDeclaredField("bO");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(tamableFox, 0);
|
|
||||||
field.setAccessible(false);
|
|
||||||
/*tamableFox.bN = 0.0F;
|
|
||||||
tamableFox.bO = 0.0F;*/
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
tamableFox.u(false);
|
|
||||||
tamableFox.s(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void e() {
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
if (entityliving != null) {
|
|
||||||
tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tamableFox.dX()) {
|
|
||||||
Vec3D vec3d = tamableFox.getMot();
|
|
||||||
if (vec3d.y * vec3d.y < 0.029999999329447746D && tamableFox.pitch != 0.0F) {
|
|
||||||
tamableFox.pitch = this.a(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;
|
|
||||||
tamableFox.pitch = (float)d1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entityliving != null && tamableFox.g(entityliving) <= 2.0F) {
|
|
||||||
tamableFox.C(entityliving);
|
|
||||||
} else if (tamableFox.pitch > 0.0F && tamableFox.onGround && (float)tamableFox.getMot().y != 0.0F && tamableFox.world.getType(new BlockPosition(tamableFox)).getBlock() == Blocks.SNOW) {
|
|
||||||
tamableFox.pitch = 60.0F;
|
|
||||||
tamableFox.setGoalTarget((EntityLiving)null);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
|
|
||||||
Method method = entityFoxClass.getDeclaredMethod("v");
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(tamableFox, true);
|
|
||||||
method.setAccessible(false);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
//tamableFox.v(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
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 FoxPathfinderGoalLungeUNKNOWN_USE extends PathfinderGoal {
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalLungeUNKNOWN_USE(TamableFox tamableFox) {
|
|
||||||
this.a(EnumSet.of(net.minecraft.server.v1_14_R1.PathfinderGoal.Type.MOVE, net.minecraft.server.v1_14_R1.PathfinderGoal.Type.LOOK));
|
|
||||||
this.tamableFox = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
if (tamableFox.isSleeping()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
|
|
||||||
Field field = entityFoxClass.getDeclaredField("bG");
|
|
||||||
field.setAccessible(true);
|
|
||||||
Predicate<Entity> bG = (Predicate<Entity>) field.get(tamableFox);
|
|
||||||
field.setAccessible(false);
|
|
||||||
|
|
||||||
return entityliving != null && entityliving.isAlive() && bG.test(entityliving) && tamableFox.h(entityliving) > 36.0D && !tamableFox.isCrouching() && !tamableFox.eg() && !tamableFox.isJumping();
|
|
||||||
} catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NullPointerException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
tamableFox.setSitting(false);
|
|
||||||
try {
|
|
||||||
Method method = tamableFox.getClass().getSuperclass().getDeclaredMethod("v", boolean.class);
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(tamableFox, false);
|
|
||||||
method.setAccessible(false);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void d() {
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
if (entityliving != null && EntityFox.a((EntityFox)tamableFox, (EntityLiving)entityliving)) {
|
|
||||||
tamableFox.u(true);
|
|
||||||
tamableFox.setCrouching(true);
|
|
||||||
tamableFox.getNavigation().o();
|
|
||||||
tamableFox.getControllerLook().a(entityliving, (float)tamableFox.dA(), (float)tamableFox.M());
|
|
||||||
} else {
|
|
||||||
tamableFox.u(false);
|
|
||||||
tamableFox.setCrouching(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void e() {
|
|
||||||
EntityLiving entityliving = tamableFox.getGoalTarget();
|
|
||||||
tamableFox.getControllerLook().a(entityliving, (float)tamableFox.dA(), (float)tamableFox.M());
|
|
||||||
if (tamableFox.h(entityliving) <= 36.0D) {
|
|
||||||
tamableFox.u(true);
|
|
||||||
tamableFox.setCrouching(true);
|
|
||||||
tamableFox.getNavigation().o();
|
|
||||||
} else {
|
|
||||||
tamableFox.getNavigation().a(entityliving, 1.5D);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityLiving;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoalMeleeAttack;
|
|
||||||
import net.minecraft.server.v1_14_R1.SoundEffects;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalMeleeAttack extends PathfinderGoalMeleeAttack {
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
public FoxPathfinderGoalMeleeAttack(TamableFox tamableFox, double d0, boolean flag) {
|
|
||||||
super(tamableFox, d0, flag);
|
|
||||||
this.tamableFox = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void a(EntityLiving entityliving, double d0) {
|
|
||||||
double d1 = this.a(entityliving);
|
|
||||||
if (d0 <= d1 && this.b <= 0) {
|
|
||||||
this.b = 20;
|
|
||||||
this.a.C(entityliving);
|
|
||||||
tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
tamableFox.u(false);
|
|
||||||
super.c();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
return !tamableFox.isSitting() && !tamableFox.isSleeping() && !tamableFox.isCrouching() && !tamableFox.dX() && super.a();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
import org.bukkit.event.entity.EntityTargetEvent;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget {
|
|
||||||
private final TamableFox a;
|
|
||||||
private EntityLiving b;
|
|
||||||
private int c;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalOwnerHurtTarget(TamableFox 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.cu();
|
|
||||||
int i = entityliving.cv();
|
|
||||||
return i != this.c && this.a(this.b, PathfinderTargetCondition.a);// && this.a.a(this.b, entityliving);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
this.e.setGoalTarget(this.b, EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true);
|
|
||||||
EntityLiving entityliving = this.a.getOwner();
|
|
||||||
if (entityliving != null) {
|
|
||||||
this.c = entityliving.cv();
|
|
||||||
}
|
|
||||||
|
|
||||||
super.c();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalPickBushes extends PathfinderGoalGotoTarget {
|
|
||||||
protected int g;
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalPickBushes(TamableFox 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 (!tamableFox.isTamed()) {
|
|
||||||
IBlockData iblockdata = iworldreader.getType(blockposition);
|
|
||||||
return iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH && (Integer) iblockdata.get(BlockSweetBerryBush.a) >= 2;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void e() {
|
|
||||||
if (this.k()) {
|
|
||||||
if (this.g >= 40) {
|
|
||||||
this.m();
|
|
||||||
} else {
|
|
||||||
++this.g;
|
|
||||||
}
|
|
||||||
//} else if (!this.k() && tamableFox.getRandom().nextFloat() < 0.05F && !tamableFox.isTamed()) {
|
|
||||||
} else if (!this.k() && tamableFox.getRandom().nextFloat() < 0.05F && !tamableFox.isTamed()) {
|
|
||||||
tamableFox.a(SoundEffects.ENTITY_FOX_SNIFF, 1.0F, 1.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.e();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void m() {
|
|
||||||
if (tamableFox.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT) && !tamableFox.isTamed()) {
|
|
||||||
IBlockData iblockdata = 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(tamableFox, this.e, (IBlockData)iblockdata.set(BlockSweetBerryBush.a, 1)).isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int j = 1 + tamableFox.world.random.nextInt(2) + (i == 3 ? 1 : 0);
|
|
||||||
ItemStack itemstack = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
|
|
||||||
if (itemstack.isEmpty()) {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.SWEET_BERRIES));
|
|
||||||
--j;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j > 0) {
|
|
||||||
Block.a(tamableFox.world, this.e, new ItemStack(Items.SWEET_BERRIES, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
tamableFox.a(SoundEffects.ITEM_SWEET_BERRIES_PICK_FROM_BUSH, 1.0F, 1.0F);
|
|
||||||
tamableFox.world.setTypeAndData(this.e, (IBlockData)iblockdata.set(BlockSweetBerryBush.a, 1), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
return !tamableFox.isSleeping() && super.a();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void c() {
|
|
||||||
this.g = 0;
|
|
||||||
tamableFox.setSitting(false);
|
|
||||||
super.c();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityCreature;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoalRandomStroll;
|
|
||||||
import net.minecraft.server.v1_14_R1.RandomPositionGenerator;
|
|
||||||
import net.minecraft.server.v1_14_R1.Vec3D;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalRandomStrollLand extends PathfinderGoalRandomStroll {
|
|
||||||
protected final float h;
|
|
||||||
protected TamableFox tamableFox;
|
|
||||||
protected Vec3D vec3D;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalRandomStrollLand(TamableFox var0, double var1) {
|
|
||||||
this(var0, var1, 0.001F);
|
|
||||||
this.tamableFox = var0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FoxPathfinderGoalRandomStrollLand(TamableFox var0, double var1, float var3) {
|
|
||||||
super(var0, var1);
|
|
||||||
this.h = var3;
|
|
||||||
this.tamableFox = var0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean a() {
|
|
||||||
if (this.a.isVehicle()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
if (!this.g) {
|
|
||||||
if (this.a.cw() >= 100) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.a.getRandom().nextInt(this.f) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tamableFox.isSitting()) {
|
|
||||||
vec3D = this.g();
|
|
||||||
}
|
|
||||||
if (vec3D == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
this.b = vec3D.x;
|
|
||||||
this.c = vec3D.y;
|
|
||||||
this.d = vec3D.z;
|
|
||||||
this.g = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected Vec3D g() {
|
|
||||||
if (this.a.av()) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean b() {
|
|
||||||
/*Bukkit.broadcastMessage("B: " + !this.a.getNavigation().n());
|
|
||||||
if (tamableFox.isSitting()) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;*/
|
|
||||||
return !this.a.getNavigation().n();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void c() {
|
|
||||||
this.a.getNavigation().a(this.b, this.c, this.d, this.e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void h() {
|
|
||||||
this.g = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTimeBetweenMovement(int var0) {
|
|
||||||
this.f = var0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void e() {
|
|
||||||
if (tamableFox.isSitting()) {
|
|
||||||
vec3D = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean C_() {
|
|
||||||
if (tamableFox.isSitting()) {
|
|
||||||
vec3D = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityLiving;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoalNearestAttackableTarget;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalRandomTargetNonTamed<T extends EntityLiving> extends PathfinderGoalNearestAttackableTarget<T> {
|
|
||||||
private final TamableFox tamableFox;
|
|
||||||
|
|
||||||
public FoxPathfinderGoalRandomTargetNonTamed(TamableFox tamableFox, Class<T> var1, boolean var2, @Nullable Predicate<EntityLiving> var3) {
|
|
||||||
super(tamableFox, var1, 10, var2, false, var3);
|
|
||||||
this.tamableFox = tamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean a() {
|
|
||||||
return !tamableFox.isTamed() && super.a();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean b() {
|
|
||||||
return this.d != null ? this.d.a(this.e, this.c) : super.b();
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes;
|
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
|
|
||||||
public class Reference {
|
|
||||||
public static final String CHAT_PREFIX = ChatColor.RED + "[Tamable Foxes] ";
|
|
||||||
public static final String CUSTOM_FOX_REGISTER_NAME = "tameablefox";
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,241 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes;
|
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.CustomPathfinding.*;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory;
|
|
||||||
import org.bukkit.entity.Fox;
|
|
||||||
import org.bukkit.event.entity.EntityTargetEvent;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static net.seanomik.tamablefoxes.TamableFoxes.plugin;
|
|
||||||
import static net.seanomik.tamablefoxes.TamableFoxes.fileManager;
|
|
||||||
|
|
||||||
public class TamableFox extends EntityFox {
|
|
||||||
private boolean isTamed;
|
|
||||||
private EntityLiving owner;
|
|
||||||
private UUID ownerUUID;
|
|
||||||
private boolean sit = false;
|
|
||||||
private static Fox thisFox;
|
|
||||||
private BukkitTask sittingRunnable;
|
|
||||||
|
|
||||||
protected FoxPathfinderGoalSit goalSit;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initPathfinder() {
|
|
||||||
this.goalSit = new FoxPathfinderGoalSit(this);
|
|
||||||
|
|
||||||
this.goalSelector.a(1, new FoxPathfinderGoalFloat(this));
|
|
||||||
|
|
||||||
this.goalSelector.a(2, this.goalSit);
|
|
||||||
|
|
||||||
this.goalSelector.a(3, new FoxPathfinderGoalMeleeAttack(this, 1.2000000476837158D, true)); // l | Lunging
|
|
||||||
this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> {
|
|
||||||
return !((EntityWolf)entityliving).isTamed();
|
|
||||||
}));
|
|
||||||
this.goalSelector.a(4, new FoxPathfinderGoalFollowOwner(this, 1.35D, 10.0F, 2.0F));
|
|
||||||
|
|
||||||
this.goalSelector.a(4, new FoxPathfinderGoalLungeUNKNOWN_USE(this)); // u | Lunging
|
|
||||||
this.goalSelector.a(5, new FoxPathfinderGoalLunge(this)); // o | Lunging
|
|
||||||
|
|
||||||
this.goalSelector.a(5, new FoxPathfinderGoalFleeSun(this, 1.25D));
|
|
||||||
this.goalSelector.a(5, new FoxPathfinderGoalBreed(this, 1.0D));
|
|
||||||
|
|
||||||
this.goalSelector.a(7, new PathfinderGoalFollowParent(this, 1.1D));
|
|
||||||
this.goalSelector.a(7, new FoxPathfinderGoalBeg(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 FoxPathfinderGoalPickBushes(this, 1.2000000476837158D, 12, 2));
|
|
||||||
this.goalSelector.a(10, new FoxPathfinderGoalRandomStrollLand(this, 1D));
|
|
||||||
|
|
||||||
this.targetSelector.a(1, new FoxPathfinderGoalOwnerHurtByTarget(this));
|
|
||||||
this.targetSelector.a(2, new FoxPathfinderGoalOwnerHurtTarget(this));
|
|
||||||
|
|
||||||
PathfinderGoal targetsGoal = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false, (entityliving) -> {
|
|
||||||
return entityliving instanceof EntityChicken || entityliving instanceof EntityRabbit;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.targetSelector.a(4, targetsGoal);
|
|
||||||
this.targetSelector.a(5, (new FoxPathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public TamableFox(EntityTypes entitytypes, World world) {
|
|
||||||
super(EntityTypes.FOX, world);
|
|
||||||
|
|
||||||
thisFox = (Fox) this.getBukkitEntity();
|
|
||||||
TamableFoxes.foxUUIDs.put(this.getBukkitEntity().getUniqueId(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@Override
|
|
||||||
//protected void a(DifficultyDamageScaler difficultydamagescaler) { } // Doesn't spawn with any items in its mouth
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initAttributes() {
|
|
||||||
this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
|
|
||||||
this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
|
|
||||||
this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
|
|
||||||
this.getAttributeMap().b(GenericAttributes.ARMOR);
|
|
||||||
this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
|
|
||||||
|
|
||||||
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
|
|
||||||
this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
|
|
||||||
|
|
||||||
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityFox createChild(EntityAgeable entityageable) {
|
|
||||||
WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
|
|
||||||
Location location = entityageable.getBukkitEntity().getLocation();
|
|
||||||
net.minecraft.server.v1_14_R1.Entity b = TamableFoxes.customType.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pick up items
|
|
||||||
@Override
|
|
||||||
protected void a(EntityItem entityitem) {
|
|
||||||
ItemStack itemstack = entityitem.getItemStack();
|
|
||||||
if (!isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem, itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
|
|
||||||
try {
|
|
||||||
int i = itemstack.getCount();
|
|
||||||
if (i > 1) {
|
|
||||||
Method method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(this, itemstack.cloneAndSubtract(i - 1));
|
|
||||||
method.setAccessible(false);
|
|
||||||
}
|
|
||||||
Method 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("bO");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(this, 0);
|
|
||||||
field.setAccessible(false);
|
|
||||||
} catch (NoSuchMethodException | NoSuchFieldException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTamed() {
|
|
||||||
return isTamed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(EntityLiving owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
fileManager.getConfig("foxes.yml").set("Foxes." + thisFox.getUniqueId() + ".owner", owner.getUniqueIDString());
|
|
||||||
fileManager.saveConfig("foxes.yml");
|
|
||||||
sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityLiving getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTamed(Boolean tamed) {
|
|
||||||
this.isTamed = tamed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean toggleSitting() {
|
|
||||||
sit = !sit;
|
|
||||||
sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
|
|
||||||
return sit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateFox() {
|
|
||||||
sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
|
|
||||||
BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
|
|
||||||
EntityFox.Type entityfox_type = EntityFox.Type.a(biomebase);
|
|
||||||
boolean flag = false;
|
|
||||||
if (groupdataentity instanceof EntityFox.i) {
|
|
||||||
entityfox_type = ((EntityFox.i)groupdataentity).a;
|
|
||||||
if (((EntityFox.i)groupdataentity).b >= 2) {
|
|
||||||
flag = true;
|
|
||||||
} else {
|
|
||||||
++((EntityFox.i)groupdataentity).b;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
groupdataentity = new EntityFox.i(entityfox_type);
|
|
||||||
++((EntityFox.i)groupdataentity).b;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setFoxType(entityfox_type);
|
|
||||||
if (flag) {
|
|
||||||
this.setAgeRaw(-24000);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.initPathfinder();
|
|
||||||
this.a(difficultydamagescaler);
|
|
||||||
|
|
||||||
// From EntityInsentient
|
|
||||||
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
|
|
||||||
if (this.random.nextFloat() < 0.05F) {
|
|
||||||
this.p(true);
|
|
||||||
} else {
|
|
||||||
this.p(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupdataentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UpdateFoxRunnable extends BukkitRunnable {
|
|
||||||
private final JavaPlugin plugin;
|
|
||||||
|
|
||||||
public UpdateFoxRunnable(JavaPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
TamableFox.this.goalSit.setSitting(TamableFox.this.sit);
|
|
||||||
TamableFox.thisFox.setVelocity(new Vector(0,0,0));
|
|
||||||
|
|
||||||
TamableFox.this.setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
|
|
||||||
|
|
||||||
// Set custom name
|
|
||||||
if (TamableFox.this.owner != null && fileManager.getConfig("config.yml").get().getBoolean("show-owner-in-fox-name")) {
|
|
||||||
getBukkitEntity().setCustomName("Tamed by: " + TamableFox.this.owner.getName());
|
|
||||||
getBukkitEntity().setCustomNameVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isJumping() {
|
|
||||||
return jumping;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,464 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes;
|
|
||||||
|
|
||||||
import com.mojang.datafixers.DataFixUtils;
|
|
||||||
import com.mojang.datafixers.types.Type;
|
|
||||||
import com.sun.istack.internal.NotNull;
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
|
||||||
import net.seanomik.tamablefoxes.Commands.CommandSpawnTamableFox;
|
|
||||||
import net.seanomik.tamablefoxes.Utils.FileManager;
|
|
||||||
import org.bukkit.*;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftFox;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.*;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
|
||||||
import org.bukkit.event.player.*;
|
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public final class TamableFoxes extends JavaPlugin implements Listener {
|
|
||||||
|
|
||||||
public static Map<UUID, UUID> foxUUIDs = new HashMap<>(); // FoxUUID, OwnerUUID
|
|
||||||
public static EntityTypes customType;
|
|
||||||
public static JavaPlugin plugin;
|
|
||||||
private boolean isOnLoad = true;
|
|
||||||
private File dataFolder = null;
|
|
||||||
|
|
||||||
public static FileManager fileManager;
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// Fix the fox moving when you make it sit while it was moving.
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
if (!Bukkit.getVersion().contains("1.14.4")) {
|
|
||||||
Bukkit.getConsoleSender().sendMessage(Reference.CHAT_PREFIX + ChatColor.RED + "THIS PLUGIN WILL ONLY RUN ON MC SPIGOT 1.14.4!");
|
|
||||||
getServer().getPluginManager().disablePlugin(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileManager = new FileManager(this);
|
|
||||||
fileManager.getConfig("foxes.yml").copyDefaults(true).save();
|
|
||||||
fileManager.getConfig("config.yml").copyDefaults(true).save();
|
|
||||||
|
|
||||||
getServer().getPluginManager().registerEvents(this, this);
|
|
||||||
getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox());
|
|
||||||
|
|
||||||
plugin = getPlugin(this.getClass());
|
|
||||||
dataFolder = getDataFolder();
|
|
||||||
|
|
||||||
// Registering Fox
|
|
||||||
Map<String, Type<?>> types = (Map<String, Type<?>>) DataConverterRegistry.a().getSchema(DataFixUtils.makeKey(SharedConstants.a().getWorldVersion())).findChoiceType(DataConverterTypes.ENTITY).types();
|
|
||||||
types.put("minecraft:" + Reference.CUSTOM_FOX_REGISTER_NAME, types.get("minecraft:fox"));
|
|
||||||
EntityTypes.a<net.minecraft.server.v1_14_R1.Entity> a = EntityTypes.a.a(TamableFox::new, EnumCreatureType.AMBIENT);
|
|
||||||
customType = IRegistry.a(IRegistry.ENTITY_TYPE, Reference.CUSTOM_FOX_REGISTER_NAME, a.a(Reference.CUSTOM_FOX_REGISTER_NAME));
|
|
||||||
|
|
||||||
// Spawn all foxes
|
|
||||||
replaceFoxesOnLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void replaceFoxesOnLoad() {
|
|
||||||
int amountReplaced = 0;
|
|
||||||
World world = Bukkit.getWorlds().get(0);
|
|
||||||
for (Chunk chunk : world.getLoadedChunks()) {
|
|
||||||
for (Entity entity : chunk.getEntities()) {
|
|
||||||
if(entity instanceof Fox) {
|
|
||||||
if (isTamableFox(entity)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TamableFox tamableFox = (TamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
|
|
||||||
|
|
||||||
if (fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId()) != null) {
|
|
||||||
Bukkit.broadcastMessage("NOT NULL");
|
|
||||||
String owner = fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId() + ".owner");
|
|
||||||
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + entity.getUniqueId(), null);
|
|
||||||
if (owner.equals("none")) {
|
|
||||||
foxUUIDs.replace(tamableFox.getUniqueID(), null);
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
|
|
||||||
} else {
|
|
||||||
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
|
|
||||||
tamableFox.setTamed(true);
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
|
|
||||||
tamableFox.updateFox();
|
|
||||||
|
|
||||||
tamableFox.setAge(((CraftFox) entity).getAge());
|
|
||||||
|
|
||||||
org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
|
|
||||||
if (entityMouthItem.getType() != Material.AIR) {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
|
|
||||||
} else {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
|
|
||||||
tamableFox.setAge(((CraftFox) entity).getAge());
|
|
||||||
|
|
||||||
org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
|
|
||||||
if (entityMouthItem.getType() != Material.AIR) {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
|
|
||||||
} else {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.remove();
|
|
||||||
amountReplaced++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Bukkit.getConsoleSender().sendMessage(Reference.CHAT_PREFIX + "Respawned " + amountReplaced + " foxes.");
|
|
||||||
fileManager.saveConfig("foxes.yml");
|
|
||||||
isOnLoad = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static net.minecraft.server.v1_14_R1.Entity spawnTamableFox(Location location, EntityFox.Type type) {
|
|
||||||
WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
|
|
||||||
|
|
||||||
net.minecraft.server.v1_14_R1.Entity spawnedEntity = customType.b(world,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
new BlockPosition(location.getX(), location.getY(), location.getZ()),
|
|
||||||
null, false, false);
|
|
||||||
world.addEntity(spawnedEntity);
|
|
||||||
|
|
||||||
EntityFox fox = (EntityFox) spawnedEntity;
|
|
||||||
fox.setFoxType(type);
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + spawnedEntity.getUniqueID() + ".owner", "none");
|
|
||||||
fileManager.saveConfig("foxes.yml");
|
|
||||||
return fox;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onChunkLoad (ChunkLoadEvent event) {
|
|
||||||
if (!isOnLoad) {
|
|
||||||
Chunk chunk = event.getChunk();
|
|
||||||
for (Entity entity : chunk.getEntities()) {
|
|
||||||
if (entity instanceof Fox) {
|
|
||||||
if (isTamableFox(entity)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TamableFox tamableFox = (TamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
|
|
||||||
|
|
||||||
if (fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId()) != null) {
|
|
||||||
String owner = fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId() + ".owner");
|
|
||||||
if (!owner.equals("none")) {
|
|
||||||
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + entity.getUniqueId(), null);
|
|
||||||
tamableFox.setTamed(true);
|
|
||||||
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
|
|
||||||
tamableFox.updateFox();
|
|
||||||
|
|
||||||
tamableFox.setAge(((CraftFox) entity).getAge());
|
|
||||||
|
|
||||||
org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
|
|
||||||
if (entityMouthItem.getType() != Material.AIR) {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
|
|
||||||
} else {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
|
|
||||||
tamableFox.setAge(((CraftFox) entity).getAge());
|
|
||||||
|
|
||||||
org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
|
|
||||||
if (entityMouthItem.getType() != Material.AIR) {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
|
|
||||||
} else {
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (foxUUIDs.containsValue(player.getUniqueId())) {
|
|
||||||
for (Map.Entry<UUID, UUID> entry : foxUUIDs.entrySet()) {
|
|
||||||
if (entry.getValue() != null && entry.getValue().equals(player.getUniqueId())) {
|
|
||||||
TamableFox tamableFox = (TamableFox) ((CraftEntity) getEntityByUniqueId(entry.getKey())).getHandle();
|
|
||||||
tamableFox.setOwner(((CraftPlayer) player).getHandle());
|
|
||||||
tamableFox.setTamed(true);
|
|
||||||
foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
|
|
||||||
Entity entity = event.getRightClicked();
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
if (event.getHand().equals(EquipmentSlot.HAND)) {
|
|
||||||
ItemMeta itemMeta = player.getInventory().getItemInMainHand().getItemMeta();
|
|
||||||
if (player.getInventory().getItemInMainHand().getType() == Material.REDSTONE_TORCH && !isTamableFox(entity) && itemMeta.getLore().contains(ChatColor.BLUE + "Tamable Fox Inspector")) {
|
|
||||||
org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand();
|
|
||||||
ItemMeta itemMeta1 = item.getItemMeta();
|
|
||||||
List<String> lore = new LinkedList<>(Arrays.asList(
|
|
||||||
ChatColor.BLUE + "Tamable Fox Inspector",
|
|
||||||
"UUID: " + entity.getUniqueId(),
|
|
||||||
"Entity ID: " + entity.getEntityId()
|
|
||||||
));
|
|
||||||
itemMeta1.setLore(lore);
|
|
||||||
item.setItemMeta(itemMeta1);
|
|
||||||
player.sendMessage("Inspected Entity.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTamableFox(entity)) {
|
|
||||||
TamableFox tamableFox = (TamableFox) ((CraftEntity)entity).getHandle();
|
|
||||||
if (player.getInventory().getItemInMainHand().getType() == Material.REDSTONE_TORCH && itemMeta.getLore().contains(ChatColor.BLUE + "Tamable Fox Inspector")) {
|
|
||||||
org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand();
|
|
||||||
List<String> lore = new LinkedList<>();
|
|
||||||
if (tamableFox.getOwner() == null) {
|
|
||||||
lore = new LinkedList<>(Arrays.asList(
|
|
||||||
ChatColor.BLUE + "Tamable Fox Inspector",
|
|
||||||
"UUID: " + entity.getUniqueId(),
|
|
||||||
"Entity ID: " + entity.getEntityId(),
|
|
||||||
"Tamable",
|
|
||||||
"Owner: None"
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
lore = new LinkedList<>(Arrays.asList(
|
|
||||||
ChatColor.BLUE + "Tamable Fox Inspector",
|
|
||||||
"UUID: " + entity.getUniqueId(),
|
|
||||||
"Entity ID: " + entity.getEntityId(),
|
|
||||||
"Tamable",
|
|
||||||
"Owner: " + tamableFox.getOwner().getName()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
itemMeta.setLore(lore);
|
|
||||||
item.setItemMeta(itemMeta);
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tamableFox.isTamed() && tamableFox.getOwner() != null && player.getInventory().getItemInMainHand().getType() != Material.SWEET_BERRIES) {
|
|
||||||
if (player.getUniqueId() == foxUUIDs.get(entity.getUniqueId())) {
|
|
||||||
if (player.isSneaking()) { // Shift right click to add items
|
|
||||||
ItemStack itemstack = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
|
|
||||||
if (itemstack.isEmpty()) {
|
|
||||||
if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
net.minecraft.server.v1_14_R1.ItemStack playerItemInHandNMS = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
|
|
||||||
|
|
||||||
playerItemInHandNMS.setCount(1);
|
|
||||||
|
|
||||||
// Set foxes mouth
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
|
|
||||||
|
|
||||||
// Take item from player
|
|
||||||
org.bukkit.inventory.ItemStack playerItemInHand = player.getInventory().getItemInMainHand();
|
|
||||||
playerItemInHand.setAmount(playerItemInHand.getAmount() - 1);
|
|
||||||
player.getInventory().setItemInMainHand(playerItemInHand);
|
|
||||||
} else {
|
|
||||||
if (player.getInventory().getItemInMainHand().getType() == Material.AIR) { //
|
|
||||||
// Drop the item in the foxes mouth on the floor
|
|
||||||
World world = Bukkit.getWorlds().get(0);
|
|
||||||
world.dropItem(tamableFox.getBukkitEntity().getLocation().add(0D, 0.2D, 0D), CraftItemStack.asBukkitCopy(itemstack));
|
|
||||||
|
|
||||||
// Remove the item from mouth
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
|
|
||||||
} else { // Replace items
|
|
||||||
net.minecraft.server.v1_14_R1.ItemStack playerItemInHandNMS = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
|
|
||||||
|
|
||||||
// Drop the item in the foxes mouth on the floor
|
|
||||||
World world = Bukkit.getWorlds().get(0);
|
|
||||||
world.dropItem(tamableFox.getBukkitEntity().getLocation().add(0D, 0.2D, 0D), CraftItemStack.asBukkitCopy(itemstack));
|
|
||||||
|
|
||||||
playerItemInHandNMS.setCount(1);
|
|
||||||
|
|
||||||
// Set foxes mouth
|
|
||||||
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
|
|
||||||
|
|
||||||
// Take item from player
|
|
||||||
org.bukkit.inventory.ItemStack playerItemInHand = player.getInventory().getItemInMainHand();
|
|
||||||
playerItemInHand.setAmount(playerItemInHand.getAmount() - 1);
|
|
||||||
player.getInventory().setItemInMainHand(playerItemInHand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tamableFox.toggleSitting();
|
|
||||||
}
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
} else if (player.getInventory().getItemInMainHand().getType() == Material.CHICKEN) {
|
|
||||||
if (Math.random() < 0.33) {
|
|
||||||
tamableFox.setTamed(true);
|
|
||||||
tamableFox.setOwner(((CraftPlayer) player).getHandle());
|
|
||||||
|
|
||||||
// Add fox to foxUUIDs to get their owner and other things
|
|
||||||
TamableFoxes.foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId());
|
|
||||||
|
|
||||||
// Indicate that it was tamed
|
|
||||||
player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
|
||||||
} else {
|
|
||||||
player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!player.getGameMode().equals(GameMode.CREATIVE)) { // Remove chicken from inventory unless in creative
|
|
||||||
player.getInventory().getItemInMainHand().setAmount(player.getInventory().getItemInMainHand().getAmount() - 1);
|
|
||||||
}
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make it so when player sleeps, fox does too
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (foxUUIDs.containsValue(player.getUniqueId())) {
|
|
||||||
List<UUID> listOfUUIDs = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Map.Entry<UUID, UUID> entry : foxUUIDs.entrySet()) {
|
|
||||||
if (entry.getValue().equals(player.getUniqueId())) {
|
|
||||||
listOfUUIDs.add(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (UUID uuid : listOfUUIDs) {
|
|
||||||
TamableFox tamableFox = ((TamableFox)((CraftFox)getEntityByUniqueId(uuid)).getHandle());
|
|
||||||
if (player.getWorld().getTime() > 12541 && player.getWorld().getTime() < 23460) {
|
|
||||||
tamableFox.setSleeping(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wake the fox up when the player wakes up
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (foxUUIDs.containsValue(player.getUniqueId())) {
|
|
||||||
List<UUID> listOfUUIDs = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Map.Entry<UUID, UUID> entry : foxUUIDs.entrySet()) {
|
|
||||||
if (entry.getValue().equals(event.getPlayer().getUniqueId())) {
|
|
||||||
listOfUUIDs.add(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (UUID uuid : listOfUUIDs) {
|
|
||||||
TamableFox tamableFox = ((TamableFox)((CraftFox)getEntityByUniqueId(uuid)).getHandle());
|
|
||||||
tamableFox.setSleeping(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace all spawned foxes with the TamableFox
|
|
||||||
@EventHandler
|
|
||||||
public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
|
|
||||||
Entity entity = event.getEntity();
|
|
||||||
if(entity instanceof Fox && !(isTamableFox(entity))) {
|
|
||||||
EntityFox.Type foxType = ((EntityFox) ((CraftEntity)entity).getHandle()).getFoxType();
|
|
||||||
spawnTamableFox(entity.getLocation(), foxType);
|
|
||||||
//Bukkit.getConsoleSender().sendMessage(Reference.CHAT_PREFIX + "Replaced vanilla fox");
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Entity getEntityByUniqueId(UUID uniqueId){
|
|
||||||
for (org.bukkit.World world : Bukkit.getWorlds()) {
|
|
||||||
for (org.bukkit.Chunk chunk : world.getLoadedChunks()) {
|
|
||||||
for (Entity entity : chunk.getEntities()) {
|
|
||||||
if (entity.getUniqueId().equals(uniqueId)) {
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onEntityDeathEvent (EntityDeathEvent event) {
|
|
||||||
Entity entity = event.getEntity();
|
|
||||||
if (isTamableFox(entity)) {
|
|
||||||
foxUUIDs.remove(entity.getUniqueId());
|
|
||||||
if (fileManager.getConfig("foxes.yml").get().getConfigurationSection("Foxes").contains(entity.getUniqueId() + "")) {
|
|
||||||
fileManager.getConfig("foxes.yml").get().set("Foxes." + entity.getUniqueId(), null);
|
|
||||||
fileManager.saveConfig("foxes.yml");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTamableFox(Entity entity) {
|
|
||||||
return ((CraftEntity)entity).getHandle().getClass().getName().contains("TamableFox") || ((CraftEntity)entity).getHandle() instanceof TamableFox;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveResource(@NotNull String resourcePath, boolean replace) {
|
|
||||||
File file = getFile();
|
|
||||||
if (resourcePath != null && !resourcePath.equals("")) {
|
|
||||||
resourcePath = resourcePath.replace('\\', '/');
|
|
||||||
InputStream in = this.getResource(resourcePath);
|
|
||||||
if (in == null) {
|
|
||||||
throw new IllegalArgumentException("The embedded resource '" + resourcePath + "' cannot be found in " + file);
|
|
||||||
} else {
|
|
||||||
File outFile = new File(this.dataFolder, resourcePath);
|
|
||||||
int lastIndex = resourcePath.lastIndexOf(47);
|
|
||||||
File outDir = new File(this.dataFolder, resourcePath.substring(0, lastIndex >= 0 ? lastIndex : 0));
|
|
||||||
if (!outDir.exists()) {
|
|
||||||
outDir.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
//if (outFile.exists() && !replace) {
|
|
||||||
if (!outFile.exists() && replace) {
|
|
||||||
//this.logger.log(Level.WARNING, "Could not save " + outFile.getName() + " to " + outFile + " because " + outFile.getName() + " already exists.");
|
|
||||||
OutputStream out = new FileOutputStream(outFile);
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
|
|
||||||
int len;
|
|
||||||
while((len = in.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
} /*else {
|
|
||||||
|
|
||||||
}*/
|
|
||||||
} catch (IOException var10) {
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Could not save " + outFile.getName() + " to " + outFile, var10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.Utils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
public class FileManager {
|
|
||||||
|
|
||||||
private final JavaPlugin plugin;
|
|
||||||
private HashMap<String, Config> configs = new HashMap<String, Config>();
|
|
||||||
|
|
||||||
public FileManager(JavaPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config getConfig(String name) {
|
|
||||||
if (!configs.containsKey(name))
|
|
||||||
configs.put(name, new Config(name));
|
|
||||||
|
|
||||||
return configs.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config saveConfig(String name) {
|
|
||||||
return getConfig(name).save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config reloadConfig(String name) {
|
|
||||||
return 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))
|
|
||||||
return this;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (config.getConfigurationSection("").getKeys(true).size() != 0)
|
|
||||||
config.save(this.file);
|
|
||||||
}
|
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public YamlConfiguration get() {
|
|
||||||
if (this.config == null)
|
|
||||||
reload();
|
|
||||||
|
|
||||||
return this.config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config saveDefaultConfig() {
|
|
||||||
file = new File(plugin.getDataFolder(), this.name);
|
|
||||||
|
|
||||||
plugin.saveResource(this.name, false);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config reload() {
|
|
||||||
if (file == null)
|
|
||||||
this.file = new File(plugin.getDataFolder(), this.name);
|
|
||||||
|
|
||||||
this.config = YamlConfiguration.loadConfiguration(file);
|
|
||||||
|
|
||||||
Reader defConfigStream;
|
|
||||||
try {
|
|
||||||
defConfigStream = new InputStreamReader(plugin.getResource(this.name), "UTF8");
|
|
||||||
|
|
||||||
if (defConfigStream != null)
|
|
||||||
{
|
|
||||||
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
|
|
||||||
this.config.setDefaults(defConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException | NullPointerException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config copyDefaults(boolean force) {
|
|
||||||
get().options().copyDefaults(force);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config set(String key, Object value) {
|
|
||||||
get().set(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object get(String key) {
|
|
||||||
return get().get(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package net.seanomik.tamablefoxes.Utils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
public static <K, V> List<K> getAllKeysForValue(Map<K, V> mapOfWords, V value) {
|
|
||||||
List<K> listOfKeys = null;
|
|
||||||
|
|
||||||
if(mapOfWords.containsValue(value)) {
|
|
||||||
listOfKeys = new ArrayList<>();
|
|
||||||
|
|
||||||
// Iterate over each entry of map using entrySet
|
|
||||||
for (Map.Entry<K, V> entry : mapOfWords.entrySet()) {
|
|
||||||
// Check if value matches with given value
|
|
||||||
if (entry.getValue().equals(value))
|
|
||||||
{
|
|
||||||
// Store the key from entry to the list
|
|
||||||
listOfKeys.add(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Return the list of keys whose value matches with given value.
|
|
||||||
return listOfKeys;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
package net.seanomilk.tamablefoxes;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_15_R1.*;
|
||||||
|
import net.seanomilk.tamablefoxes.pathfinding.*;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||||
|
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.BukkitTask;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class EntityTamableFox extends EntityFox {
|
||||||
|
|
||||||
|
private static Fox thisFox;
|
||||||
|
private final TamableFoxes plugin;
|
||||||
|
|
||||||
|
private boolean isTamed;
|
||||||
|
private EntityLiving owner;
|
||||||
|
private String chosenName;
|
||||||
|
private boolean sit = false;
|
||||||
|
private BukkitTask sittingRunnable;
|
||||||
|
|
||||||
|
private FoxPathfindGoalSit goalSit;
|
||||||
|
private PathfinderGoalNearestAttackableTarget goalAttack;
|
||||||
|
|
||||||
|
|
||||||
|
public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) {
|
||||||
|
super(EntityTypes.FOX, world);
|
||||||
|
this.plugin = plugin;
|
||||||
|
thisFox = (Fox) this.getBukkitEntity();
|
||||||
|
plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initPathfinder() {
|
||||||
|
this.goalSit = new FoxPathfindGoalSit(this);
|
||||||
|
this.goalSelector.a(1, new FoxPathfindGoalFloat(this));
|
||||||
|
this.goalSelector.a(2, this.goalSit);
|
||||||
|
this.goalSelector.a(3, new FoxPathfindGoalMeleeAttack(this, 1.2000000476837158D, true));
|
||||||
|
this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D,
|
||||||
|
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,
|
||||||
|
entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit));
|
||||||
|
|
||||||
|
if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) {
|
||||||
|
this.targetSelector.a(4, goalAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initAttributes() {
|
||||||
|
this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
|
||||||
|
this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
|
||||||
|
this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
|
||||||
|
this.getAttributeMap().b(GenericAttributes.ARMOR);
|
||||||
|
this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
|
||||||
|
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
|
||||||
|
this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
|
||||||
|
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityFox createChild(EntityAgeable entityageable) {
|
||||||
|
WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle();
|
||||||
|
Location location = entityageable.getBukkitEntity().getLocation();
|
||||||
|
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) {
|
||||||
|
ItemStack itemstack = entityitem.getItemStack();
|
||||||
|
if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem,
|
||||||
|
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) {
|
||||||
|
this.isTamed = tamed;
|
||||||
|
// remove attack goal if now tamed
|
||||||
|
if (isTamed && plugin.isTamedAttackRabbitChicken())
|
||||||
|
this.targetSelector.a(goalAttack);
|
||||||
|
else this.targetSelector.a(4, goalAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChosenName() {
|
||||||
|
return chosenName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChosenName(String chosenName) {
|
||||||
|
this.chosenName = chosenName;
|
||||||
|
updateFoxVisual();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLiving getOwner() {
|
||||||
|
return this.owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(EntityLiving owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".owner", owner.getUniqueIDString()).save();
|
||||||
|
updateFoxVisual();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean toggleSitting() {
|
||||||
|
this.sit = !this.sit;
|
||||||
|
updateFoxVisual();
|
||||||
|
return this.sit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateFox() {
|
||||||
|
updateFoxVisual();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler,
|
||||||
|
EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) {
|
||||||
|
BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
|
||||||
|
Type entityfox_type = Type.a(biomebase);
|
||||||
|
boolean flag = false;
|
||||||
|
if (groupdataentity instanceof i) {
|
||||||
|
entityfox_type = ((i) groupdataentity).a;
|
||||||
|
if (((i) groupdataentity).a() >= 2) {
|
||||||
|
flag = true;
|
||||||
|
} else {
|
||||||
|
((i) groupdataentity).b();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupdataentity = new i(entityfox_type);
|
||||||
|
((i) groupdataentity).b();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setFoxType(entityfox_type);
|
||||||
|
if (flag) {
|
||||||
|
this.setAgeRaw(-24000);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initPathfinder();
|
||||||
|
this.a(difficultydamagescaler);
|
||||||
|
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus",
|
||||||
|
this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
|
||||||
|
if (this.random.nextFloat() < 0.05F) {
|
||||||
|
this.p(true);
|
||||||
|
} else {
|
||||||
|
this.p(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,509 @@
|
||||||
|
package net.seanomilk.tamablefoxes;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.mojang.datafixers.DataFixUtils;
|
||||||
|
import com.mojang.datafixers.types.Type;
|
||||||
|
import net.seanomilk.tamablefoxes.command.CommandSpawnTamableFox;
|
||||||
|
import net.seanomilk.tamablefoxes.io.FileManager;
|
||||||
|
import net.minecraft.server.v1_15_R1.*;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.World;
|
||||||
|
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.CraftFox;
|
||||||
|
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.Fox;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
|
import org.bukkit.event.player.*;
|
||||||
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class TamableFoxes extends JavaPlugin implements Listener {
|
||||||
|
|
||||||
|
public static final String ITEM_INSPECTOR_LORE = ChatColor.BLUE + "Tamable Fox Inspector";
|
||||||
|
public static final String TAG_TAME_FOX = "tameablefox";
|
||||||
|
|
||||||
|
private FileManager fileManager;
|
||||||
|
|
||||||
|
private Map<UUID, UUID> foxUUIDs;
|
||||||
|
private EntityTypes customType;
|
||||||
|
|
||||||
|
private boolean isOnLoad = true;
|
||||||
|
|
||||||
|
private Map<UUID, Entity> lookupCache;
|
||||||
|
|
||||||
|
private FileManager.Config config, configFoxes;
|
||||||
|
|
||||||
|
private Map<Player, UUID> waitingName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
fileManager = new FileManager(this);
|
||||||
|
this.config = fileManager.getConfig("config.yml");
|
||||||
|
this.config.copyDefaults(true).save();
|
||||||
|
this.configFoxes = fileManager.getConfig("foxes.yml");
|
||||||
|
this.configFoxes.copyDefaults(true).save();
|
||||||
|
|
||||||
|
this.getServer().getPluginManager().registerEvents(this, this);
|
||||||
|
this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this));
|
||||||
|
|
||||||
|
this.foxUUIDs = Maps.newHashMap();
|
||||||
|
this.lookupCache = Maps.newHashMap();
|
||||||
|
this.waitingName = Maps.newHashMap();
|
||||||
|
|
||||||
|
final Map<String, Type<?>> types = (Map<String, Type<?>>) DataConverterRegistry.a()
|
||||||
|
.getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
|
||||||
|
.findChoiceType(DataConverterTypes.ENTITY).types();
|
||||||
|
types.put("minecraft:" + TAG_TAME_FOX, types.get("minecraft:fox"));
|
||||||
|
|
||||||
|
EntityTypes.a<net.minecraft.server.v1_15_R1.Entity> a = EntityTypes.a.a((entityTypes, world) ->
|
||||||
|
new EntityTamableFox(this, entityTypes, world), EnumCreatureType.AMBIENT);
|
||||||
|
customType = IRegistry.a(IRegistry.ENTITY_TYPE, "tameablefox", a.a("tameablefox"));
|
||||||
|
|
||||||
|
this.replaceFoxesOnLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replaceFoxesOnLoad() {
|
||||||
|
int amountReplaced = 0;
|
||||||
|
|
||||||
|
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();
|
||||||
|
if (entityMouthItem.getType() != Material.AIR) {
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
|
||||||
|
} 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();
|
||||||
|
if (entityMouthItem.getType() != Material.AIR) {
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
|
||||||
|
} else {
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.remove();
|
||||||
|
++amountReplaced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configFoxes.save();
|
||||||
|
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();
|
||||||
|
net.minecraft.server.v1_15_R1.Entity spawnedEntity = customType.b(world, null, null, null,
|
||||||
|
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
|
||||||
|
|
||||||
|
world.addEntity(spawnedEntity);
|
||||||
|
EntityFox fox = (EntityFox) spawnedEntity;
|
||||||
|
fox.setFoxType(type);
|
||||||
|
|
||||||
|
configFoxes.get().set("Foxes." + spawnedEntity.getUniqueID() + ".owner", "none");
|
||||||
|
fileManager.saveConfig("foxes.yml");
|
||||||
|
return fox;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
|
if (isOnLoad)
|
||||||
|
return;
|
||||||
|
Chunk chunk = event.getChunk();
|
||||||
|
Entity[] entities = chunk.getEntities();
|
||||||
|
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (entity instanceof Fox && !this.isTamableFox(entity)) {
|
||||||
|
EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
|
||||||
|
final YamlConfiguration configuration = configFoxes.get();
|
||||||
|
// if has data
|
||||||
|
if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
|
||||||
|
String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner", "none");
|
||||||
|
|
||||||
|
// if has owner
|
||||||
|
if (!owner.equals("none")) {
|
||||||
|
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
|
||||||
|
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
|
||||||
|
|
||||||
|
// set name
|
||||||
|
if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
|
||||||
|
String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
|
||||||
|
|
||||||
|
configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
|
||||||
|
tamableFox.setChosenName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove old data
|
||||||
|
configuration.set("Foxes." + entity.getUniqueId(), null);
|
||||||
|
|
||||||
|
tamableFox.setTamed(true);
|
||||||
|
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
|
||||||
|
tamableFox.updateFox();
|
||||||
|
tamableFox.setAge(((CraftFox) entity).getAge());
|
||||||
|
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
|
||||||
|
if (entityMouthItem.getType() != Material.AIR) {
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
|
||||||
|
} 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();
|
||||||
|
if (entityMouthItem.getType() != Material.AIR) {
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
|
||||||
|
} else {
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
getFoxesOf(player).forEach(uuid -> {
|
||||||
|
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) this.getEntityByUniqueId(uuid)).getHandle();
|
||||||
|
tamableFox.setOwner(((CraftPlayer) player).getHandle());
|
||||||
|
tamableFox.setTamed(true);
|
||||||
|
foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
|
||||||
|
Entity entity = event.getRightClicked();
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
if (event.getHand() != EquipmentSlot.HAND)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final ItemStack playerHand = player.getInventory().getItemInMainHand();
|
||||||
|
ItemMeta itemMeta = playerHand.getItemMeta();
|
||||||
|
|
||||||
|
if (itemMeta != null && playerHand.getType() == Material.REDSTONE_TORCH
|
||||||
|
&& itemMeta.hasLore() && itemMeta.getLore().contains(ITEM_INSPECTOR_LORE)) {
|
||||||
|
List<String> lore;
|
||||||
|
|
||||||
|
if (!this.isTamableFox(entity)) {
|
||||||
|
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
|
||||||
|
"UUID: " + entity.getUniqueId(),
|
||||||
|
"Entity ID: " + entity.getEntityId());
|
||||||
|
} else {
|
||||||
|
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
|
||||||
|
|
||||||
|
if (tamableFox.getOwner() == null) {
|
||||||
|
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
|
||||||
|
"UUID: " + entity.getUniqueId(),
|
||||||
|
"Entity ID: " + entity.getEntityId(),
|
||||||
|
"Tamable",
|
||||||
|
"Owner: None");
|
||||||
|
} else {
|
||||||
|
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
|
||||||
|
"UUID: " + entity.getUniqueId(),
|
||||||
|
"Entity ID: " + entity.getEntityId(),
|
||||||
|
"Tamable",
|
||||||
|
"Owner: " + 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();
|
||||||
|
|
||||||
|
if (tamableFox.isTamed() && tamableFox.getOwner() != null &&
|
||||||
|
playerHand.getType() != Material.SWEET_BERRIES) {
|
||||||
|
// if this fox is theirs
|
||||||
|
if (foxUUIDs.get(entity.getUniqueId()).equals(player.getUniqueId())) {
|
||||||
|
if (player.isSneaking()) {
|
||||||
|
net.minecraft.server.v1_15_R1.ItemStack wolfHolding = 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);
|
||||||
|
playerItemInHandNMS.setCount(1);
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
|
||||||
|
playerHand.setAmount(playerHand.getAmount() - 1);
|
||||||
|
player.getInventory().setItemInMainHand(playerHand);
|
||||||
|
} else if (playerHand.getType() == Material.AIR) {
|
||||||
|
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
|
||||||
|
CraftItemStack.asBukkitCopy(wolfHolding));
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
|
||||||
|
} else {
|
||||||
|
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
|
||||||
|
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
|
||||||
|
CraftItemStack.asBukkitCopy(wolfHolding));
|
||||||
|
playerItemInHandNMS.setCount(1);
|
||||||
|
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
|
||||||
|
playerHand.setAmount(playerHand.getAmount() - 1);
|
||||||
|
player.getInventory().setItemInMainHand(playerHand);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tamableFox.toggleSitting();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
} else if (playerHand.getType() == Material.CHICKEN) {
|
||||||
|
if (Math.random() < 0.33D) {
|
||||||
|
tamableFox.setTamed(true);
|
||||||
|
tamableFox.setOwner(((CraftPlayer) player).getHandle());
|
||||||
|
foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId());
|
||||||
|
player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
||||||
|
|
||||||
|
// Name process
|
||||||
|
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.GRAY + "Type a name in chat");
|
||||||
|
waitingName.put(player, tamableFox.getUniqueID());
|
||||||
|
tamableFox.setChosenName("???");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.getGameMode().equals(GameMode.CREATIVE)) {
|
||||||
|
playerHand.setAmount(playerHand.getAmount() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChat(AsyncPlayerChatEvent event) {
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
|
||||||
|
final UUID foxUuid = waitingName.get(player);
|
||||||
|
if (foxUuid == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
final Entity entityFox = getEntityByUniqueId(foxUuid);
|
||||||
|
if (entityFox == null || entityFox.isDead()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "R.I.P Foxy :(");
|
||||||
|
waitingName.remove(player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entityFox).getHandle();
|
||||||
|
|
||||||
|
final String chosenName = ChatColor.translateAlternateColorCodes('&', event.getMessage().trim());
|
||||||
|
tamableFox.setChosenName(chosenName);
|
||||||
|
|
||||||
|
configFoxes.set("Foxes." + entityFox.getUniqueId() + ".name", chosenName).save();
|
||||||
|
|
||||||
|
player.sendMessage(chosenName + ChatColor.RESET + ChatColor.GREEN + " is perfect.");
|
||||||
|
waitingName.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
List<UUID> dogsToSleep = getFoxesOf(player);
|
||||||
|
|
||||||
|
for (UUID uuid : dogsToSleep) {
|
||||||
|
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
|
||||||
|
if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) {
|
||||||
|
tamableFox.setSleeping(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
final List<UUID> foxesOf = getFoxesOf(player);
|
||||||
|
|
||||||
|
for (UUID uuid : foxesOf) {
|
||||||
|
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
|
||||||
|
tamableFox.setSleeping(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity getEntityByUniqueId(UUID uniqueId) {
|
||||||
|
final Entity cacheEntity = lookupCache.get(uniqueId);
|
||||||
|
if (cacheEntity != null) {
|
||||||
|
if (cacheEntity.isDead())
|
||||||
|
lookupCache.remove(uniqueId);
|
||||||
|
else return cacheEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (World world : Bukkit.getWorlds()) {
|
||||||
|
for (Chunk loadedChunk : world.getLoadedChunks()) {
|
||||||
|
for (Entity entity : loadedChunk.getEntities()) {
|
||||||
|
if (entity.getUniqueId().equals(uniqueId)) {
|
||||||
|
this.lookupCache.put(uniqueId, entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onEntityDeathEvent(EntityDeathEvent event) {
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
if (!this.isTamableFox(entity))
|
||||||
|
return;
|
||||||
|
this.lookupCache.remove(entity.getUniqueId());
|
||||||
|
foxUUIDs.remove(entity.getUniqueId());
|
||||||
|
|
||||||
|
if (configFoxes.get().getConfigurationSection("Foxes").contains(entity.getUniqueId().toString())) {
|
||||||
|
configFoxes.get().set("Foxes." + entity.getUniqueId(), null);
|
||||||
|
fileManager.saveConfig("foxes.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 FileManager.Config getConfigFoxes() {
|
||||||
|
return configFoxes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityTypes getCustomType() {
|
||||||
|
return customType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<UUID, UUID> getFoxUUIDs() {
|
||||||
|
return foxUUIDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return ChatColor.translateAlternateColorCodes('&', (String) config.get("prefix"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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.no-attack-chicken-rabbit");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package net.seanomilk.tamablefoxes.command;
|
||||||
|
|
||||||
|
import net.seanomilk.tamablefoxes.TamableFoxes;
|
||||||
|
import net.minecraft.server.v1_15_R1.EntityFox;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CommandSpawnTamableFox implements CommandExecutor {
|
||||||
|
|
||||||
|
private final TamableFoxes plugin;
|
||||||
|
|
||||||
|
public CommandSpawnTamableFox(TamableFoxes plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
sender.sendMessage("Command can only be run from player state.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sender.hasPermission("tamablefoxes.spawntamablefox")) {
|
||||||
|
sender.sendMessage(ChatColor.RED + "You do not have the permission for this command.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = (Player) sender;
|
||||||
|
if (args.length != 0) {
|
||||||
|
switch (args[0]) {
|
||||||
|
case "red":
|
||||||
|
plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED);
|
||||||
|
player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.RED + "Red" + ChatColor.WHITE + " fox.");
|
||||||
|
break;
|
||||||
|
case "snow":
|
||||||
|
plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW);
|
||||||
|
player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a Snow fox.");
|
||||||
|
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 + "Given 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;
|
||||||
|
case "reload":
|
||||||
|
plugin.getMainConfig().reload();
|
||||||
|
plugin.getConfigFoxes().reload();
|
||||||
|
player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Reloaded.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | verbose | inspect | reload]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package net.seanomilk.tamablefoxes.io;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import net.seanomilk.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,25 +1,26 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
import net.seanomilk.tamablefoxes.EntityTamableFox;
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
import net.minecraft.server.v1_15_R1.*;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
|
||||||
import org.bukkit.event.entity.EntityTeleportEvent;
|
import org.bukkit.event.entity.EntityTeleportEvent;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
|
public class FoxPathfindGoalFollowOwner extends PathfinderGoal {
|
||||||
protected final TamableFox a;
|
|
||||||
private EntityLiving c;
|
protected final EntityTamableFox a;
|
||||||
protected final IWorldReader b;
|
protected final IWorldReader b;
|
||||||
private final double d;
|
private final double d;
|
||||||
private final NavigationAbstract e;
|
private final NavigationAbstract e;
|
||||||
private int f;
|
|
||||||
private final float g;
|
private final float g;
|
||||||
private final float h;
|
private final float h;
|
||||||
|
private EntityLiving c;
|
||||||
|
private int f;
|
||||||
private float i;
|
private float i;
|
||||||
|
|
||||||
public FoxPathfinderGoalFollowOwner(TamableFox tamableFox, double d0, float f, float f1) {
|
public FoxPathfindGoalFollowOwner(EntityTamableFox tamableFox, double d0, float f, float f1) {
|
||||||
this.a = tamableFox;
|
this.a = tamableFox;
|
||||||
this.b = tamableFox.world;
|
this.b = tamableFox.world;
|
||||||
this.d = d0;
|
this.d = d0;
|
||||||
|
@ -36,11 +37,11 @@ public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
|
||||||
EntityLiving entityliving = this.a.getOwner();
|
EntityLiving entityliving = this.a.getOwner();
|
||||||
if (entityliving == null) {
|
if (entityliving == null) {
|
||||||
return false;
|
return false;
|
||||||
} else if (entityliving instanceof EntityHuman && ((EntityHuman)entityliving).isSpectator()) {
|
} else if (entityliving instanceof EntityHuman && entityliving.isSpectator()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (this.a.isSitting()) {
|
} else if (this.a.isSitting()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (this.a.h(entityliving) < (double)(this.h * this.h)) {
|
} else if (this.a.h(entityliving) < (double) (this.h * this.h)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
this.c = entityliving;
|
this.c = entityliving;
|
||||||
|
@ -49,7 +50,7 @@ public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean b() {
|
public boolean b() {
|
||||||
return !this.e.n() && this.a.h(this.c) > (double)(this.g * this.g) && !this.a.isSitting();
|
return !this.e.n() && this.a.h(this.c) > (double) (this.g * this.g) && !this.a.isSitting();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void c() {
|
public void c() {
|
||||||
|
@ -65,19 +66,19 @@ public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void e() {
|
public void e() {
|
||||||
this.a.getControllerLook().a(this.c, 10.0F, (float)this.a.M());
|
this.a.getControllerLook().a(this.c, 10.0F, (float) this.a.dU());
|
||||||
if (!this.a.isSitting() && --this.f <= 0) {
|
if (!this.a.isSitting() && --this.f <= 0) {
|
||||||
this.f = 10;
|
this.f = 10;
|
||||||
if (!this.e.a(this.c, this.d) && !this.a.isLeashed() && !this.a.isPassenger() && this.a.h(this.c) >= 144.0D) {
|
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 i = MathHelper.floor(this.c.locX()) - 2;
|
||||||
int j = MathHelper.floor(this.c.locZ) - 2;
|
int j = MathHelper.floor(this.c.locZ()) - 2;
|
||||||
int k = MathHelper.floor(this.c.getBoundingBox().minY);
|
int k = MathHelper.floor(this.c.getBoundingBox().minY);
|
||||||
|
|
||||||
for(int l = 0; l <= 4; ++l) {
|
for (int l = 0; l <= 4; ++l) {
|
||||||
for(int i1 = 0; i1 <= 4; ++i1) {
|
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))) {
|
if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.a(new BlockPosition(i + l, k - 1, j + i1))) {
|
||||||
CraftEntity entity = this.a.getBukkitEntity();
|
CraftEntity entity = this.a.getBukkitEntity();
|
||||||
Location to = new Location(entity.getWorld(), (double)((float)(i + l) + 0.5F), (double)k, (double)((float)(j + i1) + 0.5F), this.a.yaw, this.a.pitch);
|
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);
|
EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to);
|
||||||
this.a.world.getServer().getPluginManager().callEvent(event);
|
this.a.world.getServer().getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
|
@ -100,4 +101,5 @@ public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
|
||||||
IBlockData iblockdata = this.b.getType(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));
|
return iblockdata.a(this.b, blockposition, this.a.getEntityType()) && this.b.isEmpty(blockposition.up()) && this.b.isEmpty(blockposition.up(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,36 +1,35 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
import net.seanomilk.tamablefoxes.EntityTamableFox;
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
import net.minecraft.server.v1_15_R1.*;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
|
||||||
import org.bukkit.event.entity.EntityTargetEvent;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
|
public class FoxPathfindGoalHurtByTarget 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 boolean b;
|
private boolean b;
|
||||||
private int c;
|
private int c;
|
||||||
private final Class<?>[] d;
|
|
||||||
private Class<?>[] i;
|
private Class<?>[] i;
|
||||||
|
|
||||||
public FoxPathfinderGoalHurtByTarget(TamableFox entitycreature, Class<?>... aclass) {
|
public FoxPathfindGoalHurtByTarget(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean a() {
|
public boolean a() {
|
||||||
int i = this.e.ct();
|
int i = this.e.cI();
|
||||||
EntityLiving entityliving = this.e.getLastDamager();
|
EntityLiving entityliving = this.e.getLastDamager();
|
||||||
if (i != this.c && entityliving != null) {
|
if (i != this.c && entityliving != null) {
|
||||||
Class[] aclass = this.d;
|
Class[] aclass = this.d;
|
||||||
int j = aclass.length;
|
int j = aclass.length;
|
||||||
|
|
||||||
for(int k = 0; k < j; ++k) {
|
for (Class<?> oclass : aclass) {
|
||||||
Class<?> oclass = aclass[k];
|
|
||||||
if (oclass.isAssignableFrom(entityliving.getClass())) {
|
if (oclass.isAssignableFrom(entityliving.getClass())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -42,19 +41,19 @@ public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FoxPathfinderGoalHurtByTarget a(Class<?>... aclass) {
|
public FoxPathfindGoalHurtByTarget a(Class<?>... aclass) {
|
||||||
this.b = true;
|
this.b = true;
|
||||||
this.i = aclass;
|
this.i = aclass;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void c() {
|
public void c() {
|
||||||
if ( !(e instanceof TamableFox && ((TamableFox) e).getOwner() == e.getLastDamager()) ) {
|
if (!(this.e instanceof EntityTamableFox) || ((EntityTamableFox) this.e).getOwner() != this.e.getLastDamager()) {
|
||||||
this.e.setGoalTarget(this.e.getLastDamager(), EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true);
|
this.e.setGoalTarget(this.e.getLastDamager(), TargetReason.TARGET_ATTACKED_ENTITY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.g = this.e.getGoalTarget();
|
this.g = this.e.getGoalTarget();
|
||||||
this.c = this.e.ct();
|
this.c = this.e.cI();
|
||||||
this.h = 300;
|
this.h = 300;
|
||||||
if (this.b) {
|
if (this.b) {
|
||||||
this.g();
|
this.g();
|
||||||
|
@ -65,10 +64,13 @@ public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
|
||||||
|
|
||||||
protected void g() {
|
protected void g() {
|
||||||
double d0 = this.k();
|
double d0 = this.k();
|
||||||
List<EntityInsentient> list = this.e.world.b(this.e.getClass(), (new AxisAlignedBB(this.e.locX, this.e.locY, this.e.locZ, this.e.locX + 1.0D, this.e.locY + 1.0D, this.e.locZ + 1.0D)).grow(d0, 10.0D, d0));
|
List<EntityInsentient> list = this.e.world.b(this.e.getClass(),
|
||||||
|
new AxisAlignedBB(this.e.locX(), this.e.locY(), this.e.locZ(), this.e.locX() + 1.0D, this.e.locY() + 1.0D, this.e.locZ() + 1.0D)
|
||||||
|
.grow(d0, 10.0D, d0));
|
||||||
Iterator iterator = list.iterator();
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
while(true) {
|
// kekw
|
||||||
|
while (true) {
|
||||||
EntityInsentient entityinsentient;
|
EntityInsentient entityinsentient;
|
||||||
boolean flag;
|
boolean flag;
|
||||||
do {
|
do {
|
||||||
|
@ -80,13 +82,10 @@ public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entityinsentient = (EntityInsentient)iterator.next();
|
entityinsentient = (EntityInsentient) iterator.next();
|
||||||
} while (this.e == entityinsentient);
|
} while (this.e == entityinsentient);
|
||||||
} while (entityinsentient.getGoalTarget() != null);
|
} while (entityinsentient.getGoalTarget() != null);
|
||||||
|
} while (this.e instanceof EntityTamableFox && ((EntityTamableFox) this.e).getOwner() != ((EntityTamableFox) entityinsentient).getOwner());
|
||||||
//Bukkit.broadcastMessage(String.valueOf(this.e instanceof TamableFox && ((TamableFox)this.e).getOwner() != ((TamableFox) entityinsentient).getOwner()));
|
|
||||||
|
|
||||||
} while (this.e instanceof TamableFox && ((TamableFox)this.e).getOwner() != ((TamableFox) entityinsentient).getOwner());
|
|
||||||
} while (entityinsentient.r(this.e.getLastDamager()));
|
} while (entityinsentient.r(this.e.getLastDamager()));
|
||||||
|
|
||||||
if (this.i == null) {
|
if (this.i == null) {
|
||||||
|
@ -97,24 +96,22 @@ public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
|
||||||
Class[] aclass = this.i;
|
Class[] aclass = this.i;
|
||||||
int i = aclass.length;
|
int i = aclass.length;
|
||||||
|
|
||||||
for(int j = 0; j < i; ++j) {
|
for (Class<?> oclass : aclass) {
|
||||||
Class<?> oclass = aclass[j];
|
|
||||||
if (entityinsentient.getClass() == oclass) {
|
if (entityinsentient.getClass() == oclass) {
|
||||||
flag = true;
|
flag = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(flag);
|
} while (flag);
|
||||||
|
|
||||||
this.a(entityinsentient, this.e.getLastDamager());
|
this.a(entityinsentient, this.e.getLastDamager());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) {
|
protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) {
|
||||||
if (entityinsentient instanceof TamableFox && ((TamableFox) entityinsentient).getOwner() == entityliving) {
|
if (!(entityinsentient instanceof EntityTamableFox) || ((EntityTamableFox) entityinsentient).getOwner() != entityliving) {
|
||||||
return;
|
entityinsentient.setGoalTarget(entityliving, TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityinsentient.setGoalTarget(entityliving, EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.tamablefoxes.EntityTamableFox;
|
||||||
|
import net.minecraft.server.v1_15_R1.EntityLiving;
|
||||||
|
import net.minecraft.server.v1_15_R1.PathfinderGoalMeleeAttack;
|
||||||
|
import net.minecraft.server.v1_15_R1.SoundEffects;
|
||||||
|
|
||||||
|
public class FoxPathfindGoalMeleeAttack extends PathfinderGoalMeleeAttack {
|
||||||
|
|
||||||
|
protected EntityTamableFox tamableFox;
|
||||||
|
|
||||||
|
public FoxPathfindGoalMeleeAttack(EntityTamableFox tamableFox, double d0, boolean flag) {
|
||||||
|
super(tamableFox, d0, flag);
|
||||||
|
this.tamableFox = tamableFox;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void a(EntityLiving entityliving, double d0) {
|
||||||
|
double d1 = this.a(entityliving);
|
||||||
|
if (d0 <= d1 && this.b <= 0) {
|
||||||
|
this.b = 20;
|
||||||
|
this.a.B(entityliving);
|
||||||
|
this.tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c() {
|
||||||
|
this.tamableFox.u(false);
|
||||||
|
super.c();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a() {
|
||||||
|
return !this.tamableFox.isSitting() && !this.tamableFox.isSleeping() && !this.tamableFox.isCrouching() && !this.tamableFox.es() && super.a();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,18 +1,20 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.*;
|
public class FoxPathfindGoalOwnerHurtByTarget extends PathfinderGoalTarget {
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoal.Type;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget {
|
private final EntityTamableFox a;
|
||||||
private final TamableFox a; // the Fox
|
|
||||||
private EntityLiving b;
|
private EntityLiving b;
|
||||||
private int c;
|
private int c;
|
||||||
|
|
||||||
public FoxPathfinderGoalOwnerHurtByTarget(TamableFox tamableFox) {
|
public FoxPathfindGoalOwnerHurtByTarget(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));
|
||||||
|
@ -25,8 +27,8 @@ public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
this.b = entityliving.getLastDamager();
|
this.b = entityliving.getLastDamager();
|
||||||
int i = entityliving.ct();
|
int i = entityliving.cI();
|
||||||
return i != this.c && this.a(this.b, PathfinderTargetCondition.a); //&& this.a.a(this.b, entityliving);
|
return i != this.c && this.a(this.b, PathfinderTargetCondition.a);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -37,9 +39,10 @@ public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget {
|
||||||
this.e.setGoalTarget(this.b, TargetReason.TARGET_ATTACKED_OWNER, true);
|
this.e.setGoalTarget(this.b, TargetReason.TARGET_ATTACKED_OWNER, true);
|
||||||
EntityLiving entityliving = this.a.getOwner();
|
EntityLiving entityliving = this.a.getOwner();
|
||||||
if (entityliving != null) {
|
if (entityliving != null) {
|
||||||
this.c = entityliving.ct();
|
this.c = entityliving.cI();
|
||||||
}
|
}
|
||||||
|
|
||||||
super.c();
|
super.c();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,18 +1,17 @@
|
||||||
package net.seanomik.tamablefoxes.CustomPathfinding;
|
package net.seanomilk.tamablefoxes.pathfinding;
|
||||||
|
|
||||||
|
import net.seanomilk.tamablefoxes.EntityTamableFox;
|
||||||
|
import net.minecraft.server.v1_15_R1.EntityLiving;
|
||||||
|
import net.minecraft.server.v1_15_R1.PathfinderGoal;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityLiving;
|
public class FoxPathfindGoalSit extends PathfinderGoal {
|
||||||
import net.minecraft.server.v1_14_R1.EntityTameableAnimal;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoal;
|
|
||||||
import net.minecraft.server.v1_14_R1.PathfinderGoal.Type;
|
|
||||||
import net.seanomik.tamablefoxes.TamableFox;
|
|
||||||
|
|
||||||
public class FoxPathfinderGoalSit extends PathfinderGoal {
|
private final EntityTamableFox entity;
|
||||||
private final TamableFox entity;
|
|
||||||
private boolean willSit;
|
private boolean willSit;
|
||||||
|
|
||||||
public FoxPathfinderGoalSit(TamableFox tamableFox) {
|
public FoxPathfindGoalSit(EntityTamableFox tamableFox) {
|
||||||
this.entity = tamableFox;
|
this.entity = tamableFox;
|
||||||
this.a(EnumSet.of(Type.JUMP, Type.MOVE));
|
this.a(EnumSet.of(Type.JUMP, Type.MOVE));
|
||||||
}
|
}
|
||||||
|
@ -24,13 +23,13 @@ public class FoxPathfinderGoalSit extends PathfinderGoal {
|
||||||
public boolean a() {
|
public boolean a() {
|
||||||
if (!this.entity.isTamed()) {
|
if (!this.entity.isTamed()) {
|
||||||
return this.willSit && this.entity.getGoalTarget() == null;
|
return this.willSit && this.entity.getGoalTarget() == null;
|
||||||
} else if (this.entity.av()) {
|
} else if (this.entity.az()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!this.entity.onGround) {
|
} else if (!this.entity.onGround) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
EntityLiving entityliving = this.entity.getOwner();
|
EntityLiving entityliving = this.entity.getOwner();
|
||||||
return entityliving == null ? true : (this.entity.h(entityliving) < 144.0D && entityliving.getLastDamager() != null ? false : this.willSit);
|
return entityliving == null || ((!(this.entity.h(entityliving) < 144.0D) || entityliving.getLastDamager() == null) && this.willSit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,4 +45,5 @@ public class FoxPathfinderGoalSit extends PathfinderGoal {
|
||||||
public void setSitting(boolean flag) {
|
public void setSitting(boolean flag) {
|
||||||
this.willSit = flag;
|
this.willSit = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1 +1,8 @@
|
||||||
|
# Config for Tamable Foxes modified for 1.15.1
|
||||||
|
prefix: '&c[Tamable Foxes] '
|
||||||
|
|
||||||
show-owner-in-fox-name: true
|
show-owner-in-fox-name: true
|
||||||
|
show-nametags: true
|
||||||
|
|
||||||
|
tamed-behavior:
|
||||||
|
no-attack-chicken-rabbit: true
|
|
@ -1,11 +1,13 @@
|
||||||
name: TamableFoxes
|
name: TamableFoxes
|
||||||
version: ${project.version}
|
version: 1.4-RELEASE
|
||||||
main: net.seanomik.tamablefoxes.TamableFoxes
|
main: net.seanomilk.tamablefoxes.TamableFoxes
|
||||||
api-version: 1.14
|
api-version: 1.15
|
||||||
load: POSTWORLD
|
load: POSTWORLD
|
||||||
|
description: Modified version of TamableFoxes for 1.15.1.
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
spawntamablefox:
|
spawntamablefox:
|
||||||
aliases: [stf, spawntf]
|
aliases: [tamablefox, stf, spawntf]
|
||||||
usage: /spawntamablefox [type]
|
usage: /spawntamablefox [type]
|
||||||
description: Spawn a tamable fox at the standing location. Type can be snow or red, or left empty for a red.
|
description: Spawn a tamable fox at the standing location. Type can be snow or red, or left empty for a red.
|
||||||
permissions:
|
permissions:
|
||||||
|
|
Loading…
Reference in New Issue