parent
7b10885dc3
commit
de30d65fba
5
pom.xml
5
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<groupId>net.seanomik</groupId>
|
<groupId>net.seanomik</groupId>
|
||||||
<artifactId>tamablefoxes</artifactId>
|
<artifactId>tamablefoxes</artifactId>
|
||||||
<version>1.7.6-SNAPSHOT</version>
|
<version>1.7.7-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Tamablefoxes</name>
|
<name>Tamablefoxes</name>
|
||||||
|
@ -44,7 +44,8 @@
|
||||||
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.16.1_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.16.1_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
||||||
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.16.1_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.16.1_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
||||||
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.16.2_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.16.2_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
||||||
<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.16.2_\plugins\TamableFoxes_v${project.version}.jar</outputFile>
|
<!--<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.16.2_\plugins\TamableFoxes_v${project.version}.jar</outputFile>-->
|
||||||
|
<outputFile>D:\Code\java\spigotPlugins\_TEST_SERVER_1.16.3_\plugins\TamableFoxes_v${project.version}.jar</outputFile>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package net.seanomik.tamablefoxes;
|
package net.seanomik.tamablefoxes;
|
||||||
|
|
||||||
|
import net.seanomik.tamablefoxes.io.Config;
|
||||||
|
import net.seanomik.tamablefoxes.io.sqlite.SQLiteHandler;
|
||||||
|
import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper;
|
||||||
import net.seanomik.tamablefoxes.versions.NMSInterface;
|
import net.seanomik.tamablefoxes.versions.NMSInterface;
|
||||||
import net.seanomik.tamablefoxes.versions.version_1_14_R1.NMSInterface_1_14_R1;
|
import net.seanomik.tamablefoxes.versions.version_1_14_R1.NMSInterface_1_14_R1;
|
||||||
import net.seanomik.tamablefoxes.versions.version_1_15_R1.NMSInterface_1_15_R1;
|
import net.seanomik.tamablefoxes.versions.version_1_15_R1.NMSInterface_1_15_R1;
|
||||||
|
@ -12,11 +15,9 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
// @TODO:
|
// @TODO:
|
||||||
|
|
||||||
/* @CHANGELOG (1.7-SNAPSHOT):
|
/* @CHANGELOG (1.7.7-SNAPSHOT):
|
||||||
* Update to Minecraft 1.16.1.
|
* Make foxes sleep on the bed with players, similar to what cats do.
|
||||||
* This jar file will also work with Minecraft 1.14.X, 1.15.X, and 1.16.X.
|
* Add a configurable option to set the maximum about of foxes a player can tame.
|
||||||
* Due to merging 1.14 support with all other versions, I also fixed SEVERAL issues that the versions for 1.14 had.
|
|
||||||
* Foxes now sleep with their owner once again.
|
|
||||||
*/
|
*/
|
||||||
public final class TamableFoxes extends JavaPlugin implements Listener {
|
public final class TamableFoxes extends JavaPlugin implements Listener {
|
||||||
private static TamableFoxes plugin;
|
private static TamableFoxes plugin;
|
||||||
|
@ -31,24 +32,34 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
|
||||||
|
|
||||||
LanguageConfig.getConfig().saveDefault();
|
LanguageConfig.getConfig().saveDefault();
|
||||||
|
|
||||||
|
// Verify server version
|
||||||
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||||
if (version.equals("v1_14_R1")) {
|
switch (version) {
|
||||||
nmsInterface = new NMSInterface_1_14_R1();
|
case "v1_14_R1":
|
||||||
} else if (version.equals("v1_15_R1")) {
|
nmsInterface = new NMSInterface_1_14_R1();
|
||||||
nmsInterface = new NMSInterface_1_15_R1();
|
break;
|
||||||
} else if (version.equals("v1_16_R1")) {
|
case "v1_15_R1":
|
||||||
nmsInterface = new NMSInterface_1_16_R1();
|
nmsInterface = new NMSInterface_1_15_R1();
|
||||||
} else if (version.equals("v1_16_R2")) {
|
break;
|
||||||
nmsInterface = new NMSInterface_1_16_R2();
|
case "v1_16_R1":
|
||||||
} else {
|
nmsInterface = new NMSInterface_1_16_R1();
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getUnsupportedMCVersionRegister());
|
break;
|
||||||
versionSupported = false;
|
case "v1_16_R2":
|
||||||
return;
|
nmsInterface = new NMSInterface_1_16_R2();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getUnsupportedMCVersionRegister());
|
||||||
|
versionSupported = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display starting message
|
// Display starting message then register entity.
|
||||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getMCVersionLoading(version));
|
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getMCVersionLoading(version));
|
||||||
nmsInterface.registerCustomFoxEntity();
|
nmsInterface.registerCustomFoxEntity();
|
||||||
|
|
||||||
|
if (Config.getMaxPlayerFoxTames() != 0) {
|
||||||
|
SQLiteHelper.getInstance().createTablesIfNotExist();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,7 +6,6 @@ import java.lang.reflect.Constructor;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
public static String getPrefix() {
|
public static String getPrefix() {
|
||||||
return ChatColor.RED + "[Tamable Foxes] ";
|
return ChatColor.RED + "[Tamable Foxes] ";
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,11 @@ public class Config {
|
||||||
|
|
||||||
// Check if the player can tame the fox.
|
// Check if the player can tame the fox.
|
||||||
public static boolean canPlayerTameFox(Player player) {
|
public static boolean canPlayerTameFox(Player player) {
|
||||||
return !config.getBoolean("enable-taming-permission") || (config.getBoolean("enable-taming-permission") && (player.hasPermission("tamablefoxes.tame") || player.isOp()));
|
return player.hasPermission("tamablefoxes.tame") || player.isOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxPlayerFoxTames() {
|
||||||
|
return config.getInt("max-fox-tames");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the plugin asks for a fox name after taming.
|
// Check if the plugin asks for a fox name after taming.
|
||||||
|
|
|
@ -132,6 +132,10 @@ public class LanguageConfig extends YamlConfiguration {
|
||||||
return getConfig().getString((Config.doesShowOwnerInFoxName()) ? "fox-name-format" : "fox-name-no-owner-name-format").replaceAll("%FOX_NAME%", foxName).replaceAll("%OWNER%", ownerName);
|
return getConfig().getString((Config.doesShowOwnerInFoxName()) ? "fox-name-format" : "fox-name-no-owner-name-format").replaceAll("%FOX_NAME%", foxName).replaceAll("%OWNER%", ownerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getFoxDoesntTrust() {
|
||||||
|
return getConfig().getString("fox-doesnt-trust");
|
||||||
|
}
|
||||||
|
|
||||||
public static String getNoPermMessage() {
|
public static String getNoPermMessage() {
|
||||||
return getConfig().getString("no-permission");
|
return getConfig().getString("no-permission");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package net.seanomik.tamablefoxes.io.sqlite;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class SQLiteHandler {
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
private static SQLiteHandler instance;
|
||||||
|
|
||||||
|
public static SQLiteHandler getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new SQLiteHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() {
|
||||||
|
try {
|
||||||
|
String baseLoc = Bukkit.getWorldContainer().toURI().toString().substring(6);
|
||||||
|
baseLoc = baseLoc.substring(0,baseLoc.length()-2);
|
||||||
|
|
||||||
|
String url = "jdbc:sqlite:" + baseLoc + "plugins/Tamablefoxes/userFoxAmount.db";
|
||||||
|
connection = DriverManager.getConnection(url);
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getConnection() {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeConnection() {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newConnection() {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
connect();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnection(Connection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package net.seanomik.tamablefoxes.io.sqlite;
|
||||||
|
|
||||||
|
import net.seanomik.tamablefoxes.TamableFoxes;
|
||||||
|
import net.seanomik.tamablefoxes.Utils;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SQLiteHelper {
|
||||||
|
public static Plugin plugin;
|
||||||
|
public static SQLiteHandler sqLiteHandler;
|
||||||
|
|
||||||
|
private static SQLiteHelper instance;
|
||||||
|
private static String userAmountTableName = "USER_FOX_AMT";
|
||||||
|
|
||||||
|
public static SQLiteHelper getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new SQLiteHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createTablesIfNotExist() {
|
||||||
|
sqLiteHandler = SQLiteHandler.getInstance();
|
||||||
|
|
||||||
|
String userFoxAmountQuery =
|
||||||
|
"CREATE TABLE IF NOT EXISTS `" + userAmountTableName + "` ( " +
|
||||||
|
"`UUID` TEXT PRIMARY KEY , " +
|
||||||
|
"`AMOUNT` INT NOT NULL);";
|
||||||
|
|
||||||
|
try {
|
||||||
|
sqLiteHandler.connect();
|
||||||
|
// Create previous bans table
|
||||||
|
DatabaseMetaData dbm = sqLiteHandler.getConnection().getMetaData();
|
||||||
|
ResultSet tables = dbm.getTables(null, null, userAmountTableName, null);
|
||||||
|
if (!tables.next()) {
|
||||||
|
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(userFoxAmountQuery);
|
||||||
|
statement.executeUpdate();
|
||||||
|
|
||||||
|
plugin.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + "Created previous player bans table!");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (sqLiteHandler.getConnection() != null) {
|
||||||
|
try {
|
||||||
|
sqLiteHandler.getConnection().close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerFoxAmount(UUID uuid) {
|
||||||
|
try {
|
||||||
|
sqLiteHandler.connect();
|
||||||
|
PreparedStatement statement = sqLiteHandler.getConnection()
|
||||||
|
.prepareStatement("SELECT * FROM " + userAmountTableName + " WHERE UUID=?");
|
||||||
|
statement.setString(1, uuid.toString());
|
||||||
|
ResultSet results = statement.executeQuery();
|
||||||
|
|
||||||
|
if (results.next()) {
|
||||||
|
return results.getInt("AMOUNT");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (sqLiteHandler.getConnection() != null) {
|
||||||
|
try {
|
||||||
|
sqLiteHandler.getConnection().close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayerFoxAmount(UUID uuid, int amt) {
|
||||||
|
try {
|
||||||
|
String query = "UPDATE " + userAmountTableName + " SET AMOUNT = AMOUNT + " + amt + " WHERE UUID = '" + uuid.toString() + "'";
|
||||||
|
if (getPlayerFoxAmount(uuid) == -1) {
|
||||||
|
query = "INSERT INTO " + userAmountTableName + " (UUID, AMOUNT) VALUES('" + uuid.toString() + "'," + amt + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
sqLiteHandler.connect();
|
||||||
|
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(query);
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (sqLiteHandler.getConnection() != null) {
|
||||||
|
try {
|
||||||
|
sqLiteHandler.getConnection().close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayerFoxAmount(UUID uuid, int amt) {
|
||||||
|
try {
|
||||||
|
String query = "UPDATE " + userAmountTableName + " SET AMOUNT = AMOUNT - " + amt + " WHERE UUID = '" + uuid.toString() + "'";
|
||||||
|
|
||||||
|
sqLiteHandler.connect();
|
||||||
|
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(query);
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (sqLiteHandler.getConnection() != null) {
|
||||||
|
try {
|
||||||
|
sqLiteHandler.getConnection().close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes;
|
||||||
import net.seanomik.tamablefoxes.Utils;
|
import net.seanomik.tamablefoxes.Utils;
|
||||||
import net.seanomik.tamablefoxes.io.Config;
|
import net.seanomik.tamablefoxes.io.Config;
|
||||||
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
||||||
|
import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper;
|
||||||
import net.seanomik.tamablefoxes.versions.version_1_14_R1.pathfinding.*;
|
import net.seanomik.tamablefoxes.versions.version_1_14_R1.pathfinding.*;
|
||||||
import net.wesjd.anvilgui.AnvilGUI;
|
import net.wesjd.anvilgui.AnvilGUI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -73,6 +74,7 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
||||||
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
||||||
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
||||||
|
this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this));
|
||||||
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
||||||
|
|
||||||
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
||||||
|
@ -311,6 +313,14 @@ public class EntityTamableFox extends EntityFox {
|
||||||
itemstack.subtract(1);
|
itemstack.subtract(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance();
|
||||||
|
int maxTameCount = Config.getMaxPlayerFoxTames();
|
||||||
|
if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) {
|
||||||
|
((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
||||||
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
||||||
this.tame(entityhuman);
|
this.tame(entityhuman);
|
||||||
|
@ -320,6 +330,10 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.setGoalTarget(null);
|
this.setGoalTarget(null);
|
||||||
this.goalSit.setSitting(true);
|
this.goalSit.setSitting(true);
|
||||||
|
|
||||||
|
if (maxTameCount > 0) {
|
||||||
|
sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
||||||
|
|
||||||
// Give player tamed message.
|
// Give player tamed message.
|
||||||
|
@ -477,6 +491,12 @@ public class EntityTamableFox extends EntityFox {
|
||||||
public void die(DamageSource damageSource) {
|
public void die(DamageSource damageSource) {
|
||||||
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
||||||
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage());
|
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage());
|
||||||
|
|
||||||
|
// Remove the amount of foxes the player has tamed if the limit is enabled.
|
||||||
|
if (Config.getMaxPlayerFoxTames() > 0) {
|
||||||
|
SQLiteHelper sqliteHelper = SQLiteHelper.getInstance();
|
||||||
|
sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.die(damageSource);
|
super.die(damageSource);
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
package net.seanomik.tamablefoxes.versions.version_1_14_R1.pathfinding;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_14_R1.*;
|
||||||
|
import net.seanomik.tamablefoxes.versions.version_1_14_R1.EntityTamableFox;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal {
|
||||||
|
private final EntityTamableFox a;
|
||||||
|
private EntityHuman b;
|
||||||
|
private BlockPosition c;
|
||||||
|
private int d;
|
||||||
|
|
||||||
|
public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) {
|
||||||
|
this.a = entityTamableFox;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a() {
|
||||||
|
if (!this.a.isTamed()) {
|
||||||
|
return false;
|
||||||
|
} else if (this.a.isSitting()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
EntityLiving entityliving = this.a.getOwner();
|
||||||
|
if (entityliving instanceof EntityHuman) {
|
||||||
|
this.b = (EntityHuman)entityliving;
|
||||||
|
if (!entityliving.isSleeping()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.a.h(this.b) > 100.0D) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPosition blockposition = new BlockPosition(this.b);
|
||||||
|
IBlockData iblockdata = this.a.world.getType(blockposition);
|
||||||
|
if (iblockdata.getBlock().a(TagsBlock.BEDS)) {
|
||||||
|
EnumDirection enumdirection = (EnumDirection)iblockdata.get(BlockBed.FACING);
|
||||||
|
this.c = new BlockPosition(blockposition.getX() - enumdirection.getAdjacentX(), blockposition.getY(), blockposition.getZ() - enumdirection.getAdjacentZ());
|
||||||
|
return !this.g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean g() {
|
||||||
|
List<EntityTamableFox> list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
EntityTamableFox entityTamableFox;
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
if (!iterator.hasNext()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entityTamableFox = (EntityTamableFox) iterator.next();
|
||||||
|
} while(entityTamableFox == this.a);
|
||||||
|
} while(!entityTamableFox.isSleeping());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean b() {
|
||||||
|
return this.a.isTamed() && !this.a.isSitting() && this.b != null && this.b.isSleeping() && this.c != null && !this.g();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c() {
|
||||||
|
if (this.c != null) {
|
||||||
|
this.a.getGoalSit().setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d() {
|
||||||
|
this.a.u(false);
|
||||||
|
float f = this.a.world.j(1.0F);
|
||||||
|
if (this.b.dJ() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) {
|
||||||
|
this.h();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.d = 0;
|
||||||
|
//this.a.v(false);
|
||||||
|
this.a.getNavigation().o();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void h() {
|
||||||
|
Random random = this.a.getRandom();
|
||||||
|
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||||
|
blockposition_mutableblockposition.a(this.a);
|
||||||
|
this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false);
|
||||||
|
blockposition_mutableblockposition.a(this.a);
|
||||||
|
LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.af);
|
||||||
|
LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random);
|
||||||
|
List<ItemStack> list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
while(iterator.hasNext()) {
|
||||||
|
ItemStack itemstack = (ItemStack)iterator.next();
|
||||||
|
this.a.world.addEntity(new EntityItem(this.a.world, (double)((float)blockposition_mutableblockposition.getX() - MathHelper.sin(this.a.aK * 0.017453292F)), (double)blockposition_mutableblockposition.getY(), (double)((float)blockposition_mutableblockposition.getZ() + MathHelper.cos(this.a.aK * 0.017453292F)), itemstack));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void e() {
|
||||||
|
if (this.b != null && this.c != null) {
|
||||||
|
this.a.getGoalSit().setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
if (this.a.h(this.b) < 2.5D) {
|
||||||
|
++this.d;
|
||||||
|
if (this.d > 16) {
|
||||||
|
this.a.setSleeping(true);
|
||||||
|
//this.a.v(false);
|
||||||
|
} else {
|
||||||
|
this.a.a(this.b, 45.0F, 45.0F);
|
||||||
|
//this.a.v(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.a.u(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes;
|
||||||
import net.seanomik.tamablefoxes.Utils;
|
import net.seanomik.tamablefoxes.Utils;
|
||||||
import net.seanomik.tamablefoxes.io.Config;
|
import net.seanomik.tamablefoxes.io.Config;
|
||||||
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
||||||
|
import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper;
|
||||||
import net.seanomik.tamablefoxes.versions.version_1_15_R1.pathfinding.*;
|
import net.seanomik.tamablefoxes.versions.version_1_15_R1.pathfinding.*;
|
||||||
import net.wesjd.anvilgui.AnvilGUI;
|
import net.wesjd.anvilgui.AnvilGUI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -16,7 +17,6 @@ import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
||||||
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
||||||
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
||||||
|
this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this));
|
||||||
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
||||||
|
|
||||||
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
||||||
|
@ -311,6 +312,14 @@ public class EntityTamableFox extends EntityFox {
|
||||||
itemstack.subtract(1);
|
itemstack.subtract(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance();
|
||||||
|
int maxTameCount = Config.getMaxPlayerFoxTames();
|
||||||
|
if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) {
|
||||||
|
((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
||||||
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
||||||
this.tame(entityhuman);
|
this.tame(entityhuman);
|
||||||
|
@ -320,6 +329,10 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.setGoalTarget(null);
|
this.setGoalTarget(null);
|
||||||
this.goalSit.setSitting(true);
|
this.goalSit.setSitting(true);
|
||||||
|
|
||||||
|
if (maxTameCount > 0) {
|
||||||
|
sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
||||||
|
|
||||||
// Give player tamed message.
|
// Give player tamed message.
|
||||||
|
@ -477,6 +490,12 @@ public class EntityTamableFox extends EntityFox {
|
||||||
public void die(DamageSource damageSource) {
|
public void die(DamageSource damageSource) {
|
||||||
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
||||||
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage());
|
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage());
|
||||||
|
|
||||||
|
// Remove the amount of foxes the player has tamed if the limit is enabled.
|
||||||
|
if (Config.getMaxPlayerFoxTames() > 0) {
|
||||||
|
SQLiteHelper sqliteHelper = SQLiteHelper.getInstance();
|
||||||
|
sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.die(damageSource);
|
super.die(damageSource);
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
package net.seanomik.tamablefoxes.versions.version_1_15_R1.pathfinding;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_15_R1.*;
|
||||||
|
import net.seanomik.tamablefoxes.versions.version_1_15_R1.EntityTamableFox;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal {
|
||||||
|
private final EntityTamableFox a;
|
||||||
|
private EntityHuman b;
|
||||||
|
private BlockPosition c;
|
||||||
|
private int d;
|
||||||
|
|
||||||
|
public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) {
|
||||||
|
this.a = entityTamableFox;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a() {
|
||||||
|
if (!this.a.isTamed()) {
|
||||||
|
return false;
|
||||||
|
} else if (this.a.isSitting()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
EntityLiving entityliving = this.a.getOwner();
|
||||||
|
if (entityliving instanceof EntityHuman) {
|
||||||
|
this.b = (EntityHuman)entityliving;
|
||||||
|
if (!entityliving.isSleeping()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.a.h(this.b) > 100.0D) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPosition blockposition = new BlockPosition(this.b);
|
||||||
|
IBlockData iblockdata = this.a.world.getType(blockposition);
|
||||||
|
if (iblockdata.getBlock().a(TagsBlock.BEDS)) {
|
||||||
|
EnumDirection enumdirection = (EnumDirection)iblockdata.get(BlockBed.FACING);
|
||||||
|
this.c = new BlockPosition(blockposition.getX() - enumdirection.getAdjacentX(), blockposition.getY(), blockposition.getZ() - enumdirection.getAdjacentZ());
|
||||||
|
return !this.g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean g() {
|
||||||
|
List<EntityTamableFox> list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
EntityTamableFox entityTamableFox;
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
if (!iterator.hasNext()) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entityTamableFox = (EntityTamableFox) iterator.next();
|
||||||
|
} while(entityTamableFox == this.a);
|
||||||
|
} while(!entityTamableFox.isSleeping());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean b() {
|
||||||
|
return this.a.isTamed() && !this.a.isSitting() && this.b != null && this.b.isSleeping() && this.c != null && !this.g();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c() {
|
||||||
|
if (this.c != null) {
|
||||||
|
this.a.setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d() {
|
||||||
|
this.a.u(false);
|
||||||
|
float f = this.a.world.f(1.0F);
|
||||||
|
if (this.b.ef() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) {
|
||||||
|
this.h();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.d = 0;
|
||||||
|
//this.a.v(false);
|
||||||
|
this.a.getNavigation().o();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void h() {
|
||||||
|
Random random = this.a.getRandom();
|
||||||
|
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||||
|
blockposition_mutableblockposition.a(this.a);
|
||||||
|
this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false);
|
||||||
|
blockposition_mutableblockposition.a(this.a);
|
||||||
|
LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.af);
|
||||||
|
LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random);
|
||||||
|
List<ItemStack> list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
while(iterator.hasNext()) {
|
||||||
|
ItemStack itemstack = (ItemStack)iterator.next();
|
||||||
|
this.a.world.addEntity(new EntityItem(this.a.world, (double)((float)blockposition_mutableblockposition.getX() - MathHelper.sin(this.a.aI * 0.017453292F)), (double)blockposition_mutableblockposition.getY(), (double)((float)blockposition_mutableblockposition.getZ() + MathHelper.cos(this.a.aI * 0.017453292F)), itemstack));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void e() {
|
||||||
|
if (this.b != null && this.c != null) {
|
||||||
|
this.a.setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
if (this.a.h(this.b) < 2.5D) {
|
||||||
|
++this.d;
|
||||||
|
if (this.d > 16) {
|
||||||
|
this.a.u(true);
|
||||||
|
//this.a.v(false);
|
||||||
|
} else {
|
||||||
|
this.a.a(this.b, 45.0F, 45.0F);
|
||||||
|
//this.a.v(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.a.u(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes;
|
||||||
import net.seanomik.tamablefoxes.Utils;
|
import net.seanomik.tamablefoxes.Utils;
|
||||||
import net.seanomik.tamablefoxes.io.Config;
|
import net.seanomik.tamablefoxes.io.Config;
|
||||||
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
||||||
|
import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper;
|
||||||
import net.seanomik.tamablefoxes.versions.version_1_16_R1.pathfinding.*;
|
import net.seanomik.tamablefoxes.versions.version_1_16_R1.pathfinding.*;
|
||||||
import net.wesjd.anvilgui.AnvilGUI;
|
import net.wesjd.anvilgui.AnvilGUI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -80,6 +81,7 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
||||||
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
||||||
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
||||||
|
this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this));
|
||||||
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
||||||
|
|
||||||
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
||||||
|
@ -313,6 +315,14 @@ public class EntityTamableFox extends EntityFox {
|
||||||
itemstack.subtract(1);
|
itemstack.subtract(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance();
|
||||||
|
int maxTameCount = Config.getMaxPlayerFoxTames();
|
||||||
|
if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) {
|
||||||
|
((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust());
|
||||||
|
|
||||||
|
return EnumInteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
||||||
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
||||||
this.tame(entityhuman);
|
this.tame(entityhuman);
|
||||||
|
@ -322,6 +332,10 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.setGoalTarget(null);
|
this.setGoalTarget(null);
|
||||||
this.goalSit.setSitting(true);
|
this.goalSit.setSitting(true);
|
||||||
|
|
||||||
|
if (maxTameCount > 0) {
|
||||||
|
sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
||||||
|
|
||||||
// Give player tamed message.
|
// Give player tamed message.
|
||||||
|
@ -480,6 +494,12 @@ public class EntityTamableFox extends EntityFox {
|
||||||
public void die(DamageSource damageSource) {
|
public void die(DamageSource damageSource) {
|
||||||
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
||||||
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID());
|
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID());
|
||||||
|
|
||||||
|
// Remove the amount of foxes the player has tamed if the limit is enabled.
|
||||||
|
if (Config.getMaxPlayerFoxTames() > 0) {
|
||||||
|
SQLiteHelper sqliteHelper = SQLiteHelper.getInstance();
|
||||||
|
sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.die(damageSource);
|
super.die(damageSource);
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
package net.seanomik.tamablefoxes.versions.version_1_16_R1.pathfinding;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_16_R1.*;
|
||||||
|
import net.seanomik.tamablefoxes.versions.version_1_16_R1.EntityTamableFox;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal {
|
||||||
|
private final EntityTamableFox a;
|
||||||
|
private EntityHuman b;
|
||||||
|
private BlockPosition c;
|
||||||
|
private int d;
|
||||||
|
|
||||||
|
public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) {
|
||||||
|
this.a = entityTamableFox;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a() {
|
||||||
|
if (this.a.isTamed()) {
|
||||||
|
EntityLiving entityliving = this.a.getOwner();
|
||||||
|
if (entityliving instanceof EntityHuman) {
|
||||||
|
this.b = (EntityHuman) entityliving;
|
||||||
|
if (!entityliving.isSleeping()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.a.h(this.b) > 100.0D) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPosition blockposition = this.b.getChunkCoordinates();
|
||||||
|
IBlockData iblockdata = this.a.world.getType(blockposition);
|
||||||
|
if (iblockdata.getBlock().a(TagsBlock.BEDS)) {
|
||||||
|
this.c = (BlockPosition) iblockdata.d(BlockBed.FACING).map((enumdirection) -> {
|
||||||
|
return blockposition.shift(enumdirection.opposite());
|
||||||
|
}).orElseGet(() -> {
|
||||||
|
return new BlockPosition(blockposition);
|
||||||
|
});
|
||||||
|
return !this.g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean g() {
|
||||||
|
List<EntityTamableFox> list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
EntityTamableFox entityTamableFox;
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
if (!iterator.hasNext()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entityTamableFox = (EntityTamableFox) iterator.next();
|
||||||
|
} while(entityTamableFox == this.a);
|
||||||
|
} while(!entityTamableFox.isSleeping());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean b() {
|
||||||
|
return this.a.isTamed() && this.b != null && this.b.isSleeping() && this.c != null && !this.g();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c() {
|
||||||
|
if (this.c != null) {
|
||||||
|
this.a.setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d() {
|
||||||
|
this.a.setSleeping(false);
|
||||||
|
float f = this.a.world.f(1.0F);
|
||||||
|
if (this.b.eB() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) {
|
||||||
|
this.h();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.d = 0;
|
||||||
|
//this.a.y(false);
|
||||||
|
this.a.getNavigation().o();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void h() {
|
||||||
|
Random random = this.a.getRandom();
|
||||||
|
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||||
|
blockposition_mutableblockposition.g(this.a.getChunkCoordinates());
|
||||||
|
this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false);
|
||||||
|
blockposition_mutableblockposition.g(this.a.getChunkCoordinates());
|
||||||
|
LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.ak);
|
||||||
|
net.minecraft.server.v1_16_R1.LootTableInfo.Builder loottableinfo_builder = (new net.minecraft.server.v1_16_R1.LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random);
|
||||||
|
List<ItemStack> list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
while(iterator.hasNext()) {
|
||||||
|
ItemStack itemstack = (ItemStack)iterator.next();
|
||||||
|
this.a.world.addEntity(new EntityItem(this.a.world, (double)blockposition_mutableblockposition.getX() - (double)MathHelper.sin(this.a.aH * 0.017453292F), (double)blockposition_mutableblockposition.getY(), (double)blockposition_mutableblockposition.getZ() + (double)MathHelper.cos(this.a.aH * 0.017453292F), itemstack));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void e() {
|
||||||
|
if (this.b != null && this.c != null) {
|
||||||
|
this.a.setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
if (this.a.h(this.b) < 2.5D) {
|
||||||
|
++this.d;
|
||||||
|
if (this.d > 16) {
|
||||||
|
this.a.setSleeping(true);
|
||||||
|
//this.a.y(false);
|
||||||
|
} else {
|
||||||
|
this.a.a(this.b, 45.0F, 45.0F);
|
||||||
|
//this.a.y(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.a.setSleeping(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes;
|
||||||
import net.seanomik.tamablefoxes.Utils;
|
import net.seanomik.tamablefoxes.Utils;
|
||||||
import net.seanomik.tamablefoxes.io.Config;
|
import net.seanomik.tamablefoxes.io.Config;
|
||||||
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
import net.seanomik.tamablefoxes.io.LanguageConfig;
|
||||||
|
import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper;
|
||||||
import net.seanomik.tamablefoxes.versions.version_1_16_R2.pathfinding.*;
|
import net.seanomik.tamablefoxes.versions.version_1_16_R2.pathfinding.*;
|
||||||
import net.wesjd.anvilgui.AnvilGUI;
|
import net.wesjd.anvilgui.AnvilGUI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -78,6 +79,7 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal
|
||||||
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal
|
||||||
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D));
|
||||||
|
this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this));
|
||||||
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal
|
||||||
|
|
||||||
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> {
|
||||||
|
@ -310,6 +312,14 @@ public class EntityTamableFox extends EntityFox {
|
||||||
itemstack.subtract(1);
|
itemstack.subtract(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance();
|
||||||
|
int maxTameCount = Config.getMaxPlayerFoxTames();
|
||||||
|
if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) {
|
||||||
|
((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust());
|
||||||
|
|
||||||
|
return EnumInteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
// 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not.
|
||||||
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
|
||||||
this.tame(entityhuman);
|
this.tame(entityhuman);
|
||||||
|
@ -319,6 +329,10 @@ public class EntityTamableFox extends EntityFox {
|
||||||
this.setGoalTarget(null);
|
this.setGoalTarget(null);
|
||||||
this.goalSit.setSitting(true);
|
this.goalSit.setSitting(true);
|
||||||
|
|
||||||
|
if (maxTameCount > 0) {
|
||||||
|
sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D);
|
||||||
|
|
||||||
// Give player tamed message.
|
// Give player tamed message.
|
||||||
|
@ -477,6 +491,12 @@ public class EntityTamableFox extends EntityFox {
|
||||||
public void die(DamageSource damageSource) {
|
public void die(DamageSource damageSource) {
|
||||||
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) {
|
||||||
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID());
|
this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID());
|
||||||
|
|
||||||
|
// Remove the amount of foxes the player has tamed if the limit is enabled.
|
||||||
|
if (Config.getMaxPlayerFoxTames() > 0) {
|
||||||
|
SQLiteHelper sqliteHelper = SQLiteHelper.getInstance();
|
||||||
|
sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.die(damageSource);
|
super.die(damageSource);
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
package net.seanomik.tamablefoxes.versions.version_1_16_R2.pathfinding;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_16_R2.*;
|
||||||
|
import net.seanomik.tamablefoxes.versions.version_1_16_R2.EntityTamableFox;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal {
|
||||||
|
private final EntityTamableFox a;
|
||||||
|
private EntityHuman b;
|
||||||
|
private BlockPosition c;
|
||||||
|
private int d;
|
||||||
|
|
||||||
|
public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) {
|
||||||
|
this.a = entityTamableFox;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a() {
|
||||||
|
if (this.a.isTamed()) {
|
||||||
|
EntityLiving entityliving = this.a.getOwner();
|
||||||
|
if (entityliving instanceof EntityHuman) {
|
||||||
|
this.b = (EntityHuman) entityliving;
|
||||||
|
if (!entityliving.isSleeping()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.a.h(this.b) > 100.0D) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPosition blockposition = this.b.getChunkCoordinates();
|
||||||
|
IBlockData iblockdata = this.a.world.getType(blockposition);
|
||||||
|
if (iblockdata.getBlock().a(TagsBlock.BEDS)) {
|
||||||
|
this.c = (BlockPosition) iblockdata.d(BlockBed.FACING).map((enumdirection) -> {
|
||||||
|
return blockposition.shift(enumdirection.opposite());
|
||||||
|
}).orElseGet(() -> {
|
||||||
|
return new BlockPosition(blockposition);
|
||||||
|
});
|
||||||
|
return !this.g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean g() {
|
||||||
|
List<EntityTamableFox> list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
EntityTamableFox entityTamableFox;
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
if (!iterator.hasNext()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entityTamableFox = (EntityTamableFox) iterator.next();
|
||||||
|
} while(entityTamableFox == this.a);
|
||||||
|
} while(!entityTamableFox.isSleeping());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean b() {
|
||||||
|
return this.a.isTamed() && this.b != null && this.b.isSleeping() && this.c != null && !this.g();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void c() {
|
||||||
|
if (this.c != null) {
|
||||||
|
this.a.setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d() {
|
||||||
|
this.a.setSleeping(false);
|
||||||
|
float f = this.a.world.f(1.0F);
|
||||||
|
if (this.b.eB() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) {
|
||||||
|
this.h();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.d = 0;
|
||||||
|
//this.a.y(false);
|
||||||
|
this.a.getNavigation().o();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void h() {
|
||||||
|
Random random = this.a.getRandom();
|
||||||
|
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||||
|
blockposition_mutableblockposition.g(this.a.getChunkCoordinates());
|
||||||
|
this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false);
|
||||||
|
blockposition_mutableblockposition.g(this.a.getChunkCoordinates());
|
||||||
|
LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.ak);
|
||||||
|
net.minecraft.server.v1_16_R2.LootTableInfo.Builder loottableinfo_builder = (new net.minecraft.server.v1_16_R2.LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.ORIGIN, this.a.getPositionVector()).set(LootContextParameters.THIS_ENTITY, this.a).a(random);
|
||||||
|
List<ItemStack> list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT));
|
||||||
|
Iterator iterator = list.iterator();
|
||||||
|
|
||||||
|
while(iterator.hasNext()) {
|
||||||
|
ItemStack itemstack = (ItemStack)iterator.next();
|
||||||
|
this.a.world.addEntity(new EntityItem(this.a.world, (double)blockposition_mutableblockposition.getX() - (double)MathHelper.sin(this.a.aA * 0.017453292F), (double)blockposition_mutableblockposition.getY(), (double)blockposition_mutableblockposition.getZ() + (double)MathHelper.cos(this.a.aA * 0.017453292F), itemstack));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void e() {
|
||||||
|
if (this.b != null && this.c != null) {
|
||||||
|
this.a.setSitting(false);
|
||||||
|
this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D);
|
||||||
|
if (this.a.h(this.b) < 2.5D) {
|
||||||
|
++this.d;
|
||||||
|
if (this.d > 16) {
|
||||||
|
this.a.setSleeping(true);
|
||||||
|
//this.a.y(false);
|
||||||
|
} else {
|
||||||
|
this.a.a(this.b, 45.0F, 45.0F);
|
||||||
|
//this.a.y(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.a.setSleeping(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
# Config for Tamable Foxes
|
# Config for Tamable Foxes
|
||||||
show-owner-in-fox-name: true
|
show-owner-in-fox-name: true
|
||||||
enable-taming-permission: true
|
|
||||||
ask-for-name-after-taming: true
|
ask-for-name-after-taming: true
|
||||||
|
max-fox-tames: 0
|
||||||
|
|
||||||
tamed-behavior:
|
tamed-behavior:
|
||||||
attack-wild-animals: true
|
attack-wild-animals: true
|
|
@ -10,6 +10,7 @@ taming-asking-for-name-message: "What do you want to call it?"
|
||||||
taming-chosen-name-perfect: "%NEW_FOX_NAME% is perfect!"
|
taming-chosen-name-perfect: "%NEW_FOX_NAME% is perfect!"
|
||||||
fox-name-format: "%FOX_NAME% (%OWNER%'s Fox)"
|
fox-name-format: "%FOX_NAME% (%OWNER%'s Fox)"
|
||||||
fox-name-no-owner-name-format: "%FOX_NAME%"
|
fox-name-no-owner-name-format: "%FOX_NAME%"
|
||||||
|
fox-doesnt-trust: "The fox doesn't trust you! You have too many foxes!"
|
||||||
|
|
||||||
no-permission: "You do not have the permission for this command."
|
no-permission: "You do not have the permission for this command."
|
||||||
only-run-by-player: "Command can only be run from player state!"
|
only-run-by-player: "Command can only be run from player state!"
|
||||||
|
|
Loading…
Reference in New Issue