From c7655236b1eea70ba6da83986742fde75cf28314 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 20 Jul 2023 18:33:47 -0400 Subject: [PATCH] Update for 1.20.1 --- 1_14_R1/pom.xml | 4 +- 1_15_R1/pom.xml | 4 +- 1_16_R1/pom.xml | 4 +- 1_16_R2/pom.xml | 4 +- 1_16_R3/pom.xml | 4 +- 1_17_1_R1/pom.xml | 4 +- .../version_1_17_1_R1/EntityTamableFox.java | 36 +- 1_17_R1/pom.xml | 4 +- .../version_1_17_R1/EntityTamableFox.java | 36 +- 1_18_1_R1/pom.xml | 4 +- .../version_1_18_1_R1/EntityTamableFox.java | 36 +- 1_18_R1/pom.xml | 4 +- .../version_1_18_R1/EntityTamableFox.java | 36 +- 1_18_R2/pom.xml | 4 +- .../version_1_18_R2/EntityTamableFox.java | 36 +- 1_19_1_R1/pom.xml | 4 +- .../version_1_19_1_R1/EntityTamableFox.java | 36 +- 1_19_2_R1/pom.xml | 4 +- .../version_1_19_2_R1/EntityTamableFox.java | 36 +- 1_19_3_R1/pom.xml | 4 +- .../version_1_19_3_R1/EntityTamableFox.java | 36 +- 1_19_R1/pom.xml | 4 +- .../version_1_19_R1/EntityTamableFox.java | 36 +- 1_19_R3/pom.xml | 4 +- .../version_1_19_R3/EntityTamableFox.java | 36 +- 1_20_R1/pom.xml | 84 +++ .../version_1_20_R1/EntityTamableFox.java | 599 ++++++++++++++++++ .../version_1_20_R1/NMSInterface_1_20_R1.java | 54 ++ .../FoxPathfinderGoalFollowOwner.java | 152 +++++ .../FoxPathfinderGoalHurtByTarget.java | 119 ++++ .../FoxPathfinderGoalOwnerHurtByTarget.java | 56 ++ .../FoxPathfinderGoalOwnerHurtTarget.java | 57 ++ .../pathfinding/FoxPathfinderGoalPanic.java | 21 + .../FoxPathfinderGoalSitWhenOrdered.java | 56 ++ .../FoxPathfinderGoalSleepWhenOrdered.java | 51 ++ .../FoxPathfinderGoalSleepWithOwner.java | 112 ++++ Plugin/pom.xml | 12 +- .../seanomik/tamablefoxes/TamableFoxes.java | 24 +- README.md | 24 +- Utility/pom.xml | 2 +- ci-pom.xml | 2 +- compileSpigotVersions.sh | 21 +- pom.xml | 4 +- 43 files changed, 1629 insertions(+), 241 deletions(-) create mode 100644 1_20_R1/pom.xml create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/EntityTamableFox.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/NMSInterface_1_20_R1.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalFollowOwner.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalHurtByTarget.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalPanic.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSitWhenOrdered.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWhenOrdered.java create mode 100644 1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWithOwner.java diff --git a/1_14_R1/pom.xml b/1_14_R1/pom.xml index aafc7aa..84cbfd6 100644 --- a/1_14_R1/pom.xml +++ b/1_14_R1/pom.xml @@ -7,7 +7,7 @@ tamablefoxes-parent net.seanomik - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes_v1_14_R1 @@ -39,7 +39,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_15_R1/pom.xml b/1_15_R1/pom.xml index 5a09ce0..dc1a453 100644 --- a/1_15_R1/pom.xml +++ b/1_15_R1/pom.xml @@ -7,7 +7,7 @@ tamablefoxes-parent net.seanomik - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes_v1_15_R1 @@ -39,7 +39,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_16_R1/pom.xml b/1_16_R1/pom.xml index a4fe6a8..89af322 100644 --- a/1_16_R1/pom.xml +++ b/1_16_R1/pom.xml @@ -7,7 +7,7 @@ tamablefoxes-parent net.seanomik - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes_v1_16_R1 @@ -39,7 +39,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_16_R2/pom.xml b/1_16_R2/pom.xml index 7c49ec9..d5d8cd2 100644 --- a/1_16_R2/pom.xml +++ b/1_16_R2/pom.xml @@ -7,7 +7,7 @@ tamablefoxes-parent net.seanomik - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes_v1_16_R2 @@ -39,7 +39,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_16_R3/pom.xml b/1_16_R3/pom.xml index 2a35457..da03e90 100644 --- a/1_16_R3/pom.xml +++ b/1_16_R3/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes_v1_16_R3 @@ -39,7 +39,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_17_1_R1/pom.xml b/1_17_1_R1/pom.xml index c37551f..a36650c 100644 --- a/1_17_1_R1/pom.xml +++ b/1_17_1_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_17_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_1_R1/EntityTamableFox.java b/1_17_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_1_R1/EntityTamableFox.java index 4957c03..6f4f45a 100644 --- a/1_17_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_1_R1/EntityTamableFox.java +++ b/1_17_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_1_R1/EntityTamableFox.java @@ -283,27 +283,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_17_R1/pom.xml b/1_17_R1/pom.xml index 5dd0c61..d34ba78 100644 --- a/1_17_R1/pom.xml +++ b/1_17_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_17_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_R1/EntityTamableFox.java b/1_17_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_R1/EntityTamableFox.java index 11f0a0d..1e1b124 100644 --- a/1_17_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_R1/EntityTamableFox.java +++ b/1_17_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_17_R1/EntityTamableFox.java @@ -280,27 +280,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_18_1_R1/pom.xml b/1_18_1_R1/pom.xml index f9afb09..bf1534b 100644 --- a/1_18_1_R1/pom.xml +++ b/1_18_1_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_18_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_1_R1/EntityTamableFox.java b/1_18_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_1_R1/EntityTamableFox.java index 3630dfb..c72c2f0 100644 --- a/1_18_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_1_R1/EntityTamableFox.java +++ b/1_18_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_1_R1/EntityTamableFox.java @@ -302,27 +302,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_18_R1/pom.xml b/1_18_R1/pom.xml index f5080e1..aeb6937 100644 --- a/1_18_R1/pom.xml +++ b/1_18_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_18_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R1/EntityTamableFox.java b/1_18_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R1/EntityTamableFox.java index 1c601c3..0d186ce 100644 --- a/1_18_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R1/EntityTamableFox.java +++ b/1_18_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R1/EntityTamableFox.java @@ -302,27 +302,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_18_R2/pom.xml b/1_18_R2/pom.xml index 990078c..d02892e 100644 --- a/1_18_R2/pom.xml +++ b/1_18_R2/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_18_R2/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R2/EntityTamableFox.java b/1_18_R2/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R2/EntityTamableFox.java index 69b4191..2df6363 100644 --- a/1_18_R2/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R2/EntityTamableFox.java +++ b/1_18_R2/src/main/java/net/seanomik/tamablefoxes/versions/version_1_18_R2/EntityTamableFox.java @@ -300,27 +300,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_19_1_R1/pom.xml b/1_19_1_R1/pom.xml index d6333d8..e4fb99d 100644 --- a/1_19_1_R1/pom.xml +++ b/1_19_1_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_19_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_1_R1/EntityTamableFox.java b/1_19_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_1_R1/EntityTamableFox.java index e1309fe..b297dd9 100644 --- a/1_19_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_1_R1/EntityTamableFox.java +++ b/1_19_1_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_1_R1/EntityTamableFox.java @@ -300,27 +300,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_19_2_R1/pom.xml b/1_19_2_R1/pom.xml index 42745ac..d4215d7 100644 --- a/1_19_2_R1/pom.xml +++ b/1_19_2_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_19_2_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_2_R1/EntityTamableFox.java b/1_19_2_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_2_R1/EntityTamableFox.java index 22a246d..dd0d0f2 100644 --- a/1_19_2_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_2_R1/EntityTamableFox.java +++ b/1_19_2_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_2_R1/EntityTamableFox.java @@ -300,27 +300,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_19_3_R1/pom.xml b/1_19_3_R1/pom.xml index 7187d0b..a9198eb 100644 --- a/1_19_3_R1/pom.xml +++ b/1_19_3_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_19_3_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_3_R1/EntityTamableFox.java b/1_19_3_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_3_R1/EntityTamableFox.java index 6d6d9d5..06f7ee0 100644 --- a/1_19_3_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_3_R1/EntityTamableFox.java +++ b/1_19_3_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_3_R1/EntityTamableFox.java @@ -300,27 +300,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_19_R1/pom.xml b/1_19_R1/pom.xml index 53f3e26..cf34afb 100644 --- a/1_19_R1/pom.xml +++ b/1_19_R1/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_19_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R1/EntityTamableFox.java b/1_19_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R1/EntityTamableFox.java index 78eb2b8..c92f1c3 100644 --- a/1_19_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R1/EntityTamableFox.java +++ b/1_19_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R1/EntityTamableFox.java @@ -300,27 +300,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_19_R3/pom.xml b/1_19_R3/pom.xml index 1270d98..cd5c8e5 100644 --- a/1_19_R3/pom.xml +++ b/1_19_R3/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT @@ -78,7 +78,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/1_19_R3/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R3/EntityTamableFox.java b/1_19_R3/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R3/EntityTamableFox.java index 7129323..c8ec640 100644 --- a/1_19_R3/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R3/EntityTamableFox.java +++ b/1_19_R3/src/main/java/net/seanomik/tamablefoxes/versions/version_1_19_R3/EntityTamableFox.java @@ -300,27 +300,29 @@ public class EntityTamableFox extends Fox { public void rename(org.bukkit.entity.Player player) { new AnvilGUI.Builder() - .onComplete((plr, input) -> { // Called when the inventory output slot is clicked - if (!input.equals("")) { - org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); - // This will auto format the name for config settings. - String foxName = LanguageConfig.getFoxNameFormat(input, player.getDisplayName()); + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); - tamableFox.setCustomName(foxName); - tamableFox.setCustomNameVisible(true); - if (!LanguageConfig.getTamingChosenPerfect(input).equalsIgnoreCase("disabled")) { - plr.sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(input)); - } + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } - //return AnvilGUI.Response.close(); - return Arrays.asList(AnvilGUI.ResponseAction.close()); - }) - .preventClose() - .text("Fox name") // Sets the text the GUI should start with - .plugin(Utils.tamableFoxesPlugin) // Set the plugin instance - .open(player); // Opens the GUI for the player provided + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); } @Override diff --git a/1_20_R1/pom.xml b/1_20_R1/pom.xml new file mode 100644 index 0000000..2ebb704 --- /dev/null +++ b/1_20_R1/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + + net.seanomik + tamablefoxes-parent + 2.2.10-SNAPSHOT + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:1.20.1-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:1.20.1-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:1.20.1-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:1.20.1-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + + tamablefoxes_v1_20_R1 + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + codemc-snapshots + https://repo.codemc.io/repository/maven-snapshots/ + + + + + + net.seanomik + tamablefoxes-util + ${project.parent.version} + provided + + + org.spigotmc + spigot + 1.20.1-R0.1-SNAPSHOT + remapped-mojang + provided + + + net.wesjd + anvilgui + 1.7.0-SNAPSHOT + + + diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/EntityTamableFox.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/EntityTamableFox.java new file mode 100644 index 0000000..a825492 --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/EntityTamableFox.java @@ -0,0 +1,599 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1; + +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.syncher.*; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.*; +import net.minecraft.world.entity.animal.horse.AbstractHorse; +import net.minecraft.world.entity.monster.Creeper; +import net.minecraft.world.entity.monster.Ghast; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.*; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.animal.Fox; +import net.minecraft.world.level.Level; +import net.minecraft.world.scores.Team; +import net.seanomik.tamablefoxes.util.Utils; +import net.seanomik.tamablefoxes.util.io.Config; +import net.seanomik.tamablefoxes.util.io.LanguageConfig; +import net.seanomik.tamablefoxes.util.io.sqlite.SQLiteHelper; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding.*; +import net.wesjd.anvilgui.AnvilGUI; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; + +import org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.event.entity.EntityRegainHealthEvent; + +import javax.annotation.Nullable; +import java.lang.reflect.Field; +import java.util.*; +import java.util.function.Predicate; + +public class EntityTamableFox extends Fox { + + protected static final EntityDataAccessor tamed; + protected static final EntityDataAccessor> ownerUUID; + + //private static final EntityDataAccessor bw; // DATA_FLAGS_ID + private static final Predicate AVOID_PLAYERS; // AVOID_PLAYERS + + static { + tamed = SynchedEntityData.defineId(EntityTamableFox.class, EntityDataSerializers.BOOLEAN); + ownerUUID = SynchedEntityData.defineId(EntityTamableFox.class, EntityDataSerializers.OPTIONAL_UUID); + + AVOID_PLAYERS = (entity) -> !entity.isCrouching();// && EntitySelector.test(entity); + } + + List untamedGoals; + private FoxPathfinderGoalSitWhenOrdered goalSitWhenOrdered; + private FoxPathfinderGoalSleepWhenOrdered goalSleepWhenOrdered; + + public EntityTamableFox(EntityType entitytype, Level world) { + super(entitytype, world); + + this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.33000001192092896D); // Set movement speed + if (isTamed()) { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(24.0D); + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(3.0D); + this.setHealth(this.getMaxHealth()); + } else { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(10.0D); + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(2.0D); + } + + this.setTamed(false); + } + + @Override + public void registerGoals() { + try { + this.goalSitWhenOrdered = new FoxPathfinderGoalSitWhenOrdered(this); + this.goalSelector.addGoal(1, goalSitWhenOrdered); + this.goalSleepWhenOrdered = new FoxPathfinderGoalSleepWhenOrdered(this); + this.goalSelector.addGoal(1, goalSleepWhenOrdered); + + // For reflection, we must use the non remapped names, since this is done at runtime + // and the user will be using a normal spigot jar. + + // Wild animal attacking + Field landTargetGoal = this.getClass().getSuperclass().getDeclaredField("ck"); // landTargetGoal + landTargetGoal.setAccessible(true); + landTargetGoal.set(this, new NearestAttackableTargetGoal(this, Animal.class, 10, false, false, (entityliving) -> { + return (!isTamed() || (Config.doesTamedAttackWildAnimals() && isTamed())) && (entityliving instanceof Chicken || entityliving instanceof Rabbit); + })); + + Field turtleEggTargetGoal = this.getClass().getSuperclass().getDeclaredField("cl"); // turtleEggTargetGoal + turtleEggTargetGoal.setAccessible(true); + turtleEggTargetGoal.set(this, new NearestAttackableTargetGoal(this, Turtle.class, 10, false, false, Turtle.BABY_ON_LAND_SELECTOR)); + + Field fishTargetGoal = this.getClass().getSuperclass().getDeclaredField("cm"); // fishTargetGoal + fishTargetGoal.setAccessible(true); + fishTargetGoal.set(this, new NearestAttackableTargetGoal(this, AbstractFish.class, 20, false, false, (entityliving) -> { + return (!isTamed() || (Config.doesTamedAttackWildAnimals() && isTamed())) && entityliving instanceof AbstractSchoolingFish; + })); + + this.goalSelector.addGoal(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal + this.goalSelector.addGoal(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal + this.goalSelector.addGoal(2, new FoxPathfinderGoalPanic(this, 2.2D)); + this.goalSelector.addGoal(2, new FoxPathfinderGoalSleepWithOwner(this)); + this.goalSelector.addGoal(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal + + this.goalSelector.addGoal(4, new AvoidEntityGoal(this, Player.class, 16.0F, 1.6D, 1.4D, (entityliving) -> { + return !isTamed() && AVOID_PLAYERS.test((LivingEntity) entityliving) && !this.isDefending(); + })); + this.goalSelector.addGoal(4, new AvoidEntityGoal(this, Wolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> { + return !((Wolf)entityliving).isTame() && !this.isDefending(); + })); + this.goalSelector.addGoal(4, new AvoidEntityGoal(this, PolarBear.class, 8.0F, 1.6D, 1.4D, (entityliving) -> { + return !this.isDefending(); + })); + + this.goalSelector.addGoal(5, getFoxInnerPathfinderGoal("u")); // StalkPreyGoal + this.goalSelector.addGoal(6, new FoxPounceGoal()); + this.goalSelector.addGoal(7, getFoxInnerPathfinderGoal("l", Arrays.asList(1.2000000476837158D, true), Arrays.asList(double.class, boolean.class))); // FoxMeleeAttackGoal + this.goalSelector.addGoal(8, getFoxInnerPathfinderGoal("h", Arrays.asList(this, 1.25D), Arrays.asList(Fox.class, double.class))); // FoxFollowParentGoal + //this.goalSelector.addGoal(8, new FoxPathfinderGoalSleepWithOwner(this)); + this.goalSelector.addGoal(9, new FoxPathfinderGoalFollowOwner(this, 1.3D, 10.0F, 2.0F, false)); + this.goalSelector.addGoal(10, new LeapAtTargetGoal(this, 0.4F)); + this.goalSelector.addGoal(11, new RandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(11, getFoxInnerPathfinderGoal("p")); // FoxSearchForItemsGoal + this.goalSelector.addGoal(12, getFoxInnerPathfinderGoal("j", Arrays.asList(this, Player.class, 24.0f), + Arrays.asList(Mob.class, Class.class, float.class))); // LookAtPlayer + + this.targetSelector.addGoal(1, new FoxPathfinderGoalOwnerHurtByTarget(this)); + this.targetSelector.addGoal(2, new FoxPathfinderGoalOwnerHurtTarget(this)); + this.targetSelector.addGoal(3, (new FoxPathfinderGoalHurtByTarget(this)).setAlertOthers(new Class[0])); + + // Assign all the untamed goals that will later be removed. + untamedGoals = new ArrayList<>(); + + // SleepGoal + Goal sleep = getFoxInnerPathfinderGoal("t"); + this.goalSelector.addGoal(7, sleep); + untamedGoals.add(sleep); + + // PerchAndSearchGoal + Goal perchAndSearch = getFoxInnerPathfinderGoal("r"); + this.goalSelector.addGoal(13, perchAndSearch); + untamedGoals.add(perchAndSearch); + + Goal eatBerries = new FoxEatBerriesGoal(1.2000000476837158D, 12, 2); + this.goalSelector.addGoal(11, eatBerries); + untamedGoals.add(eatBerries); // Maybe this should be configurable too? + + // SeekShelterGoal + Goal seekShelter = getFoxInnerPathfinderGoal("s", Arrays.asList(1.25D), Arrays.asList(double.class)); + this.goalSelector.addGoal(6, seekShelter); + untamedGoals.add(seekShelter); + + // FoxStrollThroughVillageGoal + Goal strollThroughVillage = getFoxInnerPathfinderGoal("q", Arrays.asList(32, 200), Arrays.asList(int.class, int.class)); + this.goalSelector.addGoal(9, strollThroughVillage); + untamedGoals.add(strollThroughVillage); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected EntityDataAccessor getDataFlagsId() throws NoSuchFieldException, IllegalAccessException { + Field dataFlagsField = Fox.class.getDeclaredField("bY"); // DATA_FLAGS_ID + dataFlagsField.setAccessible(true); + EntityDataAccessor dataFlagsId = (EntityDataAccessor) dataFlagsField.get(null); + dataFlagsField.setAccessible(false); + + return dataFlagsId; + } + + protected boolean getFlag(int i) { + try { + EntityDataAccessor dataFlagsId = getDataFlagsId(); + + return ((Byte)super.entityData.get(dataFlagsId) & i) != 0; + } catch (IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + + return false; + } + + protected void setFlag(int i, boolean flag) { + try { + EntityDataAccessor dataFlagsId = getDataFlagsId(); + + if (flag) { + this.entityData.set(dataFlagsId, (byte)((Byte)this.entityData.get(dataFlagsId) | i)); + } else { + this.entityData.set(dataFlagsId, (byte)((Byte)this.entityData.get(dataFlagsId) & ~i)); + } + } catch (IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + } + + public boolean isDefending() { + return getFlag(128); + } + + public void setDefending(boolean defending) { + setFlag(128, defending); + } + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(tamed, false); + this.entityData.define(ownerUUID, Optional.empty()); + } + + @Override + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); + if (this.getOwnerUUID() == null) { + compound.putUUID("OwnerUUID", new UUID(0L, 0L)); + } else { + compound.putUUID("OwnerUUID", this.getOwnerUUID()); + } + + compound.putBoolean("Sitting", this.goalSitWhenOrdered.isOrderedToSit()); + compound.putBoolean("Sleeping", this.goalSleepWhenOrdered.isOrderedToSleep()); + } + + @Override + public void readAdditionalSaveData(CompoundTag compound) { + super.readAdditionalSaveData(compound); + UUID ownerUuid = null; + + if (compound.contains("OwnerUUID")) { + try { + ownerUuid = compound.getUUID("OwnerUUID"); + } catch (IllegalArgumentException e) { + String uuidStr = compound.getString("OwnerUUID"); + if (!uuidStr.isEmpty()) { + ownerUuid = UUID.fromString(uuidStr); + } else { + ownerUuid = null; + } + } + } + + if (ownerUuid != null && !ownerUuid.equals(new UUID(0, 0))) { + this.setOwnerUUID(ownerUuid); + this.setTamed(true); + } else { + this.setTamed(false); + } + + if (this.goalSitWhenOrdered != null) { + this.goalSitWhenOrdered.setOrderedToSit(compound.getBoolean("Sitting")); + } + + if (this.goalSleepWhenOrdered != null) { + this.goalSleepWhenOrdered.setOrderedToSleep(compound.getBoolean("Sleeping")); + } + + if (!this.isTamed()) { + goalSitWhenOrdered.setOrderedToSit(false); + goalSleepWhenOrdered.setOrderedToSleep(false); + } + } + + public boolean isTamed() { + UUID ownerUuid = getOwnerUUID(); + return this.entityData.get(tamed) && (ownerUuid != null && !ownerUuid.equals(new UUID(0, 0))); + } + + public void setTamed(boolean tamed) { + this.entityData.set(EntityTamableFox.tamed, tamed); + this.reassessTameGoals(); + + if (tamed) { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(24.0D); + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(3.0D); + } else { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(10.0D); + this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(2.0D); + } + this.setHealth(this.getMaxHealth()); + } + + // Remove untamed goals if its tamed. + private void reassessTameGoals() { + if (!isTamed()) return; + + for (Goal untamedGoal : untamedGoals) { + this.goalSelector.removeGoal(untamedGoal); + } + } + + public void rename(org.bukkit.entity.Player player) { + new AnvilGUI.Builder() + .onClick((slot, stateSnapshot) -> { + String text = stateSnapshot.getText(); + if (slot == AnvilGUI.Slot.OUTPUT && !text.isEmpty()) { + org.bukkit.entity.Entity tamableFox = this.getBukkitEntity(); + + // This will auto format the name for config settings. + String foxName = LanguageConfig.getFoxNameFormat(text, player.getDisplayName()); + + tamableFox.setCustomName(foxName); + tamableFox.setCustomNameVisible(true); + if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamingChosenPerfect(text)); + } + } else if (!LanguageConfig.getTamingChosenPerfect(text).equalsIgnoreCase("disabled")) { + stateSnapshot.getPlayer().sendMessage(Config.getPrefix() + ChatColor.GRAY + "The fox was not named"); + } + + return Arrays.asList(AnvilGUI.ResponseAction.close()); + }) + .text("Fox name") + .title("Name your new friend!") + .plugin(Utils.tamableFoxesPlugin) + .open(player); + } + + @Override + public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) { + ItemStack itemstack = entityhuman.getItemInHand(enumhand); + Item item = itemstack.getItem(); + + if (itemstack.getItem() instanceof SpawnEggItem) { + return super.mobInteract(entityhuman, enumhand); + } else { + if (this.isTamed()) { + + // Heal the fox if its health is below the max. + if (item.isEdible() && item.getFoodProperties().isMeat() && this.getHealth() < this.getMaxHealth()) { + // Only remove the item from the player if they're in survival mode. + org.bukkit.entity.Player player = (org.bukkit.entity.Player) entityhuman.getBukkitEntity(); + if (player.getGameMode() != GameMode.CREATIVE ) { + itemstack.shrink(1); + } + + this.heal((float)item.getFoodProperties().getNutrition(), EntityRegainHealthEvent.RegainReason.EATING); + return InteractionResult.CONSUME; + } + + if (isOwnedBy(entityhuman) && enumhand == InteractionHand.MAIN_HAND) { + // This super method checks if the fox can breed or not. + InteractionResult flag = super.mobInteract(entityhuman, enumhand); + + // If the player is not sneaking and the fox cannot breed, then make the fox sit. + // @TODO: Do I need to use this.eQ() instead of flag != EnumInteractionResult.SUCCESS? + if (!entityhuman.isCrouching() && (flag != InteractionResult.SUCCESS || this.isBaby())) { + // Show the rename menu again when trying to use a nametag on the fox. + if (itemstack.getItem() instanceof NameTagItem) { + org.bukkit.entity.Player player = (org.bukkit.entity.Player) entityhuman.getBukkitEntity(); + rename(player); + return InteractionResult.PASS; + } + + this.goalSleepWhenOrdered.setOrderedToSleep(false); + this.goalSitWhenOrdered.setOrderedToSit(!this.isOrderedToSit()); + return InteractionResult.SUCCESS; + } else if (entityhuman.isCrouching()) { // Swap/Put/Take item from fox. + // Ignore buckets since they can be easily duplicated. + if (itemstack.getItem() instanceof BucketItem) { + return InteractionResult.PASS; + } + + // If the fox has something in its mouth and the player has something in its hand, empty it. + if (this.hasItemInSlot(EquipmentSlot.MAINHAND)) { + getBukkitEntity().getWorld().dropItem(getBukkitEntity().getLocation(), CraftItemStack.asBukkitCopy(this.getItemBySlot(EquipmentSlot.MAINHAND))); + this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.AIR), false); + } // Check if the player's hand is empty and if it is, make the fox sleep. + // The reason its here is to make sure that we don't take the item + // from its mouth and make it sleep in a single click. + else if (!entityhuman.hasItemInSlot(EquipmentSlot.MAINHAND)) { + this.goalSitWhenOrdered.setOrderedToSit(false); + this.goalSleepWhenOrdered.setOrderedToSleep(!this.goalSleepWhenOrdered.isOrderedToSleep()); + } + + // Run this task async to make sure to not slow the server down. + // This is needed due to the item being removed as soon as its put in the foxes mouth. + Bukkit.getScheduler().runTaskLaterAsynchronously(Utils.tamableFoxesPlugin, ()-> { + // Put item in mouth + if (entityhuman.hasItemInSlot(EquipmentSlot.MAINHAND)) { + ItemStack c = itemstack.copy(); + c.setCount(1); + + // Only remove the item from the player if they're in survival mode. + org.bukkit.entity.Player player = (org.bukkit.entity.Player) entityhuman.getBukkitEntity(); + if (player.getGameMode() != GameMode.CREATIVE ) { + itemstack.shrink(1); + } + + this.setItemSlot(EquipmentSlot.MAINHAND, c, false); + } + }, 1L); + + return InteractionResult.SUCCESS; + } + } + } else if (item == Items.CHICKEN) { + // Check if the player has permissions to tame the fox + if (Config.canPlayerTameFox((org.bukkit.entity.Player) entityhuman.getBukkitEntity())) { + // Only remove the item from the player if they're in survival mode. + org.bukkit.entity.Player player = (org.bukkit.entity.Player) entityhuman.getBukkitEntity(); + if (player.getGameMode() != GameMode.CREATIVE ) { + itemstack.shrink(1); + } + + SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance(Utils.tamableFoxesPlugin); + int maxTameCount = Config.getMaxPlayerFoxTames(); + if ( !((org.bukkit.entity.Player) entityhuman.getBukkitEntity()).hasPermission("tamablefoxes.tame.unlimited") && maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUUID()) >= maxTameCount) { + if (!LanguageConfig.getFoxDoesntTrust().equalsIgnoreCase("disabled")) { + ((org.bukkit.entity.Player) entityhuman.getBukkitEntity()).sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust()); + } + + return InteractionResult.SUCCESS; + } + + // 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not. + if (this.getRandom().nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { + this.tame(entityhuman); + + this.navigation.stop(); + this.goalSitWhenOrdered.setOrderedToSit(true); + + if (maxTameCount > 0) { + sqLiteHelper.addPlayerFoxAmount(entityhuman.getUUID(), 1); + } + + getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D); + + // Give player tamed message. + if (!LanguageConfig.getTamedMessage().equalsIgnoreCase("disabled")) { + ((org.bukkit.entity.Player) entityhuman.getBukkitEntity()).sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getTamedMessage()); + } + + // Let the player choose the new fox's name if its enabled in config. + if (Config.askForNameAfterTaming()) { + if (!LanguageConfig.getTamingAskingName().equalsIgnoreCase("disabled")) { + player.sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getTamingAskingName()); + } + rename(player); + } + } else { + getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.SMOKE_NORMAL, getBukkitEntity().getLocation(), 10, 0.2D, 0.2D, 0.2D, 0.15D); + } + } + + return InteractionResult.SUCCESS; + } + + return super.mobInteract(entityhuman, enumhand); + } + } + + @Override + public EntityTamableFox getBreedOffspring(ServerLevel worldserver, AgeableMob entityageable) { + EntityTamableFox entityfox = (EntityTamableFox) EntityType.FOX.create(worldserver); + entityfox.setVariant(this.getRandom().nextBoolean() ? this.getVariant() : ((Fox)entityageable).getVariant()); + + UUID uuid = this.getOwnerUUID(); + if (uuid != null) { + entityfox.setOwnerUUID(uuid); + entityfox.setTamed(true); + } + + return entityfox; + } + + @Nullable + public UUID getOwnerUUID() { + return (UUID) ((Optional) this.entityData.get(ownerUUID)).orElse(null); + } + + public void setOwnerUUID(@Nullable UUID ownerUuid) { + this.entityData.set(ownerUUID, Optional.ofNullable(ownerUuid)); + } + + public void tame(Player owner) { + this.setTamed(true); + this.setOwnerUUID(owner.getUUID()); + + // Give the player the taming advancement. + if (owner instanceof ServerPlayer) { + CriteriaTriggers.TAME_ANIMAL.trigger((ServerPlayer) owner, this); + } + } + + @Nullable + public LivingEntity getOwner() { + try { + UUID ownerUuid = this.getOwnerUUID(); + return ownerUuid == null ? null : this.getCommandSenderWorld().getPlayerByUUID(ownerUuid); + } catch (IllegalArgumentException var2) { + return null; + } + } + + // Only attack entity if its not attacking owner. + @Override + public boolean canAttack(LivingEntity entity) { + return !this.isOwnedBy(entity) && super.canAttack(entity); + } + + public boolean isOwnedBy(LivingEntity entity) { + return entity == this.getOwner(); + } + + /* + deobf: wantsToAttack (Copied from EntityWolf) + This code being from EntityWolf also means that wolves will want to attack foxes + Our life would be so much easier if we could extend both EntityFox and EntityTameableAnimal + */ + public boolean wantsToAttack(LivingEntity entityliving, LivingEntity entityliving1) { + if (!(entityliving instanceof Creeper) && !(entityliving instanceof Ghast)) { + if (entityliving instanceof EntityTamableFox) { + EntityTamableFox entityFox = (EntityTamableFox) entityliving; + return !entityFox.isTamed() || entityFox.getOwner() != entityliving1; + } else { + return (!(entityliving instanceof Player) + || !(entityliving1 instanceof Player) || + ((Player) entityliving1).canHarmPlayer((Player) entityliving)) && ((!(entityliving instanceof AbstractHorse) + || !((AbstractHorse) entityliving).isTamed()) && (!(entityliving instanceof TamableAnimal) + || !((TamableAnimal) entityliving).isTame())); + } + } else { + return false; + } + } + + // Set the scoreboard team to the same as the owner if its tamed. + @Override + public Team getTeam() { + if (this.isTamed()) { + LivingEntity var0 = this.getOwner(); + if (var0 != null) { + return var0.getTeam(); + } + } + + return super.getTeam(); + } + + // Override isAlliedTo (Entity::r(Entity)) + @Override + public boolean isAlliedTo(Entity entity) { + if (this.isTamed()) { + LivingEntity entityOwner = this.getOwner(); + if (entity == entityOwner) { + return true; + } + + if (entityOwner != null) { + return entityOwner.isAlliedTo(entity); + } + } + return super.isAlliedTo(entity); + } + + // When the fox dies, show a chat message, and remove the player's stored tamed foxed. + @Override + public void die(DamageSource damageSource) { + if (!this.getCommandSenderWorld().isClientSide && this.getCommandSenderWorld().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) && this.getOwner() instanceof ServerPlayer) { + //this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID()); + this.getOwner().sendSystemMessage(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(Utils.tamableFoxesPlugin); + sqliteHelper.removePlayerFoxAmount(this.getOwner().getUUID(), 1); + } + + super.die(damageSource); + } + + + private Goal getFoxInnerPathfinderGoal(String innerName, List args, List> argTypes) { + return (Goal) Utils.instantiatePrivateInnerClass(Fox.class, innerName, this, args, argTypes); + } + + private Goal getFoxInnerPathfinderGoal(String innerName) { + return (Goal) Utils.instantiatePrivateInnerClass(Fox.class, innerName, this, Arrays.asList(), Arrays.asList()); + } + + public boolean isOrderedToSit() { return this.goalSitWhenOrdered.isOrderedToSit(); } + + public void setOrderedToSit(boolean flag) { this.goalSitWhenOrdered.setOrderedToSit(flag); } + + public boolean isOrderedToSleep() { return this.goalSleepWhenOrdered.isOrderedToSleep(); } + + public void setOrderedToSleep(boolean flag) { this.goalSleepWhenOrdered.setOrderedToSleep(flag); } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/NMSInterface_1_20_R1.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/NMSInterface_1_20_R1.java new file mode 100644 index 0000000..42eeffc --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/NMSInterface_1_20_R1.java @@ -0,0 +1,54 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.animal.Fox; +import net.seanomik.tamablefoxes.util.FieldHelper; +import net.seanomik.tamablefoxes.util.NMSInterface; +import net.seanomik.tamablefoxes.util.io.Config; +import net.seanomik.tamablefoxes.util.io.LanguageConfig; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; +import org.bukkit.entity.Player; + +import java.lang.reflect.Field; +import java.util.UUID; + +public class NMSInterface_1_20_R1 implements NMSInterface { + @Override + public void registerCustomFoxEntity() { + try { // Replace the fox entity + Field field = EntityType.FOX.getClass().getDeclaredField("bA"); // bA = factory + FieldHelper.setFieldUsingUnsafe(field, EntityType.FOX, (EntityType.EntityFactory) EntityTamableFox::new); + Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced()); + } catch (Exception e) { + Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace()); + e.printStackTrace(); + } + } + + @Override + public void spawnTamableFox(Location loc, FoxType type) { + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle(); + tamableFox.setVariant((type == FoxType.RED) ? Fox.Type.RED : Fox.Type.SNOW); + } + + @Override + public void changeFoxOwner(org.bukkit.entity.Fox fox, Player newOwner) { + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) fox).getHandle(); + tamableFox.setOwnerUUID(newOwner.getUniqueId()); + } + + @Override + public UUID getFoxOwner(org.bukkit.entity.Fox fox) { + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) fox).getHandle(); + return tamableFox.getOwnerUUID(); + } + + @Override + public void renameFox(org.bukkit.entity.Fox fox, Player player) { + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) fox).getHandle(); + tamableFox.rename(player); + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalFollowOwner.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalFollowOwner.java new file mode 100644 index 0000000..886f072 --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalFollowOwner.java @@ -0,0 +1,152 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; +import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.LeavesBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.BlockPathTypes; +import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; +import org.bukkit.event.entity.EntityTeleportEvent; + +import java.util.EnumSet; + +public class FoxPathfinderGoalFollowOwner extends Goal { + public static final int TELEPORT_WHEN_DISTANCE_IS = 12; + private static final int MIN_HORIZONTAL_DISTANCE_FROM_PLAYER_WHEN_TELEPORTING = 2; + private static final int MAX_HORIZONTAL_DISTANCE_FROM_PLAYER_WHEN_TELEPORTING = 3; + private static final int MAX_VERTICAL_DISTANCE_FROM_PLAYER_WHEN_TELEPORTING = 1; + private final EntityTamableFox tamableFox; + private LivingEntity owner; + private final LevelReader level; + private final double speedModifier; + private final PathNavigation navigation; + private int timeToRecalcPath; + private final float stopDistance; + private final float startDistance; + private float oldWaterCost; + private final boolean canFly; + + public FoxPathfinderGoalFollowOwner(EntityTamableFox entityfox, double d0, float f, float f1, boolean flag) { + this.tamableFox = entityfox; + this.level = entityfox.level(); + this.speedModifier = d0; + this.navigation = entityfox.getNavigation(); + this.startDistance = f; + this.stopDistance = f1; + this.canFly = flag; + this.setFlags(EnumSet.of(Goal.Flag.MOVE, Flag.LOOK)); + if (!(entityfox.getNavigation() instanceof GroundPathNavigation) && !(entityfox.getNavigation() instanceof FlyingPathNavigation)) { + throw new IllegalArgumentException("Unsupported mob type for FoxPathfinderGoalFollowOwner"); + } + } + + public boolean canUse() { + LivingEntity entityliving = this.tamableFox.getOwner(); + if (entityliving == null) { + return false; + } else if (entityliving.isSpectator()) { + return false; + } else if (this.tamableFox.isOrderedToSit() || this.tamableFox.isOrderedToSleep()) { + return false; + } else if (this.tamableFox.distanceToSqr(entityliving) < (double)(this.startDistance * this.startDistance)) { + return false; + } else { + this.owner = entityliving; + return true; + } + } + + public boolean canContinueToUse() { + return !this.navigation.isDone() && (!this.tamableFox.isOrderedToSit() && !this.tamableFox.isOrderedToSleep() && this.tamableFox.distanceToSqr(this.owner) > (double) (this.stopDistance * this.stopDistance)); + } + + public void start() { + this.timeToRecalcPath = 0; + this.oldWaterCost = this.tamableFox.getPathfindingMalus(BlockPathTypes.WATER); + this.tamableFox.setPathfindingMalus(BlockPathTypes.WATER, 0.0F); + } + + public void stop() { + this.owner = null; + this.navigation.stop(); + this.tamableFox.setPathfindingMalus(BlockPathTypes.WATER, this.oldWaterCost); + } + + public void tick() { + this.tamableFox.getLookControl().setLookAt(this.owner, 10.0F, (float)this.tamableFox.getMaxHeadXRot()); + if (--this.timeToRecalcPath <= 0) { + this.timeToRecalcPath = 10; + if (!this.tamableFox.isLeashed() && !this.tamableFox.isPassenger()) { + if (this.tamableFox.distanceToSqr(this.owner) >= 144.0D) { + this.teleportToOwner(); + } else { + this.navigation.moveTo(this.owner, this.speedModifier); + } + } + } + + } + + private void teleportToOwner() { + BlockPos blockposition = this.owner.blockPosition(); + + for(int i = 0; i < 10; ++i) { + int j = this.randomIntInclusive(-3, 3); + int k = this.randomIntInclusive(-1, 1); + int l = this.randomIntInclusive(-3, 3); + boolean flag = this.maybeTeleportTo(blockposition.getX() + j, blockposition.getY() + k, blockposition.getZ() + l); + if (flag) { + return; + } + } + + } + + private boolean maybeTeleportTo(int i, int j, int k) { + if (Math.abs((double)i - this.owner.getX()) < 2.0D && Math.abs((double)k - this.owner.getZ()) < 2.0D) { + return false; + } else if (!this.canTeleportTo(new BlockPos(i, j, k))) { + return false; + } else { + CraftEntity entity = this.tamableFox.getBukkitEntity(); + Location to = new Location(entity.getWorld(), (double)i + 0.5D, (double)j, (double)k + 0.5D, this.tamableFox.getYRot(), this.tamableFox.getXRot()); + EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to); + this.tamableFox.level().getCraftServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } else { + to = event.getTo(); + this.tamableFox.moveTo(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch()); + this.navigation.stop(); + return true; + } + } + } + + private boolean canTeleportTo(BlockPos blockposition) { + BlockPathTypes pathtype = WalkNodeEvaluator.getBlockPathTypeStatic(this.level, blockposition.mutable()); + if (pathtype != BlockPathTypes.WALKABLE) { + return false; + } else { + BlockState iblockdata = this.level.getBlockState(blockposition.below()); + if (!this.canFly && iblockdata.getBlock() instanceof LeavesBlock) { + return false; + } else { + BlockPos blockposition1 = blockposition.subtract(this.tamableFox.blockPosition()); + return this.level.noCollision(this.tamableFox, this.tamableFox.getBoundingBox().move(blockposition1)); + } + } + } + + private int randomIntInclusive(int i, int j) { + return this.tamableFox.getRandom().nextInt(j - i + 1) + i; + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalHurtByTarget.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalHurtByTarget.java new file mode 100644 index 0000000..d59fd16 --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalHurtByTarget.java @@ -0,0 +1,119 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.goal.target.TargetGoal; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.phys.AABB; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; + +public class FoxPathfinderGoalHurtByTarget extends TargetGoal { + private static final TargetingConditions HURT_BY_TARGETING = TargetingConditions.forCombat().ignoreLineOfSight().ignoreInvisibilityTesting(); + private static final int ALERT_RANGE_Y = 10; + private boolean alertSameType; + private int timestamp; + private final Class[] toIgnoreDamage; + private Class[] toIgnoreAlert; + + public FoxPathfinderGoalHurtByTarget(PathfinderMob entitycreature, Class... aclass) { + super(entitycreature, true); + this.toIgnoreDamage = aclass; + this.setFlags(EnumSet.of(Flag.TARGET)); + } + + public boolean canUse() { + int i = this.mob.getLastHurtByMobTimestamp(); + LivingEntity entityliving = this.mob.getLastHurtByMob(); + if (i != this.timestamp && entityliving != null) { + if (entityliving.getType() == EntityType.PLAYER && this.mob.level().getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) { + return false; + } else { + Class[] aclass = this.toIgnoreDamage; + int j = aclass.length; + + for(int k = 0; k < j; ++k) { + Class oclass = aclass[k]; + if (oclass.isAssignableFrom(entityliving.getClass())) { + return false; + } + } + + return this.canAttack(entityliving, HURT_BY_TARGETING); + } + } else { + return false; + } + } + + public FoxPathfinderGoalHurtByTarget setAlertOthers(Class... aclass) { + this.alertSameType = true; + this.toIgnoreAlert = aclass; + return this; + } + + public void start() { + this.mob.setTarget(this.mob.getLastHurtByMob(), TargetReason.TARGET_ATTACKED_ENTITY, true); + this.targetMob = this.mob.getTarget(); + this.timestamp = this.mob.getLastHurtByMobTimestamp(); + this.unseenMemoryTicks = 300; + if (this.alertSameType) { + this.alertOthers(); + } + + super.start(); + } + + protected void alertOthers() { + double d0 = this.getFollowDistance(); + AABB axisalignedbb = AABB.unitCubeFromLowerCorner(this.mob.position()).inflate(d0, 10.0D, d0); + List list = this.mob.level().getEntitiesOfClass(this.mob.getClass(), axisalignedbb, EntitySelector.NO_SPECTATORS); + Iterator iterator = list.iterator(); + + while(true) { + Mob entityinsentient; + boolean flag; + do { + do { + do { + do { + do { + if (!iterator.hasNext()) { + return; + } + + entityinsentient = (Mob)iterator.next(); + } while(this.mob == entityinsentient); + } while(entityinsentient.getTarget() != null); + } while(this.mob instanceof EntityTamableFox && ((EntityTamableFox)this.mob).getOwner() != ((EntityTamableFox)entityinsentient).getOwner()); + } while(entityinsentient.isAlliedTo(this.mob.getLastHurtByMob())); + + if (this.toIgnoreAlert == null) { + break; + } + + flag = false; + Class[] aclass = this.toIgnoreAlert; + int i = aclass.length; + + for(int j = 0; j < i; ++j) { + Class oclass = aclass[j]; + if (entityinsentient.getClass() == oclass) { + flag = true; + break; + } + } + } while(flag); + + this.alertOther(entityinsentient, this.mob.getLastHurtByMob()); + } + } + + protected void alertOther(Mob entityinsentient, LivingEntity entityliving) { + entityinsentient.setTarget(entityliving, TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java new file mode 100644 index 0000000..c031cdf --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java @@ -0,0 +1,56 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.goal.target.TargetGoal; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; + +import java.util.EnumSet; + +public class FoxPathfinderGoalOwnerHurtByTarget extends TargetGoal { + private final EntityTamableFox tameAnimal; + private LivingEntity ownerLastHurtBy; + private int timestamp; + + public FoxPathfinderGoalOwnerHurtByTarget(EntityTamableFox entitytameableanimal) { + super(entitytameableanimal, false); + this.tameAnimal = entitytameableanimal; + this.setFlags(EnumSet.of(Goal.Flag.TARGET)); + } + + public boolean canUse() { + if (this.tameAnimal.isTamed() && !this.tameAnimal.isOrderedToSit() && !this.tameAnimal.isOrderedToSleep()) { + LivingEntity entityliving = this.tameAnimal.getOwner(); + if (entityliving == null) { + return false; + } else { + this.ownerLastHurtBy = entityliving.getLastHurtByMob(); + int i = entityliving.getLastHurtByMobTimestamp(); + return i != this.timestamp && this.canAttack(this.ownerLastHurtBy, TargetingConditions.DEFAULT) && this.tameAnimal.wantsToAttack(this.ownerLastHurtBy, entityliving); + } + } else { + return false; + } + } + + public void start() { + this.mob.setTarget(this.ownerLastHurtBy, TargetReason.TARGET_ATTACKED_OWNER, true); + LivingEntity entityliving = this.tameAnimal.getOwner(); + if (entityliving != null) { + this.timestamp = entityliving.getLastHurtByMobTimestamp(); + } + + tameAnimal.setDefending(false); + + super.start(); + } + + @Override + public void stop() { + tameAnimal.setDefending(false); + + super.stop(); + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java new file mode 100644 index 0000000..d5de7bf --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java @@ -0,0 +1,57 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.goal.target.TargetGoal; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; + +import java.util.EnumSet; + +public class FoxPathfinderGoalOwnerHurtTarget extends TargetGoal { + private final EntityTamableFox tameAnimal; + private LivingEntity ownerLastHurt; + private int timestamp; + + public FoxPathfinderGoalOwnerHurtTarget(EntityTamableFox entitytameableanimal) { + super(entitytameableanimal, false); + this.tameAnimal = entitytameableanimal; + this.setFlags(EnumSet.of(Goal.Flag.TARGET)); + } + + public boolean canUse() { + if (this.tameAnimal.isTamed() && !this.tameAnimal.isOrderedToSit() && !this.tameAnimal.isOrderedToSleep()) { + LivingEntity entityliving = this.tameAnimal.getOwner(); + if (entityliving == null) { + return false; + } else { + this.ownerLastHurt = entityliving.getLastHurtMob(); + int i = entityliving.getLastHurtMobTimestamp(); + return i != this.timestamp && this.canAttack(this.ownerLastHurt, TargetingConditions.DEFAULT) && this.tameAnimal.wantsToAttack(this.ownerLastHurt, entityliving); + } + } else { + return false; + } + } + + public void start() { + this.mob.setTarget(this.ownerLastHurt, TargetReason.OWNER_ATTACKED_TARGET, true); + LivingEntity entityliving = this.tameAnimal.getOwner(); + if (entityliving != null) { + this.timestamp = entityliving.getLastHurtMobTimestamp(); + } + + tameAnimal.setDefending(true); + + super.start(); + } + + + @Override + public void stop() { + tameAnimal.setDefending(false); + + super.stop(); + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalPanic.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalPanic.java new file mode 100644 index 0000000..cb97a08 --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalPanic.java @@ -0,0 +1,21 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.world.entity.ai.goal.PanicGoal; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; + +public class FoxPathfinderGoalPanic extends PanicGoal { + EntityTamableFox tamableFox; + + public FoxPathfinderGoalPanic(EntityTamableFox tamableFox, double d0) { + super(tamableFox, d0); + this.tamableFox = tamableFox; + } + + public boolean canUse() { + if (tamableFox.isTamed()) { + return tamableFox.getHealth() < 2.0f && super.canUse(); + } + + return tamableFox.isDefending() && super.canUse(); + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSitWhenOrdered.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSitWhenOrdered.java new file mode 100644 index 0000000..9227bd4 --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSitWhenOrdered.java @@ -0,0 +1,56 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.seanomik.tamablefoxes.util.Utils; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; +import org.bukkit.Bukkit; + +import java.util.EnumSet; + +public class FoxPathfinderGoalSitWhenOrdered extends Goal { + private final EntityTamableFox mob; + private boolean orderedToSit; + + public FoxPathfinderGoalSitWhenOrdered(EntityTamableFox entitytameableanimal) { + this.mob = entitytameableanimal; + this.setFlags(EnumSet.of(Goal.Flag.JUMP, Goal.Flag.MOVE)); + } + + public boolean canContinueToUse() { + return this.orderedToSit; + } + + public boolean canUse() { + if (!this.mob.isTamed()) { + return this.orderedToSit && this.mob.getTarget() == null; + } else if (this.mob.isInWaterOrBubble()) { + return false; + } else if (this.mob.isFallFlying()) { + return false; + } else { + LivingEntity entityliving = this.mob.getOwner(); + return entityliving == null || ((!(this.mob.distanceToSqr(entityliving) < 144.0D) || entityliving.getLastHurtByMob() == null) && this.mob.isOrderedToSit()); + } + } + + public void start() { + // For some reason it needs to be ran later to not have the fox slide across the floor. + Bukkit.getScheduler().runTaskLater(Utils.tamableFoxesPlugin, () -> { + this.mob.getNavigation().stop(); + this.mob.setSitting(true); + this.orderedToSit = true; + }, 1L); + } + + public void stop() { + this.mob.setSitting(false); + this.orderedToSit = false; + } + + public boolean isOrderedToSit() { return this.orderedToSit; } + + public void setOrderedToSit(boolean flag) { + this.orderedToSit = flag; + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWhenOrdered.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWhenOrdered.java new file mode 100644 index 0000000..86c1770 --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWhenOrdered.java @@ -0,0 +1,51 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; + +import java.util.EnumSet; + +public class FoxPathfinderGoalSleepWhenOrdered extends Goal { + private final EntityTamableFox mob; + private boolean orderedToSleep; + + public FoxPathfinderGoalSleepWhenOrdered(EntityTamableFox entitytameableanimal) { + this.mob = entitytameableanimal; + this.setFlags(EnumSet.of(Flag.JUMP, Flag.MOVE)); + } + + public boolean canContinueToUse() { + return this.orderedToSleep; + } + + public boolean canUse() { + if (!this.mob.isTamed()) { + return this.orderedToSleep && this.mob.getTarget() == null; + } else if (this.mob.isInWaterOrBubble()) { + return false; + } else if (this.mob.isFallFlying()) { + return false; + } else { + LivingEntity entityliving = this.mob.getOwner(); + return entityliving == null || ((!(this.mob.distanceToSqr(entityliving) < 144.0D) || entityliving.getLastHurtByMob() == null) && this.mob.isOrderedToSleep()); + } + } + + public void start() { + this.mob.getNavigation().stop(); + this.mob.setSleeping(true); + this.orderedToSleep = true; + } + + public void stop() { + this.mob.setSleeping(false); + this.orderedToSleep = false; + } + + public boolean isOrderedToSleep() { return this.orderedToSleep; } + + public void setOrderedToSleep(boolean flag) { + this.orderedToSleep = flag; + } +} diff --git a/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWithOwner.java b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWithOwner.java new file mode 100644 index 0000000..8f4729e --- /dev/null +++ b/1_20_R1/src/main/java/net/seanomik/tamablefoxes/versions/version_1_20_R1/pathfinding/FoxPathfinderGoalSleepWithOwner.java @@ -0,0 +1,112 @@ +package net.seanomik.tamablefoxes.versions.version_1_20_R1.pathfinding; + +import net.minecraft.core.BlockPos; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.BedBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.EntityTamableFox; + +import java.util.Iterator; +import java.util.List; + +// From class EntityCat#b +public class FoxPathfinderGoalSleepWithOwner extends Goal { + private final EntityTamableFox fox; + private Player ownerPlayer; + private BlockPos goalPos; + private int onBedTicks; + + public FoxPathfinderGoalSleepWithOwner(EntityTamableFox entityTamableFox) { + this.fox = entityTamableFox; + } + + public boolean canUse() { + if (!this.fox.isTamed()) { + return false; + } else if (this.fox.isOrderedToSleep()) { + return false; + } else { + LivingEntity entityliving = this.fox.getOwner(); + if (entityliving instanceof Player) { + this.ownerPlayer = (Player)entityliving; + if (!entityliving.isSleeping()) { + return false; + } + + if (this.fox.distanceToSqr(this.ownerPlayer) > 100.0D) { + return false; + } + + BlockPos blockposition = this.ownerPlayer.blockPosition(); + BlockState iblockdata = this.fox.level().getBlockState(blockposition); + if (iblockdata.is(BlockTags.BEDS)) { + this.goalPos = (BlockPos)iblockdata.getOptionalValue(BedBlock.FACING).map((enumdirection) -> { + return blockposition.relative(enumdirection.getOpposite()); + }).orElseGet(() -> { + return new BlockPos(blockposition); + }); + return !this.spaceIsOccupied(); + } + } + + return false; + } + } + + private boolean spaceIsOccupied() { + List list = this.fox.level().getEntitiesOfClass(EntityTamableFox.class, (new AABB(this.goalPos)).inflate(2.0D)); + Iterator iterator = list.iterator(); + + EntityTamableFox entityTamableFox; + do { + do { + if (!iterator.hasNext()) { + return false; + } + + entityTamableFox = (EntityTamableFox)iterator.next(); + } while(entityTamableFox == this.fox); + } while(!entityTamableFox.isSleeping());// && !entityTamableFox.isRelaxStateOne()); + + return true; + } + + public boolean canContinueToUse() { + return this.fox.isTamed() && !this.fox.isOrderedToSleep() && this.ownerPlayer != null && this.ownerPlayer.isSleeping() && this.goalPos != null && !this.spaceIsOccupied(); + } + + public void start() { + if (this.goalPos != null) { + this.fox.setSitting(false); + this.fox.getNavigation().moveTo((double)this.goalPos.getX(), (double)this.goalPos.getY(), (double)this.goalPos.getZ(), 1.100000023841858D); + } + + } + + public void stop() { + this.fox.setSleeping(false); + this.onBedTicks = 0; + this.fox.getNavigation().stop(); + } + + public void tick() { + if (this.ownerPlayer != null && this.goalPos != null) { + this.fox.setSitting(false); + this.fox.getNavigation().moveTo((double)this.goalPos.getX(), (double)this.goalPos.getY(), (double)this.goalPos.getZ(), 1.100000023841858D); + if (this.fox.distanceToSqr(this.ownerPlayer) < 2.5D) { + ++this.onBedTicks; + if (this.onBedTicks > 16) { + this.fox.setSleeping(true); + } else { + this.fox.lookAt(this.ownerPlayer, 45.0F, 45.0F); + } + } else { + this.fox.setSleeping(false); + } + } + } +} diff --git a/Plugin/pom.xml b/Plugin/pom.xml index 245167e..1e8f501 100644 --- a/Plugin/pom.xml +++ b/Plugin/pom.xml @@ -7,7 +7,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes @@ -58,7 +58,7 @@ shade - /mnt/data_drive/Development/Spigot/DevServers/${server.version}/plugins/TamableFoxes_v${project.parent.version}.jar + /media/data_drive/Development/Spigot/DevServers/${server.version}/plugins/TamableFoxes_v${project.parent.version}.jar false @@ -189,6 +189,12 @@ ${project.parent.version} compile + + net.seanomik + tamablefoxes_v1_20_R1 + ${project.parent.version} + compile + org.bstats @@ -211,7 +217,7 @@ net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/Plugin/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java b/Plugin/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java index 50b7657..8667a7d 100644 --- a/Plugin/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java +++ b/Plugin/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java @@ -21,6 +21,7 @@ import net.seanomik.tamablefoxes.versions.version_1_19_1_R1.NMSInterface_1_19_1_ import net.seanomik.tamablefoxes.versions.version_1_19_2_R1.NMSInterface_1_19_2_R1; import net.seanomik.tamablefoxes.versions.version_1_19_3_R1.NMSInterface_1_19_3_R1; import net.seanomik.tamablefoxes.versions.version_1_19_R3.NMSInterface_1_19_4_R1; +import net.seanomik.tamablefoxes.versions.version_1_20_R1.NMSInterface_1_20_R1; import org.bstats.bukkit.Metrics; import org.bukkit.*; import org.bukkit.event.Listener; @@ -87,21 +88,28 @@ public final class TamableFoxes extends JavaPlugin implements Listener { nmsInterface = new NMSInterface_1_19_3_R1(); } else if (versionDouble == 19.4D) { nmsInterface = new NMSInterface_1_19_4_R1(); - } else { + } else if (versionDouble == 20D || versionDouble == 20.1D) { + nmsInterface = new NMSInterface_1_20_R1(); + } else { Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getUnsupportedMCVersionRegister()); Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + "You're trying to run MC version " + specificVersion + " which is not supported!"); + Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + "Disabling plugin..."); versionSupported = false; + + Bukkit.getPluginManager().disablePlugin(this); } - // Display starting message then register entity. - Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.YELLOW + LanguageConfig.getMCVersionLoading(version)); - nmsInterface.registerCustomFoxEntity(); + if (versionSupported) { + // Display starting message then register entity. + Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.YELLOW + LanguageConfig.getMCVersionLoading(version)); + nmsInterface.registerCustomFoxEntity(); - if (Config.getMaxPlayerFoxTames() != 0) { - SQLiteHelper.getInstance(this).createTablesIfNotExist(); + if (Config.getMaxPlayerFoxTames() != 0) { + SQLiteHelper.getInstance(this).createTablesIfNotExist(); + } + + Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); } - - Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); } @Override diff --git a/README.md b/README.md index cf88830..f03bb22 100644 --- a/README.md +++ b/README.md @@ -64,29 +64,7 @@ Have you ever wanted to tame foxes? Well, now you can! Use chicken to tame net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT tamablefoxes-util diff --git a/ci-pom.xml b/ci-pom.xml index 9072319..1b66d7e 100644 --- a/ci-pom.xml +++ b/ci-pom.xml @@ -6,7 +6,7 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT pom diff --git a/compileSpigotVersions.sh b/compileSpigotVersions.sh index b7df3ea..5fb15e7 100644 --- a/compileSpigotVersions.sh +++ b/compileSpigotVersions.sh @@ -1,9 +1,22 @@ +# Java 8 java -jar ./BuildTools.jar --rev 1.14.4 --compile-if-changed java -jar ./BuildTools.jar --rev 1.15 --compile-if-changed java -jar ./BuildTools.jar --rev 1.16.1 --compile-if-changed java -jar ./BuildTools.jar --rev 1.16.3 --compile-if-changed java -jar ./BuildTools.jar --rev 1.16.5 --compile-if-changed -java -jar ./BuildTools.jar --rev 1.17 --remapped remapped-mojang --compile-if-changed -java -jar ./BuildTools.jar --rev 1.17.1 --remapped remapped-mojang --compile-if-changed -java -jar ./BuildTools.jar --rev 1.18 --remapped remapped-mojang --compile-if-changed -java -jar ./BuildTools.jar --rev 1.18.1 --remapped remapped-mojang --compile-if-changed + +# Java 16 +java -jar ./BuildTools.jar --rev 1.17 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.17.1 --remapped --compile-if-changed + +# Java 17 +java -jar ./BuildTools.jar --rev 1.18 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.18.1 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.18.2 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.19 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.19.1 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.19.2 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.19.3 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.19.4 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.20 --remapped --compile-if-changed +java -jar ./BuildTools.jar --rev 1.21 --remapped --compile-if-changed \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4900eb8..5e50d4b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,15 @@ net.seanomik tamablefoxes-parent - 2.2.9-SNAPSHOT + 2.2.10-SNAPSHOT pom Plugin Utility + 1_20_R1 + 1_19_R3 1_19_3_R1 1_19_2_R1